feat: add GHES-compatible artifact action versions via feature flag#31664
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Pull request overview
Adds an opt-in ghes-artifact-compat feature flag so the compiler can emit GHES-compatible artifact action pins ([email protected], [email protected]) instead of newer versions that fail on GHES.
Changes:
- Added embedded pins for
actions/[email protected]andactions/[email protected]. - Introduced
GHESArtifactCompatFeatureFlagand wired it into compilation to toggle artifact pin selection. - Added tests to verify compat-mode pin selection and reset behavior.
Show a summary per file
| File | Description |
|---|---|
| pkg/actionpins/data/action_pins.json | Adds v3.x artifact action pins (SHA-locked) for GHES compatibility mode. |
| pkg/constants/feature_constants.go | Defines the new ghes-artifact-compat feature flag constant and docs. |
| pkg/workflow/action_pins.go | Implements compat-mode selection in getActionPin() (currently via a package-level toggle). |
| pkg/workflow/action_pins_test.go | Adds unit tests covering compat-mode pin selection and reset. |
| pkg/workflow/compiler.go | Enables compat mode at compile time when the feature flag is present. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 5/5 changed files
- Comments generated: 3
| // ghesArtifactCompatEnabled controls whether artifact actions use GHES-compatible | ||
| // versions (v3.x) instead of the latest (v7/v8). GHES does not support | ||
| // @actions/artifact v2.0.0+ (upload-artifact@v4+ / download-artifact@v4+). | ||
| // | ||
| // Set by the compiler at the start of CompileWorkflowData when the | ||
| // ghes-artifact-compat feature flag is enabled, and reset via defer. | ||
| var ghesArtifactCompatEnabled bool | ||
|
|
||
| // ghesArtifactCompatVersions maps artifact action repos to the exact GHES-compatible | ||
| // version to use. These are the highest v3.x releases before the breaking v4 change. | ||
| var ghesArtifactCompatVersions = map[string]string{ | ||
| "actions/upload-artifact": "v3.2.2", | ||
| "actions/download-artifact": "v3.0.2", | ||
| } | ||
|
|
||
| // SetGHESArtifactCompat enables or disables GHES-compatible artifact action versions | ||
| // for the current compilation scope. Callers must defer SetGHESArtifactCompat(false). | ||
| func SetGHESArtifactCompat(enabled bool) { | ||
| ghesArtifactCompatEnabled = enabled | ||
| if enabled { | ||
| actionPinsLog.Print("GHES artifact compatibility mode enabled: artifact actions will use v3.x pins") | ||
| } | ||
| } |
| // Enable GHES artifact compatibility when the feature flag is set. | ||
| // This makes getActionPin return v3.x artifact actions instead of v7/v8. | ||
| if isFeatureEnabled(constants.GHESArtifactCompatFeatureFlag, workflowData) { | ||
| SetGHESArtifactCompat(true) | ||
| defer SetGHESArtifactCompat(false) | ||
| } |
| // Non-artifact actions should be unaffected | ||
| checkoutPin := getActionPin("actions/checkout") | ||
| if checkoutPin == "" { | ||
| t.Fatal("getActionPin(actions/checkout) returned empty with GHES compat") | ||
| } | ||
| if strings.Contains(checkoutPin, "# v3") { | ||
| t.Errorf("GHES compat should not affect non-artifact actions, got: %s", checkoutPin) | ||
| } |
bc44126 to
d887f47
Compare
This comment has been minimized.
This comment has been minimized.
|
@copilot review all comments |
|
Feels like we should have a |
Add a ghes-artifact-compat feature flag that makes the compiler emit actions/[email protected] and actions/[email protected] instead of the latest v7/v8. GHES does not support @actions/artifact v2.0.0+ (upload-artifact@v4+ / download-artifact@v4+), so compiled workflows fail with GHESNotSupportedError on enterprise instances. The fix uses a compile-scoped flag in getActionPin() that automatically covers all 19 artifact action call sites across the compiler without modifying each caller. Users opt in via frontmatter: features: ghes-artifact-compat: true Or the GH_AW_FEATURES=ghes-artifact-compat environment variable. Closes #29551
d887f47 to
9b8d0da
Compare
|
@copilot add a |
|
@copilot update the |
|
@copilot use the tech-writer agent to add a FAQ entry on configuring GHES + pointing to docs. |
Address three PR review comments: 1. Thread safety: replace package-level `ghesArtifactCompatEnabled` bool with `ghesArtifactCompat bool` field on the Compiler struct so each compilation instance is independent. No global state mutation during compilation. 2. Defer pattern: remove `defer SetGHESArtifactCompat(false)` — no longer needed since the field is set once per CompileWorkflowData call on a per-instance basis. 3. Fragile test assertion: replace `!strings.Contains(checkoutPin, "# v3")` with a before/after equality check that verifies the checkout pin is unchanged. All 19 artifact action call sites updated to use `c.getActionPin()` (Compiler methods) or accept a `pinAction func(string) string` parameter (standalone functions). Test helper call sites also updated. Named `ghesArtifactPin` type added for the compat pins map. Co-authored-by: pelikhan <[email protected]>
All three review comments addressed in commit
|
|
@copilot review all invocation of getActionPin to ensure consistent use since it is now behaving differently between the compiler instance and the global function. |
| // | ||
| // features: | ||
| // ghes-artifact-compat: true | ||
| GHESArtifactCompatFeatureFlag FeatureFlag = "ghes-artifact-compat" |
There was a problem hiding this comment.
@copilot remove features flag in favor of compiler flag and aw.json config field
| // 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. | ||
| func (c *Compiler) getActionPin(repo string) string { | ||
| if c.ghesArtifactCompat { |
| c.ghesArtifactCompat = isFeatureEnabled(constants.GHESArtifactCompatFeatureFlag, workflowData) | ||
| if c.ghesArtifactCompat { | ||
| actionPinsLog.Print("GHES artifact compatibility mode enabled: artifact actions will use v3.x pins") | ||
| } |
Co-authored-by: pelikhan <[email protected]>
Co-authored-by: pelikhan <[email protected]>
Co-authored-by: pelikhan <[email protected]>
Done in commit
Done in commit
Done in commit
|
…rtifact-compat feature flag Add reference documentation for three user-facing surfaces merged in the last 24h that had no prior documentation: - firewall.effective-token-steering (#31796): budget-warning system message injection via AWF v0.25.44+ - concurrency.queue and features.group-concurrency-queue (#31764): queue:max behavior and opt-out for compiler-generated groups - features.ghes-artifact-compat (#31664): per-workflow GHES artifact compatibility opt-in via frontmatter or GH_AW_FEATURES env var Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
* docs: document token-steering firewall, concurrency.queue, and ghes-artifact-compat feature flag Add reference documentation for three user-facing surfaces merged in the last 24h that had no prior documentation: - firewall.effective-token-steering (#31796): budget-warning system message injection via AWF v0.25.44+ - concurrency.queue and features.group-concurrency-queue (#31764): queue:max behavior and opt-out for compiler-generated groups - features.ghes-artifact-compat (#31664): per-workflow GHES artifact compatibility opt-in via frontmatter or GH_AW_FEATURES env var Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * docs: add tip pointing to --ghes and aw.json options in per-workflow section Co-authored-by: pelikhan <[email protected]> * docs: remove features.ghes-artifact-compat per-workflow section (feature does not exist) Co-authored-by: pelikhan <[email protected]> --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]> Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: pelikhan <[email protected]> Co-authored-by: Peli de Halleux <[email protected]>
Summary
Add a
ghes-artifact-compatfeature flag that makes the compiler emitactions/[email protected]andactions/[email protected]instead of the latest v7/v8.Problem
GHES does not support
@actions/artifactv2.0.0+ —upload-artifact@v4+/download-artifact@v4+fail withGHESNotSupportedErroron enterprise instances (confirmed still the case on GHES 3.20, the latest release). Users running gh-aw compiled workflows on GHES cannot upload or download artifacts.Solution
A compile-scoped flag in
getActionPin()that automatically covers all 19 artifact action call sites across the compiler without modifying each caller. Users opt in via frontmatter:Or the
GH_AW_FEATURES=ghes-artifact-compatenvironment variable.When the flag is active, artifact actions are pinned to the highest v3.x releases that avoid the
@actions/artifactv2.0.0+ GHES incompatibility. If a required v3 pin is missing from the embedded pin database, compilation fails fast rather than silently emitting a broken v4+ reference.Files changed
pkg/actionpins/data/action_pins.jsonpkg/constants/feature_constants.goGHESArtifactCompatFeatureFlagconstantpkg/workflow/action_pins.gogetActionPin()with fail-fast on missing pinspkg/workflow/action_pins_test.gopkg/workflow/compiler.goCompileWorkflowData()with defer cleanupDesign decisions
WorkflowDataaccess, 7 don't. Threading the flag to all 19 callers would be a much larger change with no benefit — compilation is single-threaded per compiler instance.action_pins.json,getActionPin()returns empty instead of silently falling back to latest (which would break on GHES).[email protected]and[email protected]are the highest non-node20 v3 tags (both released Mar 17, 2026).[email protected]→c6a366c94c3e0affe28c06c8df20a878f24da3cf,[email protected]→a9bc5e6ef2cb54c177f32aa5726adaa15e7e2d59Testing
TestGetActionPinGHESArtifactCompat— verifies compat mode returns v3 SHAs, non-artifact actions unaffectedTestGHESArtifactCompatReset— verifies defer cleanup restores defaultsTestGHESArtifactCompatPinsExist— invariant test: every entry in compat map exists inaction_pins.jsonpkg/workflowtest suite passes (254s)CI note
CGO
build-wasmandtestfailures are pre-existing onmain(golden test snapshots stale from unrelated changes) — not caused by this PR.Closes #29551