tool-version-upgrade
Skill573 starsChanged 8 months agoMITView on GitHub
**WORKFLOW SKILL** — Bumps pinned upstream versions in azd for the GitHub CLI, Bicep CLI, and GitHub Actions referenced in `.github/workflows/*.yml`. Fetches the latest release, confirms with the user, opens a tracking issue, updates source and workflow references, and opens a PR.
- Commits and pushes
In this repository25 other files it gives its agents.
- cli/azd/AGENTS.mdAGENTS.md
- cli/azd/extensions/azure.ai.agents/AGENTS.mdAGENTS.md
- cli/azd/extensions/azure.ai.connections/AGENTS.mdAGENTS.md
- cli/azd/extensions/azure.ai.inspector/AGENTS.mdAGENTS.md
- cli/azd/extensions/azure.ai.projects/AGENTS.mdAGENTS.md
- cli/azd/extensions/azure.ai.routines/AGENTS.mdAGENTS.md
- cli/azd/extensions/azure.ai.skills/AGENTS.mdAGENTS.md
- cli/azd/extensions/azure.ai.toolboxes/AGENTS.mdAGENTS.md
- ext/vscode/AGENTS.mdAGENTS.md
- .github/skills/extension-user-contract-review/evals/fixtures/cli/azd/AGENTS.mdAGENTS.md
- ext/vscode/.github/copilot-instructions.mdCopilot instructions
- .github/copilot-instructions.mdCopilot instructions
- azdSkill
- agentic-workflowsSkill
- azd-code-reviewerSkill
- azd-grpc-contractsSkill
- azd-preflightSkill
- changelog-generationSkill
- extension-user-contract-reviewSkill
- foundry-extension-scenario-authoringSkill
- foundry-extension-scenario-pr-regressionSkill
- foundry-extension-scenario-suite-runSkill
- senseiSkill
- weekly-demo-videoSkill
- weekly-reportSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
37 rules. About 0 are common, 21 are distinctive, and 16 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈21
Distinctive · estimate
This author's own choices. Worth a look.
16
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 42
Update the Version variable: var Version semver.Version = semver.MustParse("{new_version}")
- Very specific: line 43
Update the example comment on the download URL line if present (e.g., change the version in // example: …
- Distinctive: line 54
Update the download URL in the "Upgrade bicep" step:
- Very specific: line 89
If the user's request doesn't specify which tool, ask via ask_user:
- Distinctive: line 99
Use the corresponding column from the Supported Tools table for all subsequent steps.
- Very specific: line 109
After stripping the v prefix, validate the version is strict semver (no pre-release suffixes):
- Very specific: line 115
If the latest release is a pre-release (e.g., v0.42.0-rc1), stop and warn the user — do not use pre-release versions.
- Very specific: line 118
If gh release view fails, fall back to:
- Distinctive: line 138
If the two versions don't match, warn the user before proceeding.
- Distinctive: line 142
If the current version equals the latest release, inform the user and stop — no issue, branch, or PR needed:
- Distinctive: line 147
If the current version is newer than the latest release, stop and warn — this likely means the latest GitHub release is not yet stable, or …
- Very specific: line 153
If the latest is newer, present the upgrade summary via ask_user:
- Distinctive: line 195
If the user cancels, stop immediately — do not create the issue, branch, or PR.
- Distinctive: line 201
Verify the working tree is clean (git status --porcelain).
- Distinctive: line 206
Do NOT proceed with dirty state — do not use git stash automatically.
- Very specific: line 208
Delete any stale branch from a previous cancelled run, then create the branch from origin/main:
- Distinctive: line 216
Verify zero commits ahead of origin/main:
- Distinctive: line 222
Must produce no output. If it shows any commits, abort.
- Distinctive: line 228
Update any example URL comments that reference the old version.
- Distinctive: line 240
If the build fails, delete the branch, report the error, and stop.
- Distinctive: line 241
Do NOT create an issue or PR for a broken build.
- Distinctive: line 264
Verify nothing unexpected is staged:
- Distinctive: line 365
When the selected tool is GitHub Actions, Steps 2, 3, 4, 6, 7, and 8 differ from the single-tool flow above.
- Very specific: line 389
Treat the leading integer of tagName as the latest major (e.g., v6.0.1 → v6).
- Very specific: line 390
If the latest release is a pre-release (isPrerelease: true), fall back to:
- Very specific: line 397
If the tag does not match v[0-9]+(\.[0-9]+\.[0-9]+)?, skip this action and add it to the warnings list — do not guess.
- Very specific: line 407
If .object.type == "tag" (annotated tag), follow once:
- Distinctive: line 418
If the change list is empty after this step, inform the user and stop — no issue, branch, or PR needed:
- Very specific: line 423
If any reference has a cross-major jump (e.g., v4 → v6 skipping v5), record a
- Distinctive: line 429
Use the standard gate, but the summary must show:
- Distinctive: line 452
Use the standard clean-branch flow but with a fixed slug:
- Distinctive: line 468
After all edits, sanity-check the diff for accidental SHA-pin demotion:
- Very specific: line 474
If a -uses: owner/repo@<sha> # vN line appears paired with a +uses: owner/repo@vM
- Distinctive: line 487
If any file fails to parse, abort and revert the edits to that file.
- Very specific: line 490
If actionlint happens to be installed locally, run it as an extra check:
- Very specific: line 496
Do NOT install actionlint automatically — the project's own lint workflows will catch issues on the PR.
- Distinctive: line 586
If the user asks for any of the above, tell them this skill does not cover it.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
tool-version-upgrade
WORKFLOW SKILL — Upgrades a bundled CLI tool version in azd to the latest upstream release.
INVOKES: GitHub MCP tools, gh CLI, git CLI, go build, ask_user.
Supported Tools
| Parameter | GitHub CLI | Bicep CLI | GitHub Actions (workflows) |
| Tool name | GitHub CLI | Bicep CLI | GitHub Actions |
| Tool slug | gh-cli | bicep-cli | gh-actions |
| Upstream repo | cli/cli | Azure/bicep | (per-action; e.g. actions/checkout, actions/setup-node, golangci/golangci-lint-action) |
| Go version file | cli/azd/pkg/tools/github/github.go | cli/azd/pkg/tools/bicep/bicep.go | n/a |
| Version variable | var Version semver.Version = semver.MustParse("{version}") | same | n/a — versions are pinned per uses: line in YAML |
| Files to update | 1 file (see below) | 2 files (see below) | every .github/workflows/*.yml containing an outdated uses: reference (see below) |
GitHub CLI — Files to Update
Only one file:
cli/azd/pkg/tools/github/github.go- Update the
Versionvariable:var Version semver.Version = semver.MustParse("{new_version}") - Update the example comment on the download URL line if present (e.g., change the version in
// example: https://github.com/cli/cli/releases/download/v{version}/gh_{version}_linux_arm64.tar.gz)
- Update the
Bicep CLI — Files to Update
Two files (both must be updated together):
cli/azd/pkg/tools/bicep/bicep.go- Update the
Versionvariable:var Version semver.Version = semver.MustParse("{new_version}")
- Update the
.github/workflows/lint-bicep.yml- Update the download URL in the "Upgrade bicep" step:
sudo curl -o $(which bicep) -L https://github.com/Azure/bicep/releases/download/v{new_version}/bicep-linux-x64
- Update the download URL in the "Upgrade bicep" step:
⚠️ Important (Bicep only): Both files must be updated together to keep Go code and CI workflow in sync. Forgetting the workflow file is a common mistake — always verify both are changed.
GitHub Actions (workflows) — Files to Update
N files — every .github/workflows/*.yml containing an outdated uses: reference. Scope is
limited to that directory; do not edit local actions, reusable workflows in this repo, or
devcontainer feature definitions.
For each uses: owner/repo@ref line, classify and act:
| Bucket | Pattern | Action |
| Major-tag pin | uses: owner/repo@vN (N is an integer) | Bump to latest stable major (@vM). |
| Exact-version pin | uses: owner/repo@vX.Y.Z or @X.Y.Z | Bump to latest stable major tag (@vM). |
| SHA pin | uses: owner/repo@<40-hex-sha> # vN | Resolve the SHA the latest major tag points to, replace both the SHA and the trailing # vN comment so they stay paired. Never demote a SHA pin to a bare tag. |
| Branch ref | uses: owner/repo@main (or any non-version ref) | Skip, list as warning. Branch refs are usually intentional. |
| Local action | uses: ./... | Skip silently. |
| Local reusable workflow | uses: ./.github/workflows/... | Skip silently. |
⚠️ Important (GitHub Actions only): one run produces one tracking issue and one PR covering every outdated reference, grouped by action. Do not open one PR per action.
⚠️ Supply-chain hardening: SHA-pinned references exist on purpose — typically for workflows that gate releases or extension approvals (e.g.,
approval-ext-azure-ai-agents.yml).
Workflow
Step 1 — Identify Tool
If the user's request doesn't specify which tool, ask via ask_user:
Which tool would you like to upgrade?
Choices:
- GitHub CLI
- Bicep CLI
- GitHub Actions (workflow files)
Use the corresponding column from the Supported Tools table for all subsequent steps.
Step 2 — Fetch Latest Release
gh release view --repo {upstream_repo} --json tagName,name,publishedAt,bodyThe tag format is v{version} (e.g., v2.86.0 or v0.41.2). Strip the v prefix to get the semver.
After stripping the v prefix, validate the version is strict semver (no pre-release suffixes):
echo "$version" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$' || { echo "Unexpected version format: $version"; exit 1; }If the latest release is a pre-release (e.g., v0.42.0-rc1), stop and warn the user — do not
use pre-release versions. Suggest the user wait for the stable release or specify a version manually.
If gh release view fails, fall back to:
gh api repos/{upstream_repo}/releases/latest --jq '.tag_name'Step 3 — Read Current Version
grep -n 'var Version semver.Version' {go_version_file}Extract the version string from the semver.MustParse("X.Y.Z") call.
Bicep only — also verify the CI workflow version matches:
grep -n 'bicep/releases/download' .github/workflows/lint-bicep.ymlIf the two versions don't match, warn the user before proceeding.
Step 4 — Compare & Confirm Upgrade
If the current version equals the latest release, inform the user and stop — no issue, branch, or PR needed:
✅ {tool_name} is already at the latest version ({version}). No update needed.
If the current version is newer than the latest release, stop and warn — this likely means the latest GitHub release is not yet stable, or the pinned version was set manually:
⚠️ The current {tool_name} version ({current_version}) is newer than the latest release ({latest_version}). This may indicate a pre-release pin or a release rollback. No action taken.
If the latest is newer, present the upgrade summary via
ask_user:The current {tool_name} version is {current_version}. The latest release is {latest_version} (released {release_date}).
Proceed with upgrade?
Choices:
- Yes, upgrade to {latest_version} (Recommended)
- No, cancel
Step 5 — Final Confirmation Gate
⚠️ MANDATORY — even in autopilot / auto-approve / yolo mode. This confirmation MUST use
ask_userand MUST NOT be skipped regardless of agent autonomy settings. This is a safety gate to prevent false-positive upgrades (e.g., wrong version parsed, pre-release tag picked up).
Present a full summary via ask_user:
Ready to apply {tool_name} upgrade
- Current version: {current_version}
- Target version: {latest_version}
- Upstream release: {release_url}
- Files to modify: {files_list_with_paths}
This will:
- Create a tracking issue in Azure/azure-dev
- Create a new branch from
origin/main- Apply the version changes
- Open a PR
Confirm to proceed?
Choices:
- Yes, apply upgrade (Recommended)
- No, cancel
If the user cancels, stop immediately — do not create the issue, branch, or PR.
Step 6 — Create Clean Branch, Apply Changes & Build
Per references/tool-upgrade-workflow.md § Create Clean Branch from origin/main.
Verify the working tree is clean (
git status --porcelain). If dirty, stop and warn:Your working tree has uncommitted changes. Please commit or stash them before running this skill, so the upgrade PR contains only the version bump.
Do NOT proceed with dirty state — do not use
git stashautomatically.Delete any stale branch from a previous cancelled run, then create the branch from
origin/main:git fetch origin main git branch -D update/{tool_slug}-{latest_version} 2>/dev/null || true git checkout -b update/{tool_slug}-{latest_version} origin/mainVerify zero commits ahead of origin/main:
git --no-pager log --oneline origin/main..HEADMust produce no output. If it shows any commits, abort.
Apply the file edits:
GitHub CLI: Edit
cli/azd/pkg/tools/github/github.go:- Replace version in
semver.MustParse("{old}")with the new version. - Update any example URL comments that reference the old version.
Bicep CLI: Edit both files:
cli/azd/pkg/tools/bicep/bicep.go— replace version insemver.MustParse("{old}")..github/workflows/lint-bicep.yml— replace old version in the curl download URL.
- Replace version in
Build and verify:
cd cli/azd && go build ./...If the build fails, delete the branch, report the error, and stop. Do NOT create an issue or PR for a broken build.
Bicep only — verify both files have the new version:
grep 'MustParse' cli/azd/pkg/tools/bicep/bicep.go | head -1 grep 'bicep/releases/download' .github/workflows/lint-bicep.ymlStage only the expected files (do NOT use
git add -A):GitHub CLI:
git add cli/azd/pkg/tools/github/github.goBicep CLI:
git add cli/azd/pkg/tools/bicep/bicep.go .github/workflows/lint-bicep.yml- Verify nothing unexpected is staged:
Output must show ONLY the expected files. If unexpected files appear, abort.git --no-pager diff --cached --stat
Step 7 — Create Tracking Issue
Note: The issue is created after the build succeeds to avoid orphan issues when the build or staging validation fails.
gh issue create \
--repo Azure/azure-dev \
--title "Update {tool_name} version to {latest_version}" \
--body "{issue_body}"GitHub CLI issue body:
Update GitHub CLI version from {current_version} to {latest_version}.
Release: https://github.com/cli/cli/releases/tag/v{latest_version}
### Files to update
- [ ] `cli/azd/pkg/tools/github/github.go` — update `Version` variable to `{latest_version}`Bicep CLI issue body:
Update Bicep CLI version from {current_version} to {latest_version}.
Release: https://github.com/Azure/bicep/releases/tag/v{latest_version}
### Files to update
- [ ] `cli/azd/pkg/tools/bicep/bicep.go` — update `Version` variable to `{latest_version}`
- [ ] `.github/workflows/lint-bicep.yml` — update download URL to `v{latest_version}`Capture the issue number from the output.
Step 8 — Commit & PR
git commit -m "Update {tool_name} to v{latest_version}" \
-m "Fixes #{issue_number}"
git push -u origin update/{tool_slug}-{latest_version}
gh pr create \
--repo Azure/azure-dev \
--title "Update {tool_name} to v{latest_version}" \
--body "{pr_body}" \
--base mainGitHub CLI PR body:
Updates the bundled GitHub CLI version from {current_version} to {latest_version}.
Fixes #{issue_number}
Release: https://github.com/cli/cli/releases/tag/v{latest_version}
## Changes
- Bumped `Version` constant in `cli/azd/pkg/tools/github/github.go`Bicep CLI PR body:
Updates the bundled Bicep CLI version from {current_version} to {latest_version}.
Fixes #{issue_number}
Release: https://github.com/Azure/bicep/releases/tag/v{latest_version}
## Changes
- Bumped `Version` constant in `cli/azd/pkg/tools/bicep/bicep.go`
- Updated download URL in `.github/workflows/lint-bicep.yml`Post-Creation
Present a summary to the user:
✅ Done!
- Issue: #{issue_number} — {issue_url}
- PR: #{pr_number} — {pr_url}
- Version: {current_version} → {latest_version}
GitHub Actions (workflows) — Step Overrides
When the selected tool is GitHub Actions, Steps 2, 3, 4, 6, 7, and 8 differ from the
single-tool flow above. Steps 1 (Identify Tool) and 5 (Final Confirmation Gate) work the
same way. The branch slug is gh-actions-versions (no version suffix, since this run
covers many actions at once).
Step 2 (override) — Inventory References
Scan every workflow file:
git grep -nE '^\s*uses:\s+[^ ]+' -- '.github/workflows/*.yml'Parse each line into one of the buckets in GitHub Actions (workflows) — Files to Update.
Deduplicate by (owner/repo, current_ref) so each unique reference is fetched only once.
Step 3 (override) — Fetch Latest Stable Major per Action
For each unique owner/repo:
gh release view --repo {owner}/{repo} --json tagName,name,publishedAt,isPrereleaseTreat the leading integer of tagName as the latest major (e.g., v6.0.1 → v6).
If the latest release is a pre-release (isPrerelease: true), fall back to:
gh release list --repo {owner}/{repo} --limit 20 --json tagName,isPrerelease \
| jq -r '[.[] | select(.isPrerelease==false)][0].tagName'If the tag does not match v[0-9]+(\.[0-9]+\.[0-9]+)?, skip this action and add it
to the warnings list — do not guess.
For SHA-pinned references, additionally resolve the commit SHA the major tag currently points to:
gh api repos/{owner}/{repo}/git/refs/tags/v{major} --jq '.object.sha'If .object.type == "tag" (annotated tag), follow once:
gh api repos/{owner}/{repo}/git/tags/{sha} --jq '.object.sha'Step 4 (override) — Compute Diff & Compare
For each parsed reference, compute the desired new value per the buckets table. If
new == current, drop from the change list.
If the change list is empty after this step, inform the user and stop — no issue, branch, or PR needed:
✅ All GitHub Actions references are already at the latest stable major. No updates needed.
If any reference has a cross-major jump (e.g., v4 → v6 skipping v5), record a
breaking-change advisory for the Step 5 confirmation prompt so the user can
spot-check release notes before approving.
Step 5 (Final Confirmation Gate — adapted)
Use the standard gate, but the summary must show:
- Outdated references grouped by action with
current → newand the affected file count. - Skipped entries (branch refs, unparseable tags, pre-release-only repos).
- Cross-major-jump advisories.
- The full list of files that will be modified.
Example summary body:
GitHub Actions upgrade — ready to apply
Action Current New Files actions/checkout v4 v6 14 actions/setup-node v4 v6 7 actions/github-script v7 (SHA-pinned) v9 (SHA-pinned) 1 Skipped (branch refs):
actions/stale@maininstale-issues.yml⚠️ Cross-major jumps:
actions/checkout v4 → v6(skips v5).
Step 6 (override) — Branch & Apply Edits
Use the standard clean-branch flow but with a fixed slug:
git fetch origin main
git branch -D update/gh-actions-versions 2>/dev/null || true
git checkout -b update/gh-actions-versions origin/main
git --no-pager log --oneline origin/main..HEAD # must be emptyApply edits with these constraints:
- Replace only on the parsed
uses:lines. Never use a project-wide find-and-replace. - For SHA-pinned references, replace both the SHA and the trailing
# vNcomment in a single edit so they stay paired. - Preserve indentation and surrounding YAML exactly.
After all edits, sanity-check the diff for accidental SHA-pin demotion:
git --no-pager diff -- '.github/workflows/*.yml' | grep -E '^[-+].*uses:'If a -uses: owner/repo@<sha> # vN line appears paired with a +uses: owner/repo@vM
without an SHA, abort and report.
Step 7 (override) — Validation & Staging
There is no Go build for workflow-only edits. Validate YAML parses:
for f in .github/workflows/*.yml; do
python -c "import sys, yaml; yaml.safe_load(open(sys.argv[1]))" "$f"
doneIf any file fails to parse, abort and revert the edits to that file. If every file fails, abort the whole run.
If actionlint happens to be installed locally, run it as an extra check:
actionlint .github/workflows/*.yml || trueDo NOT install actionlint automatically — the project's own lint workflows will
catch issues on the PR.
Stage explicitly — never git add -A:
git add .github/workflows/*.yml
git --no-pager diff --cached --statThe diff stat must contain ONLY paths under .github/workflows/. If anything else
is staged, abort.
Step 8 (override) — Issue, Commit & PR
Issue title: Update GitHub Actions to latest stable versions
Issue body:
Audit and bump GitHub Actions referenced in `.github/workflows/*.yml` to the latest
stable major versions.
### Upgrades
{table_of_action_to_current_to_new_to_file_count}
### Skipped
{list_of_skipped_branch_refs_or_unparseable_tags}
### Files modified
{bullet_list_of_workflow_files}Commit & push:
git commit -m "Update GitHub Actions to latest stable versions" \
-m "Fixes #{issue_number}"
git push -u origin update/gh-actions-versions
gh pr create \
--repo Azure/azure-dev \
--title "Update GitHub Actions to latest stable versions" \
--body "{pr_body}" \
--base mainPR body:
Bump all GitHub Actions referenced in workflow files to their latest stable major versions.
Fixes #{issue_number}
## Upgrades
{table_of_action_to_current_to_new_to_file_count}
## Notes
- Major-tag pins (`@vN`) preserved.
- SHA pins (`@<sha> # vN`) preserved as SHA pins, with both the SHA and the `# vN`
comment updated together to stay in sync.
- Branch refs (e.g., `@main`) intentionally skipped.
- Cross-major jumps (where applicable) called out below; release notes should be
reviewed before merge.
{breaking_change_callouts_if_any}Post-Creation (GitHub Actions)
✅ Done!
- Issue: #{issue_number} — {issue_url}
- PR: #{pr_number} — {pr_url}
- Actions bumped: {count}
- Files modified: {file_count}
Out of Scope (GitHub Actions)
- Pinning previously unpinned actions to SHAs. (Use the existing convention: bare major tags by default; SHAs only where the file already SHA-pins.)
- Bumping the Go toolchain inside
setup-gowith: go-version:— that's a separate workflow (validate-go-version). - Bumping Node / Python / Bicep tool runtime versions inside
setup-*with:blocks. - Updating actions used outside
.github/workflows/(e.g., devcontainer features).
If the user asks for any of the above, tell them this skill does not cover it.
Error Handling
gh release viewfails → fall back togh api repos/{upstream_repo}/releases/latest- Already up to date → inform user, stop
- Working tree dirty → stop, tell user to commit/stash first
- Build fails after version change → revert, report error, stop
- Version mismatch between
bicep.goandlint-bicep.ymlbefore upgrade → warn user, ask which to use as baseline - Unexpected files staged → abort, report what was found
- Issue or PR creation fails → report error, provide manual commands
- GitHub Actions only —
gh release viewfails for an action → fall back togh release listand pick the newest non-prerelease; if still none, skip the action and add it to warnings - GitHub Actions only — YAML parse failure after edits → revert that file, drop it from the change list, continue with the rest. If every file fails, abort the run.
- GitHub Actions only — a SHA pin demoted to a bare tag pin detected in the diff → abort, report the file/line, do not commit
- GitHub Actions only — a major tag (e.g.,
@v3) no longer exists upstream because the action was renamed/archived → skip and add to warnings; never silently rewrite to a differentowner/repo
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

