diff --git a/pkg/workflow/compiler_types.go b/pkg/workflow/compiler_types.go index 8e83fe72874..0231986fccc 100644 --- a/pkg/workflow/compiler_types.go +++ b/pkg/workflow/compiler_types.go @@ -641,7 +641,15 @@ func (d *WorkflowData) PinContext() *actionpins.PinContext { // resolver targets that host and fails to resolve actions/* repos which live // on github.com. Silently falling back to bundled hardcoded pins in that // case produces unverified SHA pins, so disable the fallback. - if ghHost := os.Getenv("GH_HOST"); ghHost != "" && ghHost != "github.com" { + // When GH_HOST is unset, fall back to the programmatic default host (set + // for example from auto-detected git remotes). Mirror setupGHCommand's + // (github_cli.go) precedence: GH_HOST wins when present; default host is + // only consulted when GH_HOST is absent. + if ghHost := os.Getenv("GH_HOST"); ghHost != "" { + if ghHost != "github.com" { + pinCtx.SkipHardcodedFallback = true + } + } else if defaultHost := getDefaultGHHost(); defaultHost != "" && defaultHost != "github.com" { pinCtx.SkipHardcodedFallback = true } return pinCtx diff --git a/pkg/workflow/compiler_types_test.go b/pkg/workflow/compiler_types_test.go index 8d206e74906..44fd2660cbb 100644 --- a/pkg/workflow/compiler_types_test.go +++ b/pkg/workflow/compiler_types_test.go @@ -11,6 +11,11 @@ import ( ) func TestWorkflowData_PinContext_SkipHardcodedFallback(t *testing.T) { + originalDefaultHost := getDefaultGHHost() + t.Cleanup(func() { + SetDefaultGHHost(originalDefaultHost) + }) + t.Run("sets SkipHardcodedFallback when GH_HOST is a non-github.com host", func(t *testing.T) { t.Setenv("GH_HOST", "myorg.ghe.com") @@ -31,8 +36,21 @@ func TestWorkflowData_PinContext_SkipHardcodedFallback(t *testing.T) { assert.False(t, ctx.SkipHardcodedFallback, "Expected SkipHardcodedFallback to be false when GH_HOST is github.com") }) + t.Run("GH_HOST=github.com wins over non-github.com default host", func(t *testing.T) { + t.Setenv("GH_HOST", "github.com") + SetDefaultGHHost("myorg.ghe.com") + t.Cleanup(func() { SetDefaultGHHost("") }) + + d := &WorkflowData{} + ctx := d.PinContext() + + require.NotNil(t, ctx) + assert.False(t, ctx.SkipHardcodedFallback, "Expected SkipHardcodedFallback to be false when GH_HOST=github.com even if default host is GHE") + }) + t.Run("does not set SkipHardcodedFallback when GH_HOST is not set", func(t *testing.T) { require.NoError(t, os.Unsetenv("GH_HOST")) + SetDefaultGHHost("") d := &WorkflowData{} ctx := d.PinContext() @@ -41,6 +59,28 @@ func TestWorkflowData_PinContext_SkipHardcodedFallback(t *testing.T) { assert.False(t, ctx.SkipHardcodedFallback, "Expected SkipHardcodedFallback to be false when GH_HOST is not set") }) + t.Run("sets SkipHardcodedFallback when default GH host is a non-github.com host", func(t *testing.T) { + require.NoError(t, os.Unsetenv("GH_HOST")) + SetDefaultGHHost("myorg.ghe.com") + + d := &WorkflowData{} + ctx := d.PinContext() + + require.NotNil(t, ctx) + assert.True(t, ctx.SkipHardcodedFallback, "Expected SkipHardcodedFallback to be true when default GH host is a GHE host") + }) + + t.Run("does not set SkipHardcodedFallback when default GH host is github.com", func(t *testing.T) { + require.NoError(t, os.Unsetenv("GH_HOST")) + SetDefaultGHHost("github.com") + + d := &WorkflowData{} + ctx := d.PinContext() + + require.NotNil(t, ctx) + assert.False(t, ctx.SkipHardcodedFallback, "Expected SkipHardcodedFallback to be false when default GH host is github.com") + }) + t.Run("returns nil for nil WorkflowData", func(t *testing.T) { var d *WorkflowData ctx := d.PinContext() diff --git a/pkg/workflow/github_cli_wasm.go b/pkg/workflow/github_cli_wasm.go index 1ce876e20cc..f943f72e968 100644 --- a/pkg/workflow/github_cli_wasm.go +++ b/pkg/workflow/github_cli_wasm.go @@ -46,3 +46,9 @@ func RunGHCombined(spinnerMessage string, args ...string) ([]byte, error) { func ForceGHHostEnv(cmd *exec.Cmd, host string) { // no-op in Wasm: gh CLI subprocesses are not run } + +// SetDefaultGHHost is a no-op in Wasm builds; GH CLI is unavailable. +func SetDefaultGHHost(_ string) {} + +// getDefaultGHHost always returns "" in Wasm builds. +func getDefaultGHHost() string { return "" }