Skip to content

Stop compiler from emitting deprecated artifact v3 pins in GHES mode#43298

Merged
pelikhan merged 6 commits into
mainfrom
copilot/fix-deprecated-actions
Jul 4, 2026
Merged

Stop compiler from emitting deprecated artifact v3 pins in GHES mode#43298
pelikhan merged 6 commits into
mainfrom
copilot/fix-deprecated-actions

Conversation

Copilot AI commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

gh aw compile could emit actions/upload-artifact@v3 / actions/download-artifact@v3 under GHES compatibility settings, which now hard-fail at runtime due to retired v3 artifact backend APIs. This change removes that deprecated path so generated lock workflows keep using current non-v3 pinned artifact actions.

  • Compiler behavior

    • Removed GHES-specific hardcoded v3 artifact pin override in pkg/workflow/action_pins.go.
    • Compiler.getActionPin(...) now consistently resolves artifact actions from the standard pinned dataset (same behavior as non-GHES path).
  • Regression coverage

    • Updated pkg/workflow/action_pins_test.go to assert:
      • GHES compatibility mode does not produce # v3 artifact pins.
      • GHES and default modes return the same artifact pin references.
      • No compatibility-state leakage across compiler instances.
  • CLI/config contract alignment

    • Updated user-facing/help/schema text to match implementation (GHES mode enabled, but artifact pins remain latest non-v3):
      • cmd/gh-aw/main.go
      • pkg/cli/compile_compiler_setup.go
      • pkg/cli/compile_config.go
      • pkg/workflow/compiler.go
      • pkg/workflow/compiler_types.go
      • pkg/workflow/repo_config.go
      • pkg/parser/schemas/repo_config_schema.json
// before (GHES compat path)
if c.ghesArtifactCompat {
    if pin, ok := ghesArtifactCompatPins[repo]; ok {
        return actionpins.FormatPinnedActionReference(repo, pin.sha, pin.version) // v3.x
    }
}

// after
func (c *Compiler) getActionPin(repo string) string {
    // shared cache/embedded latest pin resolution; no GHES-only v3 override
}

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix compiler to emit updated actions for artifact upload and download Stop compiler from emitting deprecated artifact v3 pins in GHES mode Jul 4, 2026
Copilot AI requested a review from pelikhan July 4, 2026 04:35
@pelikhan pelikhan marked this pull request as ready for review July 4, 2026 04:41
Copilot AI review requested due to automatic review settings July 4, 2026 04:41
@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

⚠️ PR Code Quality Reviewer failed during code quality review.

@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check.

No ADR enforcement needed: PR #43298 does not have the 'implementation' label and has only 37 new lines of code in business logic directories (threshold is 100).

@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates gh aw compile to stop generating deprecated actions/upload-artifact@v3 / actions/download-artifact@v3 pins when GHES compatibility mode is enabled, ensuring compiled lock workflows keep using the standard (non-v3) pinned artifact actions.

Changes:

  • Removed the GHES-only hardcoded v3 artifact pin override so action pin resolution is consistent across GHES and non-GHES modes.
  • Updated tests to assert GHES mode never emits v3 artifact pins and that GHES/default mode pins match.
  • Updated CLI/help/schema text to reflect that GHES mode remains available but artifact pins stay on the latest non-v3 versions.
Show a summary per file
File Description
pkg/workflow/repo_config.go Updates aw.json GHES documentation to reflect non-v3 artifact pins.
pkg/workflow/compiler.go Adjusts GHES-mode logging to reflect non-v3 artifact pin behavior.
pkg/workflow/compiler_types.go Updates GHES compat field/method documentation for the new behavior.
pkg/workflow/action_pins.go Removes the GHES-specific v3 artifact pin override from action pin resolution.
pkg/workflow/action_pins_test.go Updates tests to ensure GHES mode does not emit v3 pins and matches default pins.
pkg/parser/schemas/repo_config_schema.json Updates schema description for ghes to reflect non-v3 artifact pins.
pkg/cli/compile_config.go Updates CompileConfig GHESCompat flag comment to reflect non-v3 artifact pins.
pkg/cli/compile_compiler_setup.go Updates GHES flag wiring/logging text to reflect non-v3 artifact pins.
cmd/gh-aw/main.go Updates --ghes flag help text to reflect non-v3 artifact pins.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 9/9 changed files
  • Comments generated: 4
  • Review effort level: Low

Comment thread pkg/workflow/compiler.go
Comment on lines 444 to 446
if c.ghesArtifactCompat {
actionPinsLog.Print("GHES artifact compatibility mode enabled: artifact actions will use v3.x pins")
actionPinsLog.Print("GHES artifact compatibility mode enabled: using latest artifact action pins (v3 pins are deprecated)")
}
Comment thread pkg/workflow/compiler_types.go Outdated
Comment on lines 244 to 247
// SetGHESCompat enables GHES artifact compatibility mode via the --ghes CLI flag.
// When true, the compiler emits GHES-compatible v3.x artifact action pins
// (upload-artifact@v3, download-artifact@v3) instead of the latest v7/v8.
// v3 artifact actions are deprecated, so artifact actions continue using the
// latest non-v3 pins.
// This flag takes precedence over the aw.json ghes field.
Comment thread cmd/gh-aw/main.go
compileCmd.Flags().Bool("no-models-dev-lookup", false, "Disable compile-time models.dev pricing lookup for models missing from the embedded catalog")
compileCmd.Flags().String("prior-manifest-file", "", "Path to a JSON file containing pre-cached gh-aw-manifests (map[lockFile]*GHAWManifest); used by the MCP server to supply a tamper-proof manifest baseline captured at startup")
compileCmd.Flags().Bool("ghes", false, "Enable GitHub Enterprise Server (GHES) compatibility mode: emit upload-artifact@v3 and download-artifact@v3 instead of the latest v7/v8 which are not supported on GHES. Overrides the aw.json ghes field")
compileCmd.Flags().Bool("ghes", false, "Enable GitHub Enterprise Server (GHES) compatibility mode. Artifact actions continue using latest non-v3 pins (v3 is deprecated). Overrides the aw.json ghes field")
Comment thread pkg/workflow/action_pins.go Outdated
Comment on lines 71 to 72
// This is the preferred call site for code running inside a Compiler method, since it
// automatically honours the per-compilation GHES compat flag without any global state.
@github-actions github-actions Bot mentioned this pull request Jul 4, 2026
@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Test Quality Score: 90/100 — Excellent

Analyzed 3 test(s): 3 design, 0 implementation, 0 violation(s).

📊 Metrics (3 tests)
Metric Value
Analyzed 3 (Go: 3, JS: 0)
✅ Design 3 (100%)
⚠️ Implementation 0 (0%)
Edge/error coverage 3 (100%)
Duplicate clusters 0
Inflation Yes (25 test adds : 1 prod add — technical flag only; see note)
🚨 Violations 0
Test File Classification Issues
TestGetActionPinGHESArtifactCompat pkg/workflow/action_pins_test.go design_test · behavioral_contract · high_value None
TestGHESArtifactCompatReset pkg/workflow/action_pins_test.go design_test · behavioral_contract · high_value None
TestGHESArtifactCompatDoesNotUseV3 pkg/workflow/action_pins_test.go design_test · behavioral_contract · high_value None

Verdict

Passed. 0% implementation tests (threshold: 30%). Build tag present (//go:build !integration). No mock violations.


What changed: All three tests were updated to flip their behavioral contracts from asserting that GHES compat mode returns v3 pins to asserting it does not return v3 pins — directly mirroring the production change that removed the deprecated ghesArtifactCompatPins map. The rename of TestGHESArtifactCompatPinsExistTestGHESArtifactCompatDoesNotUseV3 with table-driven subtests (t.Run) is an improvement in both coverage and clarity.

Inflation note: The 25:1 addition ratio (test: 25 additions, prod: 1 addition) technically triggers the inflation flag. However, the production change is primarily a deletion (−25 lines removing the hardcoded v3 map), and the test file also nets a reduction (−30 deletions, +25 additions). This is expected churn when removing deprecated functionality, not test padding.

References:

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

🧪 Test quality analysis by Test Quality Sentinel · 36 AIC · ⌖ 11.8 AIC · ⊞ 6.8K ·
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Test Quality Sentinel: 90/100. 0% implementation tests (threshold: 30%). All 3 tests verify behavioral contracts (no v3 pins emitted in GHES compat mode). No violations.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: Stop compiler from emitting deprecated artifact v3 pins in GHES mode

The core change is correct and well-targeted — removing the hardcoded ghesArtifactCompatPins map and the GHES v3 override in getActionPin() prevents compilation from emitting the deprecated actions/upload-artifact@v3 / actions/download-artifact@v3 pins that now hard-fail at runtime.

Two non-blocking concerns worth addressing:

1. ghesArtifactCompat is now a write-only / no-op field (compiler.go:444)

After removing the v3 override, the ghesArtifactCompat field is set and logged but never drives any behavioral branch. --ghes and aw.json ghes: true are silently no-ops beyond the log line. If the flag is reserved for future GHES-specific behavior, a comment stating that intent would be useful. If not, removing the field and its CLI/schema surface reduces confusion.

2. Tests validate a tautology (action_pins_test.go:1607)

The updated tests set compatCompiler.ghesArtifactCompat = true (a private field that now has no effect) and then assert the result matches the default — which trivially passes because the flag does nothing. These tests no longer detect a regression where GHES compat accidentally re-introduces v3 pins. Consider testing through the public API (SetGHESCompat) after a real compile, or at least leaving a comment explaining that the flag is currently inert.

The doc, schema, and log string updates are accurate and clearly communicated. No security or data-correctness issues found.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · 78.2 AIC · ⌖ 6.23 AIC · ⊞ 4.9K

Comment thread pkg/workflow/compiler.go
@@ -442,7 +442,7 @@ func (c *Compiler) CompileWorkflowData(workflowData *WorkflowData, markdownPath
}
}
if c.ghesArtifactCompat {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After removing the v3 pin override from getActionPin(), ghesArtifactCompat is now write-only: it is set (lines 437–441) and logged here, but no code path makes a behavioral decision based on it. This means --ghes / aw.json ghes: true silently have no effect on compilation output beyond this log message.

If GHES mode is intended to gate future non-artifact behavior, this is fine as scaffolding. But if the flag is now truly inert, consider removing the field, CLI flag, and schema entry to avoid misleading users — or add an explicit comment documenting that GHES compat is retained for future use.

@copilot please address this.

@@ -1607,19 +1607,19 @@ func TestGetActionPinGHESArtifactCompat(t *testing.T) {
compatCompiler.ghesArtifactCompat = true

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test sets compatCompiler.ghesArtifactCompat = true directly (a private field). Since the field now has no behavioral effect on getActionPin, this test validates a tautology: it sets a no-op flag, then asserts the result is the same as without the flag. The test will always pass regardless of whether GHES compat is wired up correctly.

Consider driving GHES compat through the public API (compatCompiler.SetGHESCompat(true) followed by a compile step) or testing at integration level via configureCompilerFlags, to ensure the public contract is actually exercised.

@copilot please address this.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skills-Based Review 🧠

Applied /diagnosing-bugs, /tdd, and /codebase-design — commenting only; no blocking correctness issues, but there are follow-on cleanup opportunities worth addressing.

📋 Key Themes & Highlights

Key Themes

  • Stale doc comment in action_pins.go still claims the method honours the GHES compat flag, which is no longer true.
  • Semantically dead fieldghesArtifactCompat (and the supporting two-field pipeline in compiler.go) now only gate a log statement, making the module harder to navigate.
  • Test precision gaps — one isolation assertion compares the wrong compiler instances, and TestGHESArtifactCompatReset has a name that no longer describes what it verifies.

Positive Highlights

  • ✅ Root cause correctly removed: deleting ghesArtifactCompatPins eliminates the broken runtime path at the source.
  • ✅ Regression tests updated to assert the new invariant (GHES mode == default mode for artifact pins).
  • ✅ Clean net-deletion PR (-30 lines): simplifies the codebase rather than papering over the problem.
  • ✅ Comprehensive doc/comment/schema sweep — all user-facing surfaces updated consistently.
  • ✅ Structured subtests (t.Run) in TestGHESArtifactCompatDoesNotUseV3 improve failure localisation.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · 84.2 AIC · ⌖ 5.78 AIC · ⊞ 6.6K
Comment /matt to run again

Comments that could not be inline-anchored

pkg/workflow/action_pins.go:72

[/diagnosing-bugs] Stale doc comment — the GHES compat flag no longer affects this function's output, but line 72 still reads: "automatically honours the per-compilation GHES compat flag without any global state." This will mislead future contributors into thinking getActionPin behaves differently based on the flag.

<details>
<summary>💡 Suggested update</summary>

Remove the now-false claim about honouring the GHES compat flag:

// getActionPin returns the pinned reference for t…

</details>

<details><summary>pkg/workflow/compiler_types.go:108</summary>

**[/codebase-design]** The `ghesArtifactCompat` field is now semantically dead for its original purposeit no longer changes which pin is returned, only which log message is emitted. Consider whether the field (and the entire GHES compat branching path in `compiler.go`) is still needed, or whether it can be collapsed into just logging at the call site where `repoConfig.GHES` is read.

&lt;details&gt;
&lt;summary&gt;💡 Why this matters&lt;/summary&gt;

A boolean field that used to gate a meaningful code path bu</details>

<details><summary>pkg/workflow/action_pins_test.go:1632</summary>

**[/tdd]** Test name no longer matches intent. `TestGHESArtifactCompatReset` now verifies that compat and default compilers return the **same** pinwhich is correctbut &quot;reset&quot; implies it was testing state isolation between sequential calls, not pin equality. The comment inside also reads _&quot;toggling compat mode does not leak state&quot;_, which is subtly incorrect: two separate `NewCompiler()` instances never share state regardless of this change.

&lt;details&gt;
&lt;summary&gt;💡 Suggested rename&lt;/summary</details>

<details><summary>pkg/workflow/compiler_types.go:248</summary>

**[/codebase-design]** `SetGHESCompat` now sets `ghesCompatFromCLI` but the method is called _SetGHESCompat_, which is still the public name. However, the field it sets is not the one whose value ultimately gates anything meaningful`ghesArtifactCompat` is set later in `CompileWorkflowData`. If GHES compat is going to be retained as a concept, consider renaming `ghesCompatFromCLI``ghesCompatOverride` or simply remove the field entirely and pass the flag directly through the compile path.

…

</details>

<details><summary>pkg/workflow/action_pins_test.go:1599</summary>

**[/tdd]** The assertion that `actions/checkout` is unchanged uses a different compiler instance (`compatCompiler`) than the one that captured `checkoutPinBefore` (`defaultCompiler`). The test comment says _&quot;assert it is unchanged after&quot;_, but since the two compilers are separate instances, this only verifies both compilers return the same checkout pinnot that `defaultCompiler`&#39;s state was unchanged after `compatCompiler` ran. To actually test isolation, re-call `defaultCompiler.getActionPin…

</details>

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: Non-blocking observation on test coverage

The core change — removing the GHES v3 artifact pin override — is correct and the doc/comment updates are thorough. One test is now misleading after the behavioral change.

Details

TestGHESArtifactCompatReset (action_pins_test.go:1632) became a tautology when the v3 override was removed. Both compiler instances now execute identical code paths and always return the same pin, so the defaultPin != compatPin assertion can never fire. The test name implies it guards against state leakage, but it no longer does — a future regression reintroducing shared global state would pass this test silently. See inline comment for options.

Everything else looks clean: the logic simplification is correct, the other test rewrites properly invert their assertions, and the docs/comments are consistently updated across all touched files.

Warning

Firewall blocked 2 domains

The following domains were blocked by the firewall during workflow execution:

  • patchdiff.githubusercontent.com
  • proxy.golang.org

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "patchdiff.githubusercontent.com"
    - "proxy.golang.org"

See Network Configuration for more information.

🔎 Code quality review by PR Code Quality Reviewer · 197.2 AIC · ⌖ 6.55 AIC · ⊞ 5.4K
Comment /review to run again

Comment thread pkg/workflow/action_pins_test.go Outdated
@@ -1651,24 +1650,20 @@ func TestGHESArtifactCompatReset(t *testing.T) {
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TestGHESArtifactCompatReset is now a tautology that cannot detect state leakage. Both compiler instances run through identical code paths after the v3 override was removed, so defaultPin == compatPin unconditionally — the assertion if defaultPin != compatPin can never fire regardless of whether state actually leaks.

💡 Suggested fix

The test needs to verify isolation through a mechanism that would differ if state were shared. One option: inject something into compatCompiler's cache that would influence output, then confirm defaultCompiler is unaffected.

Alternatively rename to TestGHESArtifactCompatFlagIsPerInstance and add a comment explaining it asserts same-output (not non-interference) — otherwise future maintainers will trust it as a leakage guard when it provides none.

As written, this test gives false confidence: any future regression that reintroduces shared global state would not be caught here.

@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

🛠️ Agentic Maintenance updated this pull request branch.

View workflow run

@pelikhan

pelikhan commented Jul 4, 2026

Copy link
Copy Markdown
Collaborator

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

🤖 PR Triage

Field Value
Category bug
Risk 🟢 Low
Score 70 / 100
Action fast_track
Batch pr-batch:compiler-fixes

Score breakdown: Impact 36 (prevents GHES runtime failures from retired v3 artifact APIs) + Urgency 20 + Quality 14 (clean removal, approved)

Removes deprecated GHES artifact v3 pin override. -68/+38 lines, approved by github-actions bot. Ready for human sign-off.

Generated by 🔧 PR Triage Agent · 82.8 AIC · ⌖ 8.09 AIC · ⊞ 5.5K ·

Copilot AI commented Jul 4, 2026

Copy link
Copy Markdown
Contributor Author

@copilot merge main and recompile
Fix https://github.com/github/gh-aw/actions/runs/28697715838/job/85110603039

Done in commit 7c62b59. I merged latest main, recompiled, and validated with go test ./pkg/workflow -run TestExecGHUsesConfiguredProcessEnvLookup -count=1 and make test-impacted-go BASE_REF=origin/main.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please run the pr-finisher skill, refresh this PR for final review, and address the remaining non-blocking feedback if it still applies: update stale docs/comments around the removed GHES compat behavior in action_pins.go, and revisit TestGHESArtifactCompatReset since it may now be tautological after removing the v3 override. Once done, rerun the relevant checks.

Generated by 👨‍🍳 PR Sous Chef · 12.8 AIC · ⌖ 5.94 AIC · ⊞ 3.4K ·
Comment /souschef to run again

Copilot AI and others added 2 commits July 4, 2026 07:54
Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

Copilot AI commented Jul 4, 2026

Copy link
Copy Markdown
Contributor Author

@copilot please run the pr-finisher skill, refresh this PR for final review, and address the remaining non-blocking feedback if it still applies: update stale docs/comments around the removed GHES c...

Addressed in ff58f4d and 930b2d4. I updated stale GHES wording in pkg/workflow/action_pins.go, pkg/workflow/compiler.go, pkg/workflow/compiler_types.go, and the GHES reference docs, and removed TestGHESArtifactCompatReset as redundant after the v3 override removal. I reran relevant checks: make fmt, targeted workflow tests (TestGetActionPinGHESArtifactCompat, TestGHESArtifactCompatDoesNotUseV3), and parallel_validation (Code Review + CodeQL).

Copilot AI requested a review from gh-aw-bot July 4, 2026 07:59
@pelikhan pelikhan merged commit 9c66ffe into main Jul 4, 2026
29 checks passed
@pelikhan pelikhan deleted the copilot/fix-deprecated-actions branch July 4, 2026 08:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Compiler emits deprecated actions/upload-artifact@v3 / download-artifact@v3, causing hard HTTP 400 on every run

4 participants