|
| 1 | +--- |
| 2 | +description: Upgrade gh-aw extension, recompile and validate all workflows, and open a PR with changes |
| 3 | +argument-hint: "[--force] [--dry-run] [--no-merge] [--strict]" |
| 4 | +--- |
| 5 | + |
| 6 | +# /aw-upgrade |
| 7 | + |
| 8 | +End-to-end `gh-aw` upgrade, recompile, validate, and PR cycle. Designed for idempotent, unattended execution across many repos. |
| 9 | + |
| 10 | +## Usage |
| 11 | + |
| 12 | +``` |
| 13 | +/aw-upgrade → Full upgrade cycle: upgrade extension → upgrade repo → validate → PR → merge |
| 14 | +/aw-upgrade --force → Run even if gh-aw extension is already on latest version |
| 15 | +/aw-upgrade --dry-run → Show what would change without committing or creating a PR |
| 16 | +/aw-upgrade --no-merge → Create PR but do not auto-merge |
| 17 | +/aw-upgrade --strict → Enforce strict mode validation for all workflows |
| 18 | +``` |
| 19 | + |
| 20 | +## Workflow |
| 21 | + |
| 22 | +You are an operations automation agent performing an unattended gh-aw upgrade cycle. Execute the phases below **in order**. If any phase fails, **stop immediately**, report which phase failed and why, and do not proceed to subsequent phases. |
| 23 | + |
| 24 | +**Do not prompt the user for input at any point.** This command is designed for bulk execution (`$GPM_PROVISION_BULK=true`). |
| 25 | + |
| 26 | +Parse the argument string for flags: `--force`, `--dry-run`, `--no-merge`, `--strict`. Unknown flags should be rejected with an error message. |
| 27 | + |
| 28 | +--- |
| 29 | + |
| 30 | +### Phase 1: Pre-flight checks |
| 31 | + |
| 32 | +1. Verify `gh` CLI is available: `gh --version` |
| 33 | +2. Verify `gh aw` extension is installed: `gh aw version` |
| 34 | + - If not installed, install it: `gh extension install github/gh-aw` |
| 35 | + - After install, capture version: `gh aw version` |
| 36 | +3. Verify the current directory is a git repository with `.github/workflows/` containing at least one `.md` file |
| 37 | +4. Verify working tree is clean: `git status --porcelain` must be empty |
| 38 | + - If not clean, **abort** with error: "Working tree is dirty. Commit or stash changes before running /aw-upgrade." |
| 39 | +5. Capture the current branch name for later restoration |
| 40 | + |
| 41 | +Report: current gh-aw version, repo name, number of `.md` workflow files found. |
| 42 | + |
| 43 | +--- |
| 44 | + |
| 45 | +### Phase 2: Upgrade gh-aw extension |
| 46 | + |
| 47 | +1. Record the **before** version: `gh aw version` |
| 48 | +2. Run: `gh extension upgrade github/gh-aw --force` |
| 49 | +3. Record the **after** version: `gh aw version` |
| 50 | +4. Compare versions: |
| 51 | + - If versions are identical **and** `--force` was NOT passed: report "gh-aw is already on latest version (vX.Y.Z). No upgrade needed." and **exit successfully** (skip all remaining phases). |
| 52 | + - If versions are identical **and** `--force` WAS passed: continue to Phase 3 with note "Forced recompile on same version." |
| 53 | + - If versions differ: report "Upgraded gh-aw from vX.Y.Z to vA.B.C" and continue. |
| 54 | + |
| 55 | +--- |
| 56 | + |
| 57 | +### Phase 3: Upgrade repository workflows |
| 58 | + |
| 59 | +1. Create a new branch: `git checkout -b chore/gh-aw-upgrade-{after_version}` (e.g., `chore/gh-aw-upgrade-v0.60.0`) |
| 60 | + - If branch already exists, append a timestamp: `chore/gh-aw-upgrade-{after_version}-{YYYYMMDD}` |
| 61 | +2. Run the gh-aw upgrade command: |
| 62 | + ``` |
| 63 | + gh aw upgrade --verbose |
| 64 | + ``` |
| 65 | + This performs: dispatcher agent update, codemod fixes, action version updates, and full recompilation. |
| 66 | +3. Check `git diff` for changes: |
| 67 | + - If no files changed: restore original branch (`git checkout -`), delete the upgrade branch, and report "No workflow changes after upgrade. Repo is already current." **Exit successfully.** |
| 68 | + - If files changed: report summary of changed files and continue. |
| 69 | + |
| 70 | +If `--dry-run` was passed: show the diff, restore original branch, delete the upgrade branch, and **exit** with the diff summary. Do not commit or create a PR. |
| 71 | + |
| 72 | +--- |
| 73 | + |
| 74 | +### Phase 4: Validate all workflows |
| 75 | + |
| 76 | +1. Run full validation with all security scanners: |
| 77 | + ``` |
| 78 | + gh aw validate --strict --json |
| 79 | + ``` |
| 80 | + - If `--strict` flag was NOT passed to `/aw-upgrade`, omit `--strict` from the validate command. |
| 81 | +2. Parse the JSON output for errors: |
| 82 | + - If validation **passes**: report "All workflows validated successfully." and continue. |
| 83 | + - If validation **fails**: report the validation errors clearly, restore original branch (`git checkout -`), delete the upgrade branch, and **abort**. The user must fix validation errors manually before re-running. |
| 84 | + |
| 85 | +--- |
| 86 | + |
| 87 | +### Phase 5: Commit and push |
| 88 | + |
| 89 | +1. Stage all changed files: `git add .github/` |
| 90 | +2. Commit with conventional message: |
| 91 | + ``` |
| 92 | + git commit -m "chore(ci): recompile workflows for gh-aw {after_version} |
| 93 | +
|
| 94 | + Ran \`gh aw upgrade\` to update dispatcher agent, apply codemods, |
| 95 | + update action pins, and recompile all workflow lock files." |
| 96 | + ``` |
| 97 | +3. Push the branch: `git push -u origin HEAD` |
| 98 | + |
| 99 | +Report: commit SHA, branch name, number of files changed. |
| 100 | + |
| 101 | +--- |
| 102 | + |
| 103 | +### Phase 6: Create and merge PR |
| 104 | + |
| 105 | +1. Create PR: |
| 106 | + ``` |
| 107 | + gh pr create \ |
| 108 | + --title "chore(ci): upgrade gh-aw workflows to {after_version}" \ |
| 109 | + --body "## Summary |
| 110 | +
|
| 111 | + - Upgraded gh-aw extension from {before_version} to {after_version} |
| 112 | + - Ran \`gh aw upgrade\` to apply codemods, update action pins, and recompile lock files |
| 113 | + - All workflows validated successfully |
| 114 | +
|
| 115 | + ## Changed files |
| 116 | +
|
| 117 | + {list of changed files} |
| 118 | +
|
| 119 | + --- |
| 120 | + _Automated by /aw-upgrade_" \ |
| 121 | + --label "dependencies,ci" |
| 122 | + ``` |
| 123 | + - If labels don't exist, omit `--label` and continue without failing. |
| 124 | +2. Wait for CI checks: |
| 125 | + - Poll with `gh pr checks` every 15 seconds, up to 10 minutes max. |
| 126 | + - If checks pass: continue to merge. |
| 127 | + - If checks fail: report which checks failed and **do not merge**. Leave the PR open for manual review. Report the PR URL and exit. |
| 128 | + - If no checks are configured (empty checks): proceed to merge. |
| 129 | +3. Merge (unless `--no-merge` was passed): |
| 130 | + ``` |
| 131 | + gh pr merge --squash --auto --delete-branch |
| 132 | + ``` |
| 133 | + - If `--no-merge` was passed: skip merge, report PR URL, and exit successfully. |
| 134 | +4. Restore original branch: `git checkout {original_branch} && git pull` |
| 135 | + |
| 136 | +Report: PR URL, merge status, final state. |
| 137 | + |
| 138 | +--- |
| 139 | + |
| 140 | +### Error Recovery |
| 141 | + |
| 142 | +If any phase fails mid-execution: |
| 143 | +1. Report the phase number, command that failed, and exit code/stderr |
| 144 | +2. If a branch was created, leave it for inspection (do not auto-delete on error) |
| 145 | +3. If on the upgrade branch, switch back to the original branch |
| 146 | +4. Exit with a clear error message |
| 147 | + |
| 148 | +--- |
| 149 | + |
| 150 | +### Final Report |
| 151 | + |
| 152 | +After all phases complete (or on early exit), print a summary: |
| 153 | + |
| 154 | +``` |
| 155 | +┌─────────────────────────────────────┐ |
| 156 | +│ /aw-upgrade complete │ |
| 157 | +├─────────────────────────────────────┤ |
| 158 | +│ Repository: {owner/repo} │ |
| 159 | +│ gh-aw: {before} → {after} │ |
| 160 | +│ Workflows: {N} compiled │ |
| 161 | +│ Validation: ✓ passed │ |
| 162 | +│ PR: {url} │ |
| 163 | +│ Merged: yes/no/skipped │ |
| 164 | +└─────────────────────────────────────┘ |
| 165 | +``` |
| 166 | + |
| 167 | +<!-- |
| 168 | +## Phase 5 Investigation: GitHub Actions Automation |
| 169 | +
|
| 170 | +### How to automate /aw-upgrade as a GitHub Actions workflow |
| 171 | +
|
| 172 | +The `gh aw upgrade --create-pull-request` flag already handles the upgrade + PR |
| 173 | +creation natively within gh-aw. This is the recommended path for CI automation |
| 174 | +rather than reimplementing the logic. |
| 175 | +
|
| 176 | +#### Recommended workflow: `.github/workflows/gh-aw-upgrade.lock.yml` |
| 177 | +
|
| 178 | +Source as a gh-aw markdown workflow or a plain YAML workflow: |
| 179 | +
|
| 180 | +```yaml |
| 181 | +name: gh-aw Upgrade Check |
| 182 | +on: |
| 183 | + schedule: |
| 184 | + - cron: '0 8 * * 1' # Weekly Monday 8am UTC |
| 185 | + workflow_dispatch: |
| 186 | + inputs: |
| 187 | + force: |
| 188 | + description: 'Force upgrade even if on latest' |
| 189 | + type: boolean |
| 190 | + default: false |
| 191 | +
|
| 192 | +permissions: |
| 193 | + contents: write |
| 194 | + pull-requests: write |
| 195 | +
|
| 196 | +jobs: |
| 197 | + upgrade: |
| 198 | + runs-on: ubuntu-latest |
| 199 | + steps: |
| 200 | + - uses: actions/checkout@v4 |
| 201 | +
|
| 202 | + - name: Install gh-aw |
| 203 | + run: gh extension install github/gh-aw |
| 204 | + env: |
| 205 | + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 206 | +
|
| 207 | + - name: Record version before |
| 208 | + id: before |
| 209 | + run: echo "version=$(gh aw version | awk '{print $NF}')" >> "$GITHUB_OUTPUT" |
| 210 | +
|
| 211 | + - name: Upgrade gh-aw extension |
| 212 | + run: gh extension upgrade github/gh-aw --force |
| 213 | + env: |
| 214 | + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 215 | +
|
| 216 | + - name: Record version after |
| 217 | + id: after |
| 218 | + run: echo "version=$(gh aw version | awk '{print $NF}')" >> "$GITHUB_OUTPUT" |
| 219 | +
|
| 220 | + - name: Upgrade repository workflows and create PR |
| 221 | + if: steps.before.outputs.version != steps.after.outputs.version || inputs.force |
| 222 | + run: gh aw upgrade --create-pull-request --verbose |
| 223 | + env: |
| 224 | + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 225 | +
|
| 226 | + - name: Auto-merge PR |
| 227 | + if: steps.before.outputs.version != steps.after.outputs.version || inputs.force |
| 228 | + run: | |
| 229 | + PR_URL=$(gh pr list --head "gh-aw-upgrade" --json url --jq '.[0].url' 2>/dev/null) |
| 230 | + if [ -n "$PR_URL" ]; then |
| 231 | + gh pr merge "$PR_URL" --squash --auto --delete-branch |
| 232 | + fi |
| 233 | + env: |
| 234 | + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 235 | +``` |
| 236 | +
|
| 237 | +#### Key considerations: |
| 238 | +
|
| 239 | +1. **`gh aw upgrade --create-pull-request`** is the native flag — it handles |
| 240 | + branch creation, commit, and PR in one command. Prefer this over manual |
| 241 | + git operations in CI. |
| 242 | +
|
| 243 | +2. **Authentication**: Use `GITHUB_TOKEN` for same-repo. For cross-repo |
| 244 | + provisioning via GPM, use a GitHub App token with `contents: write` and |
| 245 | + `pull-requests: write` on target repos. |
| 246 | +
|
| 247 | +3. **GPM provisioning**: This workflow YAML can be deployed across repos using |
| 248 | + the GPM `gpm-workflows-deploy` skill. Add it to gpm-config.yml under |
| 249 | + `workflows:` and GPM will push it to all managed repos. |
| 250 | +
|
| 251 | +4. **Alternative: gh-aw native workflow**: Write this as a gh-aw `.md` |
| 252 | + workflow that triggers on schedule, uses bash tools to run `gh extension |
| 253 | + upgrade` and `gh aw upgrade --create-pull-request`. This keeps the |
| 254 | + automation within the gh-aw ecosystem. |
| 255 | +
|
| 256 | +5. **Branch naming**: `gh aw upgrade --create-pull-request` creates its own |
| 257 | + branch name. Check `gh aw upgrade --help` for any `--branch` flag in |
| 258 | + future versions if custom naming is needed. |
| 259 | +
|
| 260 | +6. **Idempotency**: The workflow is safe to re-run. If no changes result |
| 261 | + from `gh aw upgrade`, no PR is created. If a PR already exists, gh-aw |
| 262 | + will update it or skip. |
| 263 | +--> |
0 commit comments