Conversation
…t major version - Add isCoreAction() helper to identify repos under actions/ org - Modify UpdateActions to always allow major version bumps for actions/* - Add UpdateActionsInWorkflowFiles() to update uses: actions/*@Version in .md files - Call both from RunUpdateWorkflows so update command handles both lock file and user-provided steps - Add tests for isCoreAction and updateActionRefsInContent Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
|
@copilot run update command |
| if isSHA { | ||
| // Extract version from comment (e.g., " # v6.0.2" -> "v6.0.2") | ||
| if comment != "" { | ||
| commentVersion := strings.TrimSpace(strings.TrimPrefix(strings.TrimSpace(comment), "#")) |
There was a problem hiding this comment.
When a .md file has a bare SHA with no version comment (e.g., uses: actions/checkout@11bd719 like in hourly-ci-cleaner.md), currentVersion is set to "". Does getLatestActionRelease handle an empty version string gracefully? If it needs a version to determine the current major, passing "" might cause it to skip the update or error. Might be worth falling back to resolving the SHA to a tag via the API, or just defaulting to "v0" so it always picks up the latest.
- bot-detection.md: actions/github-script v7 → v8 - daily-syntax-error-quality.md: actions/setup-go v5 → v6 - hourly-ci-cleaner.md: actions/checkout SHA@11bd719 → @de0fac2 # v6.0.2 - release.md: actions/github-script v7 → v8 - release.md: actions/setup-go SHA@4dc6199 # v6.1.0 → @7a3fe6c # v6.2.0 - Recompiled all 161 workflows to update lock files Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Applied the updates in commit c2984c7:
All 161 workflow lock files recompiled successfully. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
|
@copilot merge main, recompile, run update |
pkg/cli/update_actions.go
Outdated
| continue | ||
| } | ||
|
|
||
| if err := os.WriteFile(filePath, []byte(newContent), 0644); err != nil { |
There was a problem hiding this comment.
Nit: os.WriteFile with hardcoded 0644 will change the file's permissions if they were different (e.g., 0664 or 0600).
There was a problem hiding this comment.
@copilot apply comment and leave a note as a comment in the go code
There was a problem hiding this comment.
Pull request overview
Updates the update command to also bump GitHub core actions (actions/*) to the latest major version (and corresponding SHAs) both in actions-lock.json and in action references embedded in workflow source .md files.
Changes:
- Ensure
UpdateActionsalways allows major bumps foractions/*entries in.github/aw/actions-lock.json. - Add
UpdateActionsInWorkflowFilesto rewriteuses: actions/*@...references in workflow.mdfiles and recompile updated workflows. - Wire action updates into
RunUpdateWorkflows, and apply the resulting action bumps to repository workflows + regenerated.lock.ymlfiles.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/cli/update_command.go | Runs action lock + workflow reference updates as part of update, while preserving UpdateWorkflows error reporting. |
| pkg/cli/update_actions.go | Implements core-action major-bump behavior and adds workflow .md scanning/updating logic. |
| pkg/cli/update_actions_test.go | Adds unit tests for isCoreAction and no-op behavior when no actions/* refs are present. |
| .github/workflows/release.md | Updates actions/github-script and actions/setup-go references. |
| .github/workflows/release.lock.yml | Regenerates compiled workflow lock with updated action SHAs/versions. |
| .github/workflows/hourly-ci-cleaner.md | Updates actions/checkout SHA pin and adds version comment. |
| .github/workflows/hourly-ci-cleaner.lock.yml | Regenerates compiled workflow lock with updated action SHAs/versions. |
| .github/workflows/daily-syntax-error-quality.md | Updates actions/setup-go major tag. |
| .github/workflows/daily-syntax-error-quality.lock.yml | Regenerates compiled workflow lock with updated action SHAs/versions. |
| .github/workflows/bot-detection.md | Updates actions/github-script major tag. |
| .github/workflows/bot-detection.lock.yml | Regenerates compiled workflow lock with updated action SHAs/versions. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| func TestUpdateActionRefsInContent_NonCoreActionsUnchanged(t *testing.T) { | ||
| // Non-actions/* org references should not be modified by updateActionRefsInContent | ||
| // since it only processes "uses: actions/" prefixed references. | ||
| input := `steps: | ||
| - uses: docker/login-action@v3 | ||
| - uses: github/codeql-action/upload-sarif@v3 | ||
| - run: echo hello` | ||
|
|
||
| changed, newContent, err := updateActionRefsInContent(input, false) | ||
| if err != nil { | ||
| t.Fatalf("updateActionRefsInContent() error = %v", err) | ||
| } | ||
| if changed { | ||
| t.Errorf("updateActionRefsInContent() changed = true, want false for non-actions/* refs") | ||
| } | ||
| if newContent != input { | ||
| t.Errorf("updateActionRefsInContent() modified content for non-actions/* refs\nGot: %s\nWant: %s", newContent, input) | ||
| } | ||
| } | ||
|
|
||
| func TestUpdateActionRefsInContent_NoActionRefs(t *testing.T) { | ||
| input := `description: Test workflow | ||
| steps: | ||
| - run: echo hello | ||
| - run: echo world` | ||
|
|
||
| changed, _, err := updateActionRefsInContent(input, false) | ||
| if err != nil { | ||
| t.Fatalf("updateActionRefsInContent() error = %v", err) | ||
| } | ||
| if changed { | ||
| t.Errorf("updateActionRefsInContent() changed = true, want false for content with no action refs") | ||
| } | ||
| } |
There was a problem hiding this comment.
The new workflow-reference updater (updateActionRefsInContent / UpdateActionsInWorkflowFiles) has no test that asserts actual replacements for version-tag and SHA-pinned forms. Since getLatestActionRelease hits external systems, consider injecting it behind an interface/func var so unit tests can stub it and verify that tags, SHAs, and generated version comments are updated as intended (including nested-workflow paths once recursion is added).
There was a problem hiding this comment.
Fixed in 32b407a — added getLatestActionReleaseFn as a package-level func var (defaulting to getLatestActionRelease) so tests can inject a stub. Three new tests added:
TestUpdateActionRefsInContent_VersionTagReplacement— verifies@v4→@v6updatesTestUpdateActionRefsInContent_SHAPinnedReplacement— verifies SHA+comment updatesTestUpdateActionRefsInContent_CacheReusedAcrossLines— verifies the stub is called only once for duplicate refs
pkg/cli/update_actions.go
Outdated
| // UpdateActionsInWorkflowFiles scans all workflow .md files in workflowsDir | ||
| // and updates any "uses: actions/*@version" references to the latest major version. | ||
| // Updated files are recompiled. Core actions (actions/*) always update to latest major. | ||
| func UpdateActionsInWorkflowFiles(workflowsDir, engineOverride string, verbose bool) error { | ||
| if workflowsDir == "" { | ||
| workflowsDir = getWorkflowsDir() | ||
| } | ||
|
|
||
| updateLog.Printf("Updating action references in workflow files: dir=%s", workflowsDir) | ||
|
|
||
| entries, err := os.ReadDir(workflowsDir) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to read workflows directory: %w", err) | ||
| } | ||
|
|
||
| var updatedFiles []string | ||
|
|
||
| for _, entry := range entries { | ||
| if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".md") { | ||
| continue | ||
| } | ||
|
|
There was a problem hiding this comment.
UpdateActionsInWorkflowFiles only iterates over os.ReadDir(workflowsDir) and skips subdirectories. In this repo there are workflow source files under nested paths (e.g. .github/workflows/shared/mcp-debug.md still references actions/checkout@v5), so these won’t be updated. Consider walking workflowsDir recursively (filepath.WalkDir) and applying the same update+recompile logic to all *.md files.
There was a problem hiding this comment.
Fixed in 32b407a — UpdateActionsInWorkflowFiles now uses filepath.WalkDir to recurse into all subdirectories (including .github/workflows/shared/), applying the same update+recompile logic to all *.md files.
pkg/cli/update_actions.go
Outdated
|
|
||
| // actionRefPattern matches "uses: actions/repo@SHA-or-tag" in workflow files. | ||
| // Captures: (1) indentation+uses prefix, (2) repo path, (3) SHA or version tag, | ||
| // (4) optional version comment (e.g., "v6.0.2" from "# v6.0.2"). |
There was a problem hiding this comment.
The comment above actionRefPattern says it captures 4 groups, but the regex has 5 capturing groups (including the trailing whitespace group). Please update the comment to match the actual capture groups to avoid confusion/incorrect future edits.
| // (4) optional version comment (e.g., "v6.0.2" from "# v6.0.2"). | |
| // (4) optional version comment (e.g., "v6.0.2" from "# v6.0.2"), (5) trailing whitespace. |
There was a problem hiding this comment.
Fixed in 32b407a — comment now reads: (4) optional version comment (e.g., "v6.0.2" from "# v6.0.2"), (5) trailing whitespace.
pkg/cli/update_actions.go
Outdated
| func updateActionRefsInContent(content string, verbose bool) (bool, string, error) { | ||
| changed := false | ||
| lines := strings.Split(content, "\n") | ||
|
|
||
| for i, line := range lines { | ||
| match := actionRefPattern.FindStringSubmatchIndex(line) | ||
| if match == nil { | ||
| continue | ||
| } | ||
|
|
||
| // Extract matched groups | ||
| prefix := line[match[2]:match[3]] // "uses: " | ||
| repo := line[match[4]:match[5]] // e.g. "actions/checkout" | ||
| ref := line[match[6]:match[7]] // SHA or version tag | ||
| comment := "" | ||
| if match[8] >= 0 { | ||
| comment = line[match[8]:match[9]] // e.g. " # v6.0.2" | ||
| } | ||
| trailing := "" | ||
| if match[10] >= 0 { | ||
| trailing = line[match[10]:match[11]] | ||
| } | ||
|
|
||
| // Determine the "current version" to pass to getLatestActionRelease | ||
| isSHA := IsCommitSHA(ref) | ||
| currentVersion := ref | ||
| if isSHA { | ||
| // Extract version from comment (e.g., " # v6.0.2" -> "v6.0.2") | ||
| if comment != "" { | ||
| commentVersion := strings.TrimSpace(strings.TrimPrefix(strings.TrimSpace(comment), "#")) | ||
| if commentVersion != "" { | ||
| currentVersion = commentVersion | ||
| } else { | ||
| currentVersion = "" | ||
| } | ||
| } else { | ||
| currentVersion = "" | ||
| } | ||
| } | ||
|
|
||
| // Get the latest version for this core action (always allow major) | ||
| latestVersion, latestSHA, err := getLatestActionRelease(repo, currentVersion, true, verbose) | ||
| if err != nil { | ||
| updateLog.Printf("Failed to get latest release for %s: %v", repo, err) | ||
| continue | ||
| } |
There was a problem hiding this comment.
updateActionRefsInContent calls getLatestActionRelease (GitHub API / git ls-remote) for every matching line. With many workflows and repeated actions, this can result in a large number of redundant network calls and slow/flake the update command. Cache results per repo (and possibly per currentVersion/allowMajor) within a single run, and reuse the latestVersion/latestSHA across lines/files.
There was a problem hiding this comment.
Fixed in 32b407a — added a map[string]latestReleaseResult cache (keyed by repo|currentVersion) passed through updateActionRefsInContent. Each unique repo/version is resolved only once per UpdateActionsInWorkflowFiles call, regardless of how many files or lines reference it.
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Done in commit 20419c3:
Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
|
🌑 The shadows whisper... Smoke Codex failed. The oracle requires further meditation... |
|
📰 BREAKING: Smoke Copilot is now investigating this pull request. Sources say the story is developing... |
|
🎬 THE END — Smoke Claude MISSION: ACCOMPLISHED! The hero saves the day! ✨ |
|
Commit pushed:
|
Agent Container Tool Check
Result: 12/12 tools available ✅ Overall Status: PASS
|
|
Smoke test §22490809225 results for
Overall: PASS ✅
|
There was a problem hiding this comment.
Good PR! The isCoreAction helper cleanly separates the "always update" policy for actions/*. The UpdateActionsInWorkflowFiles function adds useful automation for keeping workflow files current. Two inline notes on the implementation details — nothing blocking.
📰 BREAKING: Report filed by Smoke Copilot
|
|
||
| // isCoreAction returns true if the repo is a GitHub-maintained core action (actions/* org). | ||
| // Core actions are always updated to the latest major version without requiring --major. | ||
| func isCoreAction(repo string) bool { |
There was a problem hiding this comment.
Nice clean helper function! The HasPrefix check is simple and effective. One thought: if other "trusted" orgs need similar treatment in the future (e.g., github/), this could be extended to a slice of trusted prefixes. For now, actions/*-only is the right scope.
| // actionRefPattern matches "uses: actions/repo@SHA-or-tag" in workflow files. | ||
| // Captures: (1) indentation+uses prefix, (2) repo path, (3) SHA or version tag, | ||
| // (4) optional version comment (e.g., "v6.0.2" from "# v6.0.2"), (5) trailing whitespace. | ||
| var actionRefPattern = regexp.MustCompile(`(uses:\s+)(actions/[a-zA-Z0-9_.-]+(?:/[a-zA-Z0-9_.-]+)*)@([a-fA-F0-9]{40}|[^\s#\n]+?)(\s*#\s*\S+)?(\s*)$`) |
There was a problem hiding this comment.
The regex captures SHA hashes (40 hex chars) and version tags correctly. The [^\s#\n]+? lazy match for version tags looks good. Worth noting: the $ anchor with a multiline regex could be tricky — make sure the regexp.MustCompile is used with line-by-line processing (which it is, based on the scanning logic in UpdateActionsInWorkflowFiles).
|
📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤 |
Smoke Test Results — Run §22490809219Core tests #1–10: ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅
Overall: PARTIAL (push blocked by sandbox firewall)
|
There was a problem hiding this comment.
💥 Automated smoke test review - all systems nominal!
💥 [THE END] — Illustrated by Smoke Claude
The
updatecommand was not updatingactions/*core actions to newer major versions, nor updating action references hardcoded in user-provided workflow steps — requiring manual PRs like #18688 to bump e.g.actions/checkout@v4 → v6,actions/setup-go@v5 → v6.Changes
UpdateActions: core actions bypass--majorrestrictionisCoreAction(repo)— true for anyactions/*repoUpdateActionsnow usesallowMajor || isCoreAction(entry.Repo), soactions/*entries inactions-lock.jsonalways update to the latest major version regardless of the user's--majorflagUpdateActionsInWorkflowFilesScans all
.mdworkflow files (recursively, including subdirectories like.github/workflows/shared/) and updatesuses: actions/*@<ref>references:@v7) → updated to new tag (@v8)@abc123or@abc123 # v6.1.0) → updated to new SHA with version comment (@newsha # v6.3.0)RunUpdateWorkflows: wires both stepsUpdateActionsandUpdateActionsInWorkflowFilesafter source-workflow updatesUpdateWorkflowserrors are preserved and returned after action updates completeTesting
getLatestActionReleaseis now injectable viagetLatestActionReleaseFnfunc var, enabling unit tests without network callsApplied updates to repository workflows
Ran the update command effect on the existing workflow files in this repository:
bot-detection.md:actions/github-script@v7→@v8daily-syntax-error-quality.md:actions/setup-go@v5→@v6hourly-ci-cleaner.md:actions/checkout@11bd719...→@de0fac2... # v6.0.2release.md:actions/github-script@v7→@v8release.md:actions/setup-go@4dc6199... # v6.1.0→@7a3fe6c... # v6.2.0Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.
Changeset
actions/*updates and refreshes workflowuses:references when updating workflowsWarning
The following domain was blocked by the firewall during workflow execution:
github.comTo allow these domains, add them to the
network.allowedlist in your workflow frontmatter:See Network Configuration for more information.
✨ PR Review Safe Output Test - Run 22490809219