-
-
Notifications
You must be signed in to change notification settings - Fork 210
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ci: started working on composite action for gptme-bot, generated basi…
…c docs
- Loading branch information
Showing
2 changed files
with
296 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,243 @@ | ||
name: 'gptme-bot' | ||
description: 'A composite action for the gptme-bot workflow' | ||
inputs: | ||
openai_api_key: | ||
description: 'OpenAI API Key' | ||
required: true | ||
github_token: | ||
description: 'GitHub Token' | ||
required: true | ||
issue_number: | ||
description: 'Issue Number' | ||
required: true | ||
comment_body: | ||
description: 'Comment Body' | ||
required: true | ||
comment_id: | ||
description: 'Comment ID' | ||
required: true | ||
repo_name: | ||
description: 'Repository Name' | ||
required: true | ||
user_name: | ||
description: 'User Name' | ||
required: true | ||
branch_base: | ||
description: 'Base Branch' | ||
required: true | ||
python_version: | ||
description: 'Python Version' | ||
required: true | ||
is_pr: | ||
description: 'Is Pull Request' | ||
required: true | ||
branch_name: | ||
description: 'Branch Name' | ||
required: true | ||
runs: | ||
using: "composite" | ||
steps: | ||
- name: Detect gptme command | ||
id: detect_command | ||
run: | | ||
# Check if the comment starts with "@gptme" | ||
if [[ "${{ inputs.comment_body }}" == "@gptme "* ]]; then | ||
# Extract the command | ||
GPTME_COMMAND=${{ inputs.comment_body }}#"@gptme " | ||
# Escape double quotes | ||
# GPTME_COMMAND="${GPTME_COMMAND//\"/\\\"}" | ||
# Set output | ||
{ | ||
echo "gptme_command<<EOFMAGIC" | ||
echo $GPTME_COMMAND | ||
echo "EOFMAGIC" | ||
} >> $GITHUB_OUTPUT | ||
fi | ||
shell: bash | ||
|
||
- name: Fail if author not on whitelist | ||
if: steps.detect_command.outputs.gptme_command | ||
run: | | ||
WHITELIST=("ErikBjare") # Add your allowed usernames here | ||
COMMENT_AUTHOR="${{ inputs.user_name }}" | ||
if [[ ! " ${WHITELIST[@]} " =~ " ${COMMENT_AUTHOR} " ]]; then | ||
echo "Error: Author ${COMMENT_AUTHOR} is not on the whitelist." | ||
exit 1 | ||
else | ||
echo "Author ${COMMENT_AUTHOR} is on the whitelist." | ||
fi | ||
shell: bash | ||
|
||
- name: React to comment | ||
if: steps.detect_command.outputs.gptme_command | ||
run: | | ||
gh api /repos/${{ inputs.user_name }}/${{ inputs.repo_name }}/issues/comments/${{ inputs.comment_id }}/reactions -X POST -f content='+1' | ||
shell: bash | ||
env: | ||
GITHUB_TOKEN: ${{ inputs.github_token }} | ||
|
||
- name: Checkout | ||
uses: actions/checkout@v3 | ||
|
||
- name: Install ctags | ||
run: sudo apt install universal-ctags | ||
shell: bash | ||
|
||
- name: Checkout PR branch if comment is on a PR | ||
id: checkout_branch | ||
run: | | ||
# Fetch details about the "issue" the comment is on | ||
DATA=$(gh api /repos/${{ github.repository }}/issues/${{ inputs.issue_number }}) | ||
# Extract whether this "issue" is a PR and | ||
IS_PR=${{ inputs.is_pr }} | ||
# If this is a PR, checkout its branch | ||
if [[ "$IS_PR" != "null" ]]; then | ||
# Fetch details about the PR the comment is on | ||
DATA=$(gh api /repos/${{ github.repository }}/pulls/${{ inputs.issue_number }}) | ||
# Get the PR's branch name | ||
BRANCH_NAME=${{ inputs.branch_name }} | ||
git fetch origin $BRANCH_NAME | ||
git checkout $BRANCH_NAME | ||
else | ||
# Create a new branch and push changes | ||
BRANCH_NAME="gptme-bot-changes-$(date +'%Y%m%d%H%M%S')" | ||
git checkout -b $BRANCH_NAME | ||
fi | ||
echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT | ||
shell: bash | ||
env: | ||
GITHUB_TOKEN: ${{ inputs.github_token }} | ||
|
||
- name: Install poetry | ||
run: pipx install poetry | ||
shell: bash | ||
|
||
- name: Set up Python | ||
uses: actions/setup-python@v4 | ||
with: | ||
python-version: ${{ inputs.python_version }} | ||
cache: 'poetry' | ||
|
||
- name: Install dependencies | ||
run: | | ||
make build | ||
poetry install -E datascience | ||
shell: bash | ||
|
||
- name: Run gptme | ||
run: | | ||
gh issue view ${{ inputs.issue_number }} > issue.md | ||
gh issue view ${{ inputs.issue_number }} -c > comments.md | ||
# strip long <details>...</details> from issue.md and comments.md | ||
perl -0777 -i -pe 's/\n<details>.*?<\/details>//sg' issue.md | ||
perl -0777 -i -pe 's/\n<details>.*?<\/details>//sg' comments.md | ||
# install a shim that makes `git commit` a no-op (in case it would get that idea prematurely) | ||
source scripts/git-shim.sh | ||
# Run gptme with the extracted command and save logs | ||
poetry run gptme --non-interactive "$GPTME_COMMAND" issue.md comments.md | ||
# remove tmp files so that they do not get committed | ||
rm issue.md comments.md | ||
# stage changes | ||
git add -A | ||
shell: bash | ||
env: | ||
GITHUB_TOKEN: ${{ inputs.github_token }} | ||
GPTME_COMMAND: ${{ steps.detect_command.outputs.gptme_command }} | ||
ISSUE_NUMBER: ${{ inputs.issue_number }} | ||
|
||
- name: Generate commit message | ||
run: | | ||
# generate commit message | ||
poetry run gptme --non-interactive "Run `git diff --staged`, then write a commit message for it to message.txt, following conventional commits. Don't commit." | ||
shell: bash | ||
|
||
- name: Commit, push, comment | ||
run: | | ||
# Read and format log | ||
./scripts/format_log.sh ~/.local/share/gptme/logs/*/conversation.jsonl > log.txt | ||
RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" | ||
COMMENT_URL="https://github.com/${{ github.repository }}/issues/${{ inputs.issue_number }}#issuecomment-${{ inputs.comment_id }}" | ||
# commit message & description | ||
COMMIT_MSG="$(cat message.txt || echo 'no commit message')" | ||
COMMIT_DESC="\`gptme '$GPTME_COMMAND'\` | ||
Triggered by: $COMMENT_URL | ||
Run: $RUN_URL" | ||
# commit message with description | ||
COMMIT_MSG_FULL="$COMMIT_MSG | ||
$COMMIT_DESC" | ||
# commit message with description and log | ||
COMMIT_MSG_FULL_WITH_LOG="$COMMIT_MSG_FULL | ||
<details> | ||
<summary>Log</summary> | ||
<pre>$(cat log.txt || echo 'could not get log')</pre> | ||
</details>" | ||
git config user.name "gptme-bot" | ||
git config user.email "[email protected]" | ||
git commit -m "$COMMIT_MSG_FULL" | ||
# Push changes to the PR branch | ||
git push -u origin $BRANCH_NAME | ||
if [[ $ISSUE_TYPE == "pull_request" ]]; then | ||
# Comment on the PR | ||
echo "Changes have been pushed to this pull request." | gh pr comment $ISSUE_NUMBER -R $USER_NAME/$REPO_NAME --body-file=- | ||
else | ||
# Some say this helps! https://github.com/cli/cli/issues/2691#issuecomment-1289521962 | ||
sleep 1 | ||
# Create a PR | ||
PR_URL=$(gh pr create --title "$COMMIT_MSG" --body "$COMMIT_MSG_FULL_WITH_LOG" --repo $USER_NAME/$REPO_NAME | grep -o 'https://github.com[^ ]*') | ||
# These are redundant/implied: --base $BRANCH_BASE --head $USER_NAME:$BRANCH_NAME | ||
# Comment on the issue with the PR link | ||
echo "A pull request has been created for this issue: $PR_URL" | gh issue comment $ISSUE_NUMBER -R $USER_NAME/$REPO_NAME --body-file=- | ||
fi | ||
shell: bash | ||
env: | ||
GITHUB_TOKEN: ${{ inputs.github_token }} | ||
GPTME_COMMAND: ${{ steps.detect_command.outputs.gptme_command }} | ||
ISSUE_NUMBER: ${{ inputs.issue_number }} | ||
ISSUE_TYPE: ${{ github.event.issue.pull_request && 'pull_request' || 'issue' }} | ||
REPO_NAME: ${{ inputs.repo_name }} | ||
USER_NAME: ${{ inputs.user_name }} | ||
BRANCH_NAME: ${{ steps.checkout_branch.outputs.branch_name }} | ||
BRANCH_BASE: ${{ inputs.branch_base }} | ||
|
||
- name: Report error | ||
if: failure() | ||
run: | | ||
# reply to the comment that we could not fulfill the request | ||
RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" | ||
MESSAGE="I'm sorry, I could not fulfill your request. Please check the [log of this run]($RUN_URL) for more information." | ||
if [[ -f log.txt ]]; then | ||
MESSAGE+=" | ||
<details> | ||
<summary>Conversation log</summary> | ||
<pre>$(cat log.txt)</pre> | ||
</details>" | ||
fi | ||
echo "$MESSAGE" | gh issue comment $ISSUE_NUMBER -R $USER_NAME/$REPO_NAME --body-file=- | ||
shell: bash | ||
env: | ||
GITHUB_TOKEN: ${{ inputs.github_token }} | ||
ISSUE_NUMBER: ${{ inputs.issue_number }} | ||
REPO_NAME: ${{ inputs.repo_name }} | ||
USER_NAME: ${{ inputs.user_name }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
GitHub Bot | ||
========== | ||
|
||
One way to run gptme is as a GitHub bot. | ||
|
||
The `gptme-bot` composite action is a GitHub Action that automates the process of running the `gptme` in response to comments on GitHub issues or pull requests. It is designed to be used for tasks that gptme can perform with a one-shot prompt, such as running commands and committing their results, creating files or making simple changes/additions (like write tests), and (potentially) automating code reviews. | ||
|
||
## Inputs | ||
|
||
The action has the following inputs: | ||
|
||
- `openai_api_key`: The OpenAI API key. Required. | ||
- `github_token`: The GitHub token. Required. | ||
- `issue_number`: The number of the issue or pull request the comment is associated with. Required. | ||
- `comment_body`: The body of the comment. Required. | ||
- `comment_id`: The ID of the comment. Required. | ||
- `repo_name`: The name of the repository. Required. | ||
- `user_name`: The username of the comment author. Required. | ||
- `branch_base`: The base branch for the pull request. Required. | ||
- `python_version`: The version of Python to use. Required. | ||
- `is_pr`: A boolean indicating whether the issue is a pull request. Required. | ||
- `branch_name`: The name of the branch associated with the pull request. Required. | ||
|
||
## Usage | ||
|
||
To use the `gptme-bot` composite action in your workflow, include it as a step: | ||
|
||
```yaml | ||
on: | ||
issue_comment: | ||
types: [created] | ||
|
||
steps: | ||
- name: Run gptme-bot composite action | ||
uses: ./.github/actions/bot-composite | ||
with: | ||
openai_api_key: ${{ secrets.OPENAI_API_KEY }} | ||
github_token: ${{ github.token }} | ||
issue_number: ${{ github.event.issue.number }} | ||
comment_body: ${{ github.event.comment.body }} | ||
comment_id: ${{ github.event.comment.id }} | ||
repo_name: ${{ github.event.repository.name }} | ||
user_name: ${{ github.event.repository.owner.login }} | ||
branch_base: "master" | ||
python_version: '3.11' | ||
is_pr: ${{ github.event.issue.pull_request != null }} | ||
branch_name: ${{ github.event.pull_request.head.ref }} | ||
``` | ||
Please note that you need to replace the `uses` path with the correct path to your `bot-composite.yml` file. Also, make sure to replace the `branch_base`, `python_version`, `is_pr`, and `branch_name` inputs with the correct values for your use case. | ||
|
||
The `gptme-bot` composite action will then run the `gptme` command-line tool with the command specified in the comment, and perform actions based on the output of the tool. This includes checking out the appropriate branch, installing dependencies, running the `gptme` command, and committing and pushing any changes made by the tool. If the issue is a pull request, the action will push changes directly to the pull request branch. If the issue is not a pull request, the action will create a new pull request with the changes. | ||
|