.agents/skills/resolve-backport/SKILL.md
Follow these steps precisely to resolve merge conflicts in a Vitess backport PR.
vitessio/vitess.gh pr view <number> --repo vitessio/vitess --json number,title,body,labels,headRefName,baseRefName,isDraft,assigneesBackport label. If not, stop and ask the user what they'd like to do — this skill is designed for backport PRs and should not auto-merge non-backport PRs.gh api user --jq .login), continue.Merge Conflict label — it may have been removed prematurely. Check the actual mergeable state:
gh pr view <number> --repo vitessio/vitess --json mergeable --jq .mergeable
CONFLICTING, or if the PR has a Merge Conflict label, treat it as conflicting.gh pr edit <number> --repo vitessio/vitess --add-assignee "@me"
Backport of #<number> or backport of #<number>(#<number>)
Parse from these patterns specifically — do not use a broad #(\d+) regex, as the body may reference unrelated issues. If the upstream PR number cannot be found unambiguously, ask the user to provide it.
Continue to Step 2.gh pr ready <number> --repo vitessio/vitess
b. Enable auto-merge: gh pr merge <number> --repo vitessio/vitess --squash --autogh pr diff <upstream-number> --repo vitessio/vitess
gh pr view <upstream-number> --repo vitessio/vitess --json files
git fetch origin <headRefName>
git worktree add /tmp/backport-<number> origin/<headRefName>
cd /tmp/backport-<number>
The backport branch may be based on a stale version of the release branch. Always rebase before resolving conflicts to avoid creating a resolution that conflicts with the current base.
baseRefName (e.g., release-22.0).vitessio/vitess. Do not assume it is named upstream:
git remote -v | grep 'vitessio/vitess.*fetch'
upstream or origin) for all subsequent fetch/rebase commands. If no remote points to vitessio/vitess, ask the user which remote to use.git fetch <remote> <base-branch>
git rebase <remote>/<base-branch>
go.mod on the backport branch to determine the required Go version (e.g., go 1.24.13 means minor version 1.24).go version.govm is installed (which govm). If so, use it to switch:
govm use <version>
go.mod requires go 1.24.13, run govm use 1.24.13.gvm is installed (which gvm). If so, use it to switch:
gvm use go<version>
go.mod requires go 1.24.13, run gvm use go1.24.13.ls /opt/homebrew/opt/go@<minor>/bin/go
export PATH="/opt/homebrew/opt/go@<minor>/bin:$PATH"
<<<<<<<, =======, >>>>>>>).git diff --name-only) against the upstream PR's file list.git checkout HEAD -- <file>.source build.env && go test -v <changed-packages>
web/vtadmin/ were changed, include the VTAdmin build:
source build.env && make build
source build.env && NOVTADMINBUILD=1 make build
.go files:
gofumpt -w <changed-go-files>
goimports -local "vitess.io/vitess" -w <changed-go-files>
golangci-lint run <changed-packages>
golangci-lint versions. If you get unexpected linter results, check the branch's expected version in CI config and consider using that version instead..sh files were changed, run shellcheck:
shellcheck <changed-sh-files>
go.mod was changed, run go mod tidy and include go.sum in the commit.proto/ were changed, regenerate protobuf code and include the generated files:
make proto
make vtadmin_web_proto_types
git add web/ go/vt/proto/
gh pr edit <number> --repo vitessio/vitess --remove-label "Skip CI" --remove-label "Merge Conflict"
git add <resolved-files>git commit --signoff -m "resolve conflicts for backport of #<upstream-number>"
git push --force-with-lease
gh pr comment <number> --repo vitessio/vitess --body "<summary>"
gh pr ready <number> --repo vitessio/vitess
gh pr merge <number> --repo vitessio/vitess --squash --auto
cd <original-directory>
git worktree remove <worktree-path>
This applies to both the No conflicts flow and the conflict resolution flow. After enabling auto-merge, monitor all CI checks — not just Static Code Checks.
A backport PR only exists because CI passed on the upstream PR. Any CI failure on the backport is a strong signal that our changes introduced a problem.
gh pr checks <number> --repo vitessio/vitess every 60 seconds.# Get the e2e workflow ID
workflow_id=$(gh api repos/vitessio/vitess/actions/workflows --jq '.workflows[] | select(.name | test("Cluster")) | .id' | head -1)
# Check last 10 runs for the specific job
pass=0; fail=0; total=0
while IFS= read -r rid; do
conclusion=$(gh run view "$rid" --repo vitessio/vitess --json jobs \
--jq '.jobs[] | select(.name == "<job-name>") | .conclusion' 2>/dev/null | head -1)
if [ -n "$conclusion" ] && [ "$conclusion" != "null" ] && [ "$conclusion" != "cancelled" ]; then
total=$((total + 1))
if [ "$conclusion" = "success" ]; then pass=$((pass + 1)); else fail=$((fail + 1)); fi
fi
done < <(gh api "repos/vitessio/vitess/actions/workflows/$workflow_id/runs?branch=<base-branch>&per_page=10" --jq '.workflow_runs[].id')