Skip to content

Commit

Permalink
🎉 Initial project setup with GitHub Action configuration
Browse files Browse the repository at this point in the history
This commit sets up the foundation for the Auto PR from Dev to Default Branch GitHub Action. Here's what's included:

- 📝 Added README.md with comprehensive project documentation
- ⚙️ Created action.yml to define the GitHub Action workflow
- 📜 Included MIT License for the project
- 🙈 Set up .gitignore to exclude the diff/ directory

Key features of the GitHub Action:
- 🔄 Automatically creates or updates PRs from dev to default branch
- 🤖 Generates PR descriptions using OpenAI API
- 👥 Adds relevant reviewers to the PR
- 📅 Sets PR title with the current date

The action is configured to use OpenAI's API for generating descriptive PR content and includes steps for checking out the repository, setting up Git, determining the default branch, generating diffs, and managing pull requests.

Next steps:
- 🔑 Set up OPENAI_API_KEY secret in repository settings
- 🧪 Test the action in a real workflow
- 📚 Update usage instructions with the correct GitHub username/organization
  • Loading branch information
yuri-val committed Oct 18, 2024
0 parents commit 8f1bf22
Show file tree
Hide file tree
Showing 4 changed files with 298 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

diff/
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2024 [Yuri V]

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
65 changes: 65 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Auto PR from Dev to Default Branch

## Description

This GitHub Action automatically creates or updates a Pull Request from a development branch to the default branch, generates descriptive PR content using OpenAI's API, and adds relevant reviewers.

## Features

- 🔄 Automatically creates or updates a PR from dev to the default branch
- 🤖 Generates PR descriptions using OpenAI API
- 👥 Automatically adds relevant reviewers
- 📅 Sets PR title with current date (e.g., "Release v2023.05.25")

## Inputs

| Name | Description | Required | Default |
|------|-------------|----------|---------|
| `openai_api_key` | OpenAI API Key | Yes | N/A |
| `github_token` | GitHub Personal Access Token with repo permissions | Yes | N/A |
| `dev_branch` | Name of the development branch | No | 'dev' |

## Outputs

| Name | Description |
|------|-------------|
| `pr_number` | The number of the pull request created or updated |

## Usage

To use this action in your workflow, add the following step:

```yaml
- name: Auto PR from Dev to Default
uses: your-github-username/auto-pr-action@v1
with:
openai_api_key: ${{ secrets.OPENAI_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
dev_branch: dev # Optional, defaults to 'dev'
```
Make sure to set up the `OPENAI_API_KEY` secret in your repository settings.

## How it works

1. Checks out the repository
2. Sets up Git configuration
3. Determines the default branch
4. Generates a diff between the dev and default branches
5. Uses OpenAI API to generate a descriptive PR content
6. Creates a new PR or updates an existing one
7. Adds relevant reviewers to the PR

## License

[MIT License](LICENSE)

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

This README.md provides an overview of your GitHub Action, including its features, inputs, outputs, and usage instructions. It also briefly explains how the action works and includes sections for licensing and contributions.

You may want to adjust the "Usage" section to reflect the correct GitHub username or organization where this action will be published. Also, if you haven't already, you might want to add a LICENSE file to your repository.

Feel free to modify this README to better fit your project's specific needs or to add any additional information you think would be helpful for users of your GitHub Action.
210 changes: 210 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
# action.yml

name: 'Auto PR from dev to default'
description: 'Creates or updates a PR from dev to the default branch, generates descriptions using OpenAI API, and adds reviewers.'
author: 'Your Name'
inputs:
openai_api_key:
description: 'OpenAI API Key'
required: true
github_token:
description: 'GitHub (PAT) token with repo permissions'
required: true
dev_branch:
description: 'Development branch name'
required: false
default: 'dev'
outputs:
pr_number:
description: 'The number of the pull request created or updated'
runs:
using: 'composite'
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ inputs.dev_branch }}

- name: Set up Git
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
- name: Get the default branch
id: get_default_branch
shell: bash
run: |
default_branch=$(git remote show origin | grep 'HEAD branch' | awk '{print $NF}')
echo "branch=${default_branch}" >> $GITHUB_OUTPUT
- name: Get the diff using custom script
id: get_diff
shell: bash
run: |
set -e
branch_from="${{ steps.get_default_branch.outputs.branch }}"
branch_to="${{ inputs.dev_branch }}"
echo "Branch from: $branch_from"
echo "Branch to: $branch_to"
git fetch --all
mkdir -p diff
output_file="diff/${branch_from:-main}-${branch_to}_$(date +'%Y%m%d_%H%M').diff"
echo "Output file: $output_file"
{
echo "Commits between $branch_from and $branch_to:"
echo "============================================"
git log origin/"$branch_from"..origin/"$branch_to" || echo "No commits found"
echo "--------------------------------------------"
echo "Git diff between $branch_from and $branch_to"
echo "============================================"
git diff origin/"$branch_from" origin/"$branch_to" || echo "No differences found"
} > "$output_file"
if [ -s "$output_file" ]; then
echo "diff_output<<EOF" >> $GITHUB_OUTPUT
cat "$output_file" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
else
echo "diff_output=No changes detected between $branch_from and $branch_to" >> $GITHUB_OUTPUT
fi
- name: Generate release description using OpenAI API
id: generate_release_notes
env:
OPENAI_API_KEY: ${{ inputs.openai_api_key }}
DIFF_OUTPUT: ${{ steps.get_diff.outputs.diff_output }}
shell: bash
run: |
prompt="**Instructions:**\n\nPlease generate a **Pull Request description** for the provided diff, following these guidelines:\n- Add appropriate emojis to the description.\n- Do **not** include the words \"Title\" and \"Description\" in your output.\n- Format your answer in **Markdown**."
escaped_prompt=$(echo "$prompt" | jq -Rs .)
escaped_diff=$(echo "$DIFF_OUTPUT" | jq -Rs .)
response=$(curl -s -X POST https://api.openai.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d "{
\"model\": \"gpt-4o-mini\",
\"messages\": [
{
\"role\": \"system\",
\"content\": ${escaped_prompt}
},
{
\"role\": \"user\",
\"content\": ${escaped_diff}
}
],
\"temperature\": 1,
\"max_tokens\": 2048,
\"top_p\": 1,
\"frequency_penalty\": 0,
\"presence_penalty\": 0
}")
description=$(echo "$response" | jq -r '.choices[0].message.content')
echo "description<<EOF" >> $GITHUB_OUTPUT
echo "$description" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Set Release Title
id: set_release_title
shell: bash
run: |
echo "title=Release v$(date +'%Y.%m.%d')" >> $GITHUB_OUTPUT
- name: Create or Update Pull Request and Add Reviewers
id: create_pr
uses: actions/github-script@v6
with:
github-token: ${{ inputs.github_token }}
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;
const head = '${{ inputs.dev_branch }}';
const base = '${{ steps.get_default_branch.outputs.branch }}';
const title = '${{ steps.set_release_title.outputs.title }}';
const body = `${{ steps.generate_release_notes.outputs.description }}`;
// Check if PR from dev to default branch already exists
const { data: pulls } = await github.rest.pulls.list({
owner: owner,
repo: repo,
head: `${owner}:${head}`,
base: base,
state: 'open',
});
let prNumber;
let prAuthor;
if (pulls.length > 0) {
prNumber = pulls[0].number;
prAuthor = pulls[0].user.login;
console.log(`Updating existing PR #${prNumber}`);
await github.rest.pulls.update({
owner: owner,
repo: repo,
pull_number: prNumber,
title: title,
body: body,
});
} else {
console.log('Creating new PR');
const { data: pr } = await github.rest.pulls.create({
owner: owner,
repo: repo,
head: head,
base: base,
title: title,
body: body,
});
prNumber = pr.number;
prAuthor = pr.user.login;
}
// Now, add reviewers
// First, get the list of committers to this PR
const { data: commits } = await github.rest.pulls.listCommits({
owner: owner,
repo: repo,
pull_number: prNumber,
});
const committersSet = new Set();
for (const commit of commits) {
if (commit.author && commit.author.login) {
committersSet.add(commit.author.login);
}
}
// Add the repo owner
committersSet.add(owner);
// Remove the PR author from reviewers
committersSet.delete(prAuthor);
// Remove the bot user (if present)
const botUser = 'github-actions[bot]';
committersSet.delete(botUser);
// Convert set to array
const reviewers = Array.from(committersSet);
console.log(`Adding reviewers: ${reviewers.join(', ')}`);
if (reviewers.length > 0) {
// Add reviewers to the PR
await github.rest.pulls.requestReviewers({
owner: owner,
repo: repo,
pull_number: prNumber,
reviewers: reviewers,
});
} else {
console.log('No reviewers to add.');
}
core.setOutput('pr_number', prNumber);

0 comments on commit 8f1bf22

Please sign in to comment.