| name | argentos-github-pr-workflow |
| description | Full pull request lifecycle — create branches, commit changes, open PRs, monitor CI status, auto-fix failures, and merge. Works with gh CLI or falls back to git + GitHub REST API via curl. |
| version | 1.1.0 |
| author | ArgentOS |
| license | MIT |
| metadata | {"argent":{"tags":["GitHub","Pull-Requests","CI/CD","Git","Automation","Merge"],"related_skills":["github-auth","github-code-review"]},"imported_from":{"original_name":"github-pr-workflow","source":"upstream skill profile"}} |
GitHub Pull Request Workflow
Complete guide for managing the PR lifecycle. Each section shows the gh way first, then the git + curl fallback for machines without gh.
Prerequisites
- Authenticated with GitHub (see
github-auth skill)
- Inside a git repository with a GitHub remote
Quick Auth Detection
if command -v gh &>/dev/null && gh auth status &>/dev/null; then
AUTH="gh"
else
AUTH="git"
if [ -z "$GITHUB_TOKEN" ]; then
if [ -f ~/.hermes/.env ] && grep -q "^GITHUB_TOKEN=" ~/.hermes/.env; then
GITHUB_TOKEN=$(grep "^GITHUB_TOKEN=" ~/.hermes/.env | head -1 | cut -d= -f2 | tr -d '\n\r')
elif grep -q "github.com" ~/.git-credentials 2>/dev/null; then
GITHUB_TOKEN=$(grep "github.com" ~/.git-credentials 2>/dev/null | head -1 | sed 's|https://[^:]*:\([^@]*\)@.*|\1|')
fi
fi
fi
echo "Using: $AUTH"
Extracting Owner/Repo from the Git Remote
Many curl commands need owner/repo. Extract it from the git remote:
REMOTE_URL=$(git remote get-url origin)
OWNER_REPO=$(echo "$REMOTE_URL" | sed -E 's|.*github\.com[:/]||; s|\.git$||')
OWNER=$(echo "$OWNER_REPO" | cut -d/ -f1)
REPO=$(echo "$OWNER_REPO" | cut -d/ -f2)
echo "Owner: $OWNER, Repo: $REPO"
1. Branch Creation
This part is pure git — identical either way:
git fetch origin
git checkout main && git pull origin main
git checkout -b feat/add-user-authentication
Branch naming conventions:
feat/description — new features
fix/description — bug fixes
refactor/description — code restructuring
docs/description — documentation
ci/description — CI/CD changes
2. Making Commits
Use the agent's file tools (write_file, patch) to make changes, then commit:
git add src/auth.py src/models/user.py tests/test_auth.py
git commit -m "feat: add JWT-based user authentication
- Add login/register endpoints
- Add User model with password hashing
- Add auth middleware for protected routes
- Add unit tests for auth flow"
Commit message format (Conventional Commits):
type(scope): short description
Longer explanation if needed. Wrap at 72 characters.
Types: feat, fix, refactor, docs, test, ci, chore, perf
3. Pushing and Creating a PR
Push the Branch (same either way)
git push -u origin HEAD
Create the PR
With gh:
gh pr create \
--title "feat: add JWT-based user authentication" \
--body "## Summary
- Adds login and register API endpoints
- JWT token generation and validation
## Test Plan
- [ ] Unit tests pass
Closes #42"
Options: --draft, --reviewer user1,user2, --label "enhancement", --base develop
With git + curl:
BRANCH=$(git branch --show-current)
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/$OWNER/$REPO/pulls \
-d "{
\"title\": \"feat: add JWT-based user authentication\",
\"body\": \"## Summary\nAdds login and register API endpoints.\n\nCloses #42\",
\"head\": \"$BRANCH\",
\"base\": \"main\"
}"
The response JSON includes the PR number — save it for later commands.
To create as a draft, add "draft": true to the JSON body.
PR Permission and Ambiguity Discipline
Before creating a PR, respect the most specific recent user instruction about PR timing. If the user explicitly said not to create a PR yet, do not treat a later vague phrase such as “move forward,” “continue,” or “when ready proceed” as authorization to open the PR unless it clearly mentions PR creation or the broader context makes that unambiguous. In that case, push the branch, report it is ready, and ask whether to open the PR; or provide the manual PR URL. This matters especially when the user said a major correction/change must happen before PR creation.
PR Creation Troubleshooting
If gh pr create fails with No commits between main and <branch>:
- Do not assume GitHub is broken. Verify the relationship first:
git fetch origin
git merge-base origin/main HEAD
git rev-list --left-right --count origin/main...HEAD
git diff --stat origin/main...HEAD
- If the branch is already an ancestor of
main or has 0 commits ahead, there is no diff to PR. Report that clearly.
- If the user still needs a PR for follow-up work, create a fresh branch from current
main, make the required changes there, commit, push, and create the PR from that new branch.
- If an interface/security gate blocks
gh pr create with BLOCKED: User denied. Do NOT retry., do not retry via gh or bypass with curl. Provide the manual GitHub PR URL instead:
echo "https://github.com/$OWNER/$REPO/pull/new/$BRANCH"
When verification is partially blocked by pre-existing unrelated failures, still run the most relevant checks. Record exactly what passed, what failed, and why the failure appears unrelated to the current diff.
4. Monitoring CI Status
Check CI Status
With gh:
gh pr checks
gh pr checks --watch
With git + curl:
SHA=$(git rev-parse HEAD)
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/commits/$SHA/status \
| python3 -c "
import sys, json
data = json.load(sys.stdin)
print(f\"Overall: {data['state']}\")
for s in data.get('statuses', []):
print(f\" {s['context']}: {s['state']} - {s.get('description', '')}\")"
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/commits/$SHA/check-runs \
| python3 -c "
import sys, json
data = json.load(sys.stdin)
for cr in data.get('check_runs', []):
print(f\" {cr['name']}: {cr['status']} / {cr['conclusion'] or 'pending'}\")"
Poll Until Complete (git + curl)
SHA=$(git rev-parse HEAD)
for i in $(seq 1 20); do
STATUS=$(curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/commits/$SHA/status \
| python3 -c "import sys,json; print(json.load(sys.stdin)['state'])")
echo "Check $i: $STATUS"
if [ "$STATUS" = "success" ] || [ "$STATUS" = "failure" ] || [ "$STATUS" = "error" ]; then
break
fi
sleep 30
done
5. Auto-Fixing CI Failures
When CI fails, diagnose and fix. This loop works with either auth method.
Step 1: Get Failure Details
With gh:
gh run list --branch $(git branch --show-current) --limit 5
gh run view <RUN_ID> --log-failed
With git + curl:
BRANCH=$(git branch --show-current)
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
"https://api.github.com/repos/$OWNER/$REPO/actions/runs?branch=$BRANCH&per_page=5" \
| python3 -c "
import sys, json
runs = json.load(sys.stdin)['workflow_runs']
for r in runs:
print(f\"Run {r['id']}: {r['name']} - {r['conclusion'] or r['status']}\")"
RUN_ID=<run_id>
curl -s -L \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/actions/runs/$RUN_ID/logs \
-o /tmp/ci-logs.zip
cd /tmp && unzip -o ci-logs.zip -d ci-logs && cat ci-logs/*.txt
Step 2: Fix and Push
After identifying the issue, use file tools (patch, write_file) to fix it:
git add <fixed_files>
git commit -m "fix: resolve CI failure in <check_name>"
git push
Step 3: Verify
Re-check CI status using the commands from Section 4 above.
Auto-Fix Loop Pattern
When asked to auto-fix CI, follow this loop:
- Check CI status → identify failures
- Read failure logs → understand the error
- Use
read_file + patch/write_file → fix the code
git add . && git commit -m "fix: ..." && git push
- Wait for CI → re-check status
- Repeat if still failing (up to 3 attempts, then ask the user)
6. Merging
With gh:
gh pr merge --squash --delete-branch
gh pr merge --auto --squash --delete-branch
With git + curl:
PR_NUMBER=<number>
curl -s -X PUT \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/pulls/$PR_NUMBER/merge \
-d "{
\"merge_method\": \"squash\",
\"commit_title\": \"feat: add user authentication (#$PR_NUMBER)\"
}"
BRANCH=$(git branch --show-current)
git push origin --delete $BRANCH
git checkout main && git pull origin main
git branch -d $BRANCH
Merge methods: "merge" (merge commit), "squash", "rebase"
Enable Auto-Merge (curl)
PR_NODE_ID=$(curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/pulls/$PR_NUMBER \
| python3 -c "import sys,json; print(json.load(sys.stdin)['node_id'])")
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/graphql \
-d "{\"query\": \"mutation { enablePullRequestAutoMerge(input: {pullRequestId: \\\"$PR_NODE_ID\\\", mergeMethod: SQUASH}) { clientMutationId } }\"}"
7. Complete Workflow Example
git checkout main && git pull origin main
git checkout -b fix/login-redirect-bug
git add src/auth/login.py tests/test_login.py
git commit -m "fix: correct redirect URL after login
Preserves the ?next= parameter instead of always redirecting to /dashboard."
git push -u origin HEAD
Useful PR Commands Reference
| Action | gh | git + curl |
|---|
| List my PRs | gh pr list --author @me | curl -s -H "Authorization: token $GITHUB_TOKEN" "https://api.github.com/repos/$OWNER/$REPO/pulls?state=open" |
| View PR diff | gh pr diff | git diff main...HEAD (local) or curl -H "Accept: application/vnd.github.diff" ... |
| Add comment | gh pr comment N --body "..." | curl -X POST .../issues/N/comments -d '{"body":"..."}' |
| Request review | gh pr edit N --add-reviewer user | curl -X POST .../pulls/N/requested_reviewers -d '{"reviewers":["user"]}' |
| Close PR | gh pr close N | curl -X PATCH .../pulls/N -d '{"state":"closed"}' |
| Check out someone's PR | gh pr checkout N | git fetch origin pull/N/head:pr-N && git checkout pr-N |