diff --git a/.github/workflows/issue-monster.lock.yml b/.github/workflows/issue-monster.lock.yml index efd91245e3..b35095a56c 100644 --- a/.github/workflows/issue-monster.lock.yml +++ b/.github/workflows/issue-monster.lock.yml @@ -1385,6 +1385,7 @@ jobs: await main(); - name: Generate GitHub App token for skip-if checks id: pre-activation-app-token + continue-on-error: true uses: actions/create-github-app-token@a7f885bf4560200d03183ed941cb6fb072e4b343 # v3.0.0-beta.4 with: app-id: ${{ vars.APP_ID }} @@ -1400,7 +1401,7 @@ jobs: GH_AW_WORKFLOW_NAME: "Issue Monster" GH_AW_SKIP_MAX_MATCHES: "5" with: - github-token: ${{ steps.pre-activation-app-token.outputs.token }} + github-token: ${{ steps.pre-activation-app-token.outputs.token || github.token }} script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); setupGlobals(core, github, context, exec, io); @@ -1414,7 +1415,7 @@ jobs: GH_AW_WORKFLOW_NAME: "Issue Monster" GH_AW_SKIP_MIN_MATCHES: "1" with: - github-token: ${{ steps.pre-activation-app-token.outputs.token }} + github-token: ${{ steps.pre-activation-app-token.outputs.token || github.token }} script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); setupGlobals(core, github, context, exec, io); diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index a339fc73b7..bceba229df 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -2629,6 +2629,8 @@ jobs: /// // Auto-generated safe-output script handler: post-slack-message + const { sanitizeContent } = require("./sanitize_content.cjs"); + /** @type {import('./types/safe-output-script').SafeOutputScriptMain} */ async function main(config = {}) { const { channel, message } = config; diff --git a/pkg/workflow/compiler_pre_activation_job.go b/pkg/workflow/compiler_pre_activation_job.go index a049bd2592..df7c206a99 100644 --- a/pkg/workflow/compiler_pre_activation_job.go +++ b/pkg/workflow/compiler_pre_activation_job.go @@ -482,12 +482,15 @@ func (c *Compiler) extractPreActivationCustomFields(jobs map[string]any) ([]stri // buildPreActivationAppTokenMintStep generates a single GitHub App token mint step for use // by all skip-if checks in the pre-activation job. The step ID is "pre-activation-app-token". // Auth configuration comes from the top-level on.github-app field. +// The step uses continue-on-error: true so that a missing app installation (HTTP 404) does not +// fail the pre-activation job; skip-if checks fall back to github.token in that case. func (c *Compiler) buildPreActivationAppTokenMintStep(app *GitHubAppConfig) []string { var steps []string tokenStepID := constants.PreActivationAppTokenStepID steps = append(steps, " - name: Generate GitHub App token for skip-if checks\n") steps = append(steps, fmt.Sprintf(" id: %s\n", tokenStepID)) + steps = append(steps, " continue-on-error: true\n") steps = append(steps, fmt.Sprintf(" uses: %s\n", GetActionPin("actions/create-github-app-token"))) steps = append(steps, " with:\n") steps = append(steps, fmt.Sprintf(" app-id: %s\n", app.AppID)) @@ -520,9 +523,11 @@ func (c *Compiler) buildPreActivationAppTokenMintStep(app *GitHubAppConfig) []st // resolvePreActivationSkipIfToken returns the GitHub token expression to use for skip-if check // steps in the pre-activation job. Priority: App token > custom github-token > empty (default). // When non-empty, callers should emit `with.github-token: ` in the step. +// When an app is configured the token step uses continue-on-error: true, so the expression +// falls back to github.token in case the app is not installed on the repository. func (c *Compiler) resolvePreActivationSkipIfToken(data *WorkflowData) string { if data.ActivationGitHubApp != nil { - return fmt.Sprintf("${{ steps.%s.outputs.token }}", constants.PreActivationAppTokenStepID) + return fmt.Sprintf("${{ steps.%s.outputs.token || github.token }}", constants.PreActivationAppTokenStepID) } if data.ActivationGitHubToken != "" { return data.ActivationGitHubToken diff --git a/pkg/workflow/skip_if_match_test.go b/pkg/workflow/skip_if_match_test.go index 2d1ffc7a64..05e1ea214c 100644 --- a/pkg/workflow/skip_if_match_test.go +++ b/pkg/workflow/skip_if_match_test.go @@ -440,9 +440,9 @@ This workflow uses a GitHub App token for org-wide search. t.Error("Expected owner to be set in GitHub App token mint step") } - // Verify the minted token is used in the skip-if step via the unified step ID - if !strings.Contains(lockContentStr, "github-token: ${{ steps.pre-activation-app-token.outputs.token }}") { - t.Error("Expected minted app token (pre-activation-app-token) to be used in skip-if-match step") + // Verify the minted token is used in the skip-if step via the unified step ID (with github.token fallback) + if !strings.Contains(lockContentStr, "github-token: ${{ steps.pre-activation-app-token.outputs.token || github.token }}") { + t.Error("Expected minted app token (pre-activation-app-token) with github.token fallback to be used in skip-if-match step") } // Verify GH_AW_SKIP_SCOPE is set to "none" diff --git a/pkg/workflow/skip_if_no_match_test.go b/pkg/workflow/skip_if_no_match_test.go index 6f4abb5d61..b73b20a138 100644 --- a/pkg/workflow/skip_if_no_match_test.go +++ b/pkg/workflow/skip_if_no_match_test.go @@ -499,9 +499,9 @@ This workflow uses a GitHub App token for org-wide search. t.Error("Expected owner to be set in GitHub App token mint step") } - // Verify the minted token is used in the skip-if step via the unified step ID - if !strings.Contains(lockContentStr, "github-token: ${{ steps.pre-activation-app-token.outputs.token }}") { - t.Error("Expected minted app token (pre-activation-app-token) to be used in skip-if-no-match step") + // Verify the minted token is used in the skip-if step via the unified step ID (with github.token fallback) + if !strings.Contains(lockContentStr, "github-token: ${{ steps.pre-activation-app-token.outputs.token || github.token }}") { + t.Error("Expected minted app token (pre-activation-app-token) with github.token fallback to be used in skip-if-no-match step") } // Verify GH_AW_SKIP_SCOPE is set to "none" @@ -563,9 +563,9 @@ Both skip-if-match and skip-if-no-match share one mint step. if !strings.Contains(lockContentStr, "Check skip-if-no-match query") { t.Error("Expected skip-if-no-match check to be present") } - // Both reference the same pre-activation-app-token step - if strings.Count(lockContentStr, "github-token: ${{ steps.pre-activation-app-token.outputs.token }}") != 2 { - t.Error("Expected both skip-if steps to reference the unified pre-activation-app-token step") + // Both reference the same pre-activation-app-token step (with github.token fallback) + if strings.Count(lockContentStr, "github-token: ${{ steps.pre-activation-app-token.outputs.token || github.token }}") != 2 { + t.Error("Expected both skip-if steps to reference the unified pre-activation-app-token step with github.token fallback") } }) }