This skill should be used when the user asks to "commit and push", "push my changes", or wants to commit, push, and respond to PR comments.
Commit changes, run local validation, push to remote, open a draft PR if needed, and ensure CI passes.
Before running validation, clean up your changes:
Before committing, run all local checks:
Linting, Typechecking, and Formatting:
ruff check, eslint, golangci-lint)basedpyright, , )mypytsc --noEmitruff format --check, prettier --check, gofmt)Tests:
@pytest.mark.slow (search for mark.slow in test files)pytest -m "not slow" for fast tests, then run affected slow testspytest, npm test, go test ./...uv pip show pytest-xdist), use -n auto for parallel execution:
pytest -n auto -m "not slow" # fast tests in parallel
pytest -n auto path/to/slow_test1.py path/to/slow_test2.py # affected slow tests in parallel
If this is a DVC-tracked repository (has .dvc files or dvc.yaml):
dvc repro to reproduce any affected pipelinesdvc push to push data artifacts to remote storagecheck-dvc CI failuresFixing check-dvc CI failures:
dvc status --remote to see which files are missingdvc push to upload missing files to the remote.dvc files if they changedIf this is a Pivot-tracked repository (has .pvt files or pipeline.py):
pivot run to execute any outdated pipeline stagespivot push to push outputs to S3.pvt or .pivot/stages/*.lock filescheck-pivot CI failuresFixing check-pivot CI failures:
pivot status to see which stages need to runpivot run to execute outdated stages (or pivot run stage_name@variant for specific stages)pivot push to upload outputs to S3.pvt or .pivot/stages/*.lock filesOnce local validation passes:
git status and git diff to see changesgit log --oneline -3 to match commit message stylegit addgit pushDetermine if you're pushing directly to the main branch:
current_branch=$(git branch --show-current)
main_branch=$(git remote show origin | grep 'HEAD branch' | cut -d: -f2 | xargs)
if [ "$current_branch" = "$main_branch" ]; then
# Pushing directly to main - skip PR creation, go to step 10
echo "On main branch, skipping PR workflow"
fi
If on main/master: Skip steps 6-9 and go directly to step 10 (Wait for CI on Direct Push).
If on a feature branch: Continue with step 6.
Before creating a PR, determine the correct base branch:
# Get the main/master branch name
main_branch=$(git remote show origin | grep 'HEAD branch' | cut -d: -f2 | xargs)
# Find the merge-base with main
merge_base=$(git merge-base HEAD origin/$main_branch)
# Check if there's another branch between current branch and main
# This finds branches that contain the merge-base but are not main
intermediate_branch=$(git branch -r --contains $merge_base | grep -v "origin/$main_branch" | grep -v "origin/HEAD" | head -1 | xargs)
# If an intermediate branch exists and is an ancestor of HEAD, use it as base
if [ -n "$intermediate_branch" ]; then
base_branch=${intermediate_branch#origin/}
else
base_branch=$main_branch
fi
Use $base_branch as the PR base instead of always using main/master.
Check if the current branch has an open PR:
gh pr view --json number,url,state,isDraft 2>/dev/null
If no PR exists:
gh pr create --draft --base $base_branch --title "..." --body "..."
gh pr edit --add-assignee tbroadley
OKR-):
# List available OKR labels
gh label list --search "OKR-"
# Add the appropriate label using the API (gh pr edit --add-label can fail due to deprecated Projects classic)
gh api repos/{owner}/{repo}/issues/{pr_number}/labels -f "labels[]=okr-..."
If PR already exists:
# Review all commits on the branch vs base
git log origin/$base_branch..HEAD --oneline
git diff origin/$base_branch..HEAD --stat
# Update the PR title and body via the API
gh api repos/{owner}/{repo}/pulls/{pr_number} -X PATCH \
-f title="<concise title reflecting all branch changes>" \
-f body="$(cat <<'EOF'
## Summary
<1-3 bullet points covering all changes on the branch>
## Test plan
<how the changes were validated>
EOF
)"
First, check if the repo has GitHub Actions workflows:
# Check for workflow files
if ! ls .github/workflows/*.yml .github/workflows/*.yaml 2>/dev/null | head -1 > /dev/null; then
echo "No GitHub Actions workflows found, skipping CI wait"
# Skip to step 9
fi
If no workflows exist, skip waiting for CI and proceed to step 9.
Before waiting for CI, check for merge conflicts:
Merge conflicts prevent CI from running. Check immediately after pushing:
gh pr view --json mergeable,mergeStateStatus
mergeable is false or mergeStateStatus is DIRTY, there are merge conflictsmergeable is UNKNOWN, wait a few seconds and check again (GitHub is still computing)If merge conflicts exist, resolve them before waiting for CI (see "If CI cannot run" below).
If no conflicts, monitor CI status:
gh pr checks --watch
If CI cannot run (e.g., merge conflict):
gh pr view --json mergeable,mergeStateStatusgit fetch origin $base_branch
git rebase origin/$base_branch
# Resolve conflicts
git add .
git rebase --continue
git push --force-with-leaseIf CI fails:
gh pr checksgh run view <run_id> --log-failedIMPORTANT: Never leave top-level comments on the PR (via gh pr comment or the issues comments API). Only reply directly within review comment threads using the replies API. Top-level comments like "Addressed review feedback" clutter the PR.
If there are existing PR review comments, check if pushed changes address them.
Fetch review comments:
gh api repos/{owner}/{repo}/pulls/{pr_number}/comments --paginate
For each unresolved comment that was addressed:
Leave a reply:
gh api repos/{owner}/{repo}/pulls/{pr_number}/comments/{comment_id}/replies \
-f body="<agent-name>: <explanation of how this was addressed>"
Resolve the thread:
gh api graphql -f query='
mutation {
resolveReviewThread(input: {threadId: "<thread_id>"}) {
thread { isResolved }
}
}
'
To get thread IDs:
gh api graphql -f query='
query {
repository(owner: "{owner}", name: "{repo}") {
pullRequest(number: {pr_number}) {
reviewThreads(first: 100) {
nodes {
id
isResolved
comments(first: 1) {
nodes {
id
databaseId
body
}
}
}
}
}
}
}
'
Re-request review: After addressing all comments from a reviewer, request their re-review:
gh pr edit --add-reviewer <reviewer-username>
To find reviewers who left comments:
gh api repos/{owner}/{repo}/pulls/{pr_number}/reviews --jq '.[].user.login' | sort -u
First, check if the repo has GitHub Actions workflows:
# Check for workflow files
if ! ls .github/workflows/*.yml .github/workflows/*.yaml 2>/dev/null | head -1 > /dev/null; then
echo "No GitHub Actions workflows found, skipping CI wait"
# Task complete - no CI to wait for
fi
If no workflows exist, the task is complete.
If workflows exist, monitor CI using the workflow run:
# Watch the CI run for the latest commit
gh run watch
If CI fails:
gh run view --log-failedgh pr edit often fails with "Projects (classic) deprecation" errors. Use the API directly instead:
# Edit PR body
gh api repos/{owner}/{repo}/pulls/{number} -X PATCH -f body="..."
# Add reviewer
gh api repos/{owner}/{repo}/pulls/{number}/requested_reviewers -X POST -f "reviewers[]=username"
# Add label
gh api repos/{owner}/{repo}/issues/{number}/labels -f "labels[]=label-name"
# Add assignee
gh api repos/{owner}/{repo}/issues/{number}/assignees -f "assignees[]=username"