diff --git a/.github/workflows/issue-classifier.lock.yml b/.github/workflows/issue-classifier.lock.yml index 4f4a69a3e57..3be5ab9acd8 100644 --- a/.github/workflows/issue-classifier.lock.yml +++ b/.github/workflows/issue-classifier.lock.yml @@ -2241,7 +2241,7 @@ jobs: path: /tmp/gh-aw/aw_info.json if-no-files-found: warn - name: Run AI Inference - uses: actions/ai-inference@334892bb203895caaed82ec52d23c1ed9385151e # v1 + uses: actions/ai-inference@334892bb203895caaed82ec52d23c1ed9385151e # v2.0.4 env: GH_AW_MCP_CONFIG: /tmp/gh-aw/mcp-config/mcp-servers.json GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt diff --git a/.github/workflows/release.lock.yml b/.github/workflows/release.lock.yml index 8433f151f17..ce61da11ec3 100644 --- a/.github/workflows/release.lock.yml +++ b/.github/workflows/release.lock.yml @@ -6056,13 +6056,13 @@ jobs: - name: Download Go modules run: go mod download - name: Generate SBOM (SPDX format) - uses: anchore/sbom-action@43a17d6e7add2b5535efe4dcae9952337c479a93 # v0.20.10 + uses: anchore/sbom-action@43a17d6e7add2b5535efe4dcae9952337c479a93 # v0.20.11 with: artifact-name: sbom.spdx.json format: spdx-json output-file: sbom.spdx.json - name: Generate SBOM (CycloneDX format) - uses: anchore/sbom-action@43a17d6e7add2b5535efe4dcae9952337c479a93 # v0.20.10 + uses: anchore/sbom-action@43a17d6e7add2b5535efe4dcae9952337c479a93 # v0.20.11 with: artifact-name: sbom.cdx.json format: cyclonedx-json @@ -6261,7 +6261,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Release with gh-extension-precompile - uses: cli/gh-extension-precompile@9e2237c30f869ad3bcaed6a4be2cd43564dd421b # v2 + uses: cli/gh-extension-precompile@9e2237c30f869ad3bcaed6a4be2cd43564dd421b # v2.1.0 with: build_script_override: scripts/build-release.sh go_version_file: go.mod diff --git a/.github/workflows/stale-repo-identifier.lock.yml b/.github/workflows/stale-repo-identifier.lock.yml index a8cd91dcd02..21caadf4297 100644 --- a/.github/workflows/stale-repo-identifier.lock.yml +++ b/.github/workflows/stale-repo-identifier.lock.yml @@ -176,7 +176,7 @@ jobs: ORGANIZATION: ${{ env.ORGANIZATION }} id: stale-repos name: Run stale_repos tool - uses: github/stale-repos@a21e55567b83cf3c3f3f9085d3038dc6cee02598 # v3 + uses: github/stale-repos@a21e55567b83cf3c3f3f9085d3038dc6cee02598 # v3.0.2 - env: INACTIVE_REPOS: ${{ steps.stale-repos.outputs.inactiveRepos }} name: Save stale repos output diff --git a/.github/workflows/super-linter.lock.yml b/.github/workflows/super-linter.lock.yml index b15660af2fb..4c2fde522cd 100644 --- a/.github/workflows/super-linter.lock.yml +++ b/.github/workflows/super-linter.lock.yml @@ -6189,7 +6189,7 @@ jobs: persist-credentials: false - name: Super-linter id: super-linter - uses: super-linter/super-linter@47984f49b4e87383eed97890fe2dca6063bbd9c3 # v8.2.1 + uses: super-linter/super-linter@47984f49b4e87383eed97890fe2dca6063bbd9c3 # v8.3.1 env: CREATE_LOG_FILE: "true" DEFAULT_BRANCH: main diff --git a/pkg/workflow/action_mode.go b/pkg/workflow/action_mode.go index 7ffca0f75fa..39657efe1e7 100644 --- a/pkg/workflow/action_mode.go +++ b/pkg/workflow/action_mode.go @@ -45,14 +45,13 @@ func (m ActionMode) UsesExternalActions() bool { return true } -// DetectActionMode determines the appropriate action mode based on environment and version. -// Returns ActionModeRelease if the binary version is a release tag, -// otherwise returns ActionModeDev as the default. -// Can be overridden with GH_AW_ACTION_MODE environment variable. -// If version parameter is provided, it will be used to determine release mode. -// Never uses dirty SHA - only clean version tags or dev mode with local paths. +// DetectActionMode determines the appropriate action mode based on the release flag. +// Returns ActionModeRelease if this binary was built as a release (controlled by the +// isReleaseBuild flag set via -X linker flag at build time), otherwise returns ActionModeDev. +// Can be overridden with GH_AW_ACTION_MODE environment variable or GitHub Actions context. +// The version parameter is kept for backward compatibility but is no longer used for detection. func DetectActionMode(version string) ActionMode { - actionModeLog.Printf("Detecting action mode: version=%s", version) + actionModeLog.Printf("Detecting action mode: version=%s, isRelease=%v", version, IsRelease()) // Check for explicit override via environment variable if envMode := os.Getenv("GH_AW_ACTION_MODE"); envMode != "" { @@ -64,11 +63,10 @@ func DetectActionMode(version string) ActionMode { actionModeLog.Printf("Invalid action mode in environment: %s, falling back to auto-detection", envMode) } - // Check if version indicates a release build - // Release tags are clean version strings (not "dev", not empty, no "-dirty" suffix, and start with "v") - if version != "" && version != "dev" && !strings.Contains(version, "-dirty") && strings.HasPrefix(version, "v") { - // Version is a clean release tag, use release mode - actionModeLog.Printf("Detected release mode from binary version: %s", version) + // Check if this binary was built as a release using the release flag + // This flag is set at build time via -X linker flag and does not rely on version string heuristics + if IsRelease() { + actionModeLog.Printf("Detected release mode from build flag (isReleaseBuild=true)") return ActionModeRelease } @@ -92,7 +90,7 @@ func DetectActionMode(version string) ActionMode { // 1. Running on a PR (refs/pull/*) // 2. Running locally (no GITHUB_REF) // 3. Running on any other branch (including main) - // 4. Version is "dev" or empty - actionModeLog.Printf("Detected dev mode (default): version=%s, ref=%s", version, githubRef) + // 4. Non-release builds (isReleaseBuild=false) + actionModeLog.Printf("Detected dev mode (default): isRelease=%v, ref=%s", IsRelease(), githubRef) return ActionModeDev } diff --git a/pkg/workflow/compiler_action_mode_test.go b/pkg/workflow/compiler_action_mode_test.go index fb80c7281f0..da7f671cec6 100644 --- a/pkg/workflow/compiler_action_mode_test.go +++ b/pkg/workflow/compiler_action_mode_test.go @@ -156,6 +156,120 @@ func TestActionModeReleaseValidation(t *testing.T) { } } +// TestActionModeDetectionWithReleaseFlag tests that DetectActionMode uses the release flag +func TestActionModeDetectionWithReleaseFlag(t *testing.T) { + tests := []struct { + name string + isRelease bool + githubRef string + githubEvent string + envOverride string + expectedMode ActionMode + description string + }{ + { + name: "release flag true", + isRelease: true, + githubRef: "", + githubEvent: "", + expectedMode: ActionModeRelease, + description: "Release flag set to true should use release mode", + }, + { + name: "release flag false", + isRelease: false, + githubRef: "", + githubEvent: "", + expectedMode: ActionModeDev, + description: "Release flag set to false should use dev mode", + }, + { + name: "release flag true with main branch", + isRelease: true, + githubRef: "refs/heads/main", + githubEvent: "push", + expectedMode: ActionModeRelease, + description: "Release flag should take precedence over branch", + }, + { + name: "release flag false with release tag", + isRelease: false, + githubRef: "refs/tags/v1.0.0", + githubEvent: "push", + expectedMode: ActionModeRelease, + description: "GitHub release tag should still work when release flag is false", + }, + { + name: "env override with release flag", + isRelease: true, + githubRef: "", + githubEvent: "", + envOverride: "dev", + expectedMode: ActionModeDev, + description: "Environment variable should override release flag", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Save original environment and release flag + origRef := os.Getenv("GITHUB_REF") + origEvent := os.Getenv("GITHUB_EVENT_NAME") + origMode := os.Getenv("GH_AW_ACTION_MODE") + origRelease := IsRelease() + + defer func() { + // Restore environment variables + if origRef != "" { + os.Setenv("GITHUB_REF", origRef) + } else { + os.Unsetenv("GITHUB_REF") + } + if origEvent != "" { + os.Setenv("GITHUB_EVENT_NAME", origEvent) + } else { + os.Unsetenv("GITHUB_EVENT_NAME") + } + if origMode != "" { + os.Setenv("GH_AW_ACTION_MODE", origMode) + } else { + os.Unsetenv("GH_AW_ACTION_MODE") + } + // Restore release flag + SetIsRelease(origRelease) + }() + + // Set test environment + if tt.githubRef != "" { + os.Setenv("GITHUB_REF", tt.githubRef) + } else { + os.Unsetenv("GITHUB_REF") + } + + if tt.githubEvent != "" { + os.Setenv("GITHUB_EVENT_NAME", tt.githubEvent) + } else { + os.Unsetenv("GITHUB_EVENT_NAME") + } + + if tt.envOverride != "" { + os.Setenv("GH_AW_ACTION_MODE", tt.envOverride) + } else { + os.Unsetenv("GH_AW_ACTION_MODE") + } + + // Set release flag + SetIsRelease(tt.isRelease) + + // Test detection (version parameter is ignored now) + mode := DetectActionMode("ignored-version") + if mode != tt.expectedMode { + t.Errorf("%s: expected mode %s, got %s", tt.description, tt.expectedMode, mode) + } + }) + } +} + // TestReleaseModeCompilation tests workflow compilation in release mode // Note: This test uses create_issue which already has ScriptName set. // Other safe outputs (add_labels, etc.) don't have ScriptName yet and will use inline mode.