diff --git a/.github/workflows/artifacts-summary.lock.yml b/.github/workflows/artifacts-summary.lock.yml index 34bb993267..e674aed036 100644 --- a/.github/workflows/artifacts-summary.lock.yml +++ b/.github/workflows/artifacts-summary.lock.yml @@ -5610,6 +5610,7 @@ jobs: repositories: ${{ github.event.repository.name }} github-api-url: ${{ github.api_url }} permission-contents: read + permission-discussions: write permission-issues: write permission-pull-requests: write - name: Debug job inputs @@ -6019,6 +6020,7 @@ jobs: repositories: ${{ github.event.repository.name }} github-api-url: ${{ github.api_url }} permission-contents: read + permission-discussions: write - name: Create Discussion id: create_discussion if: ((!cancelled()) && (needs.agent.result != 'skipped')) && (contains(needs.agent.outputs.output_types, 'create_discussion')) diff --git a/.github/workflows/changeset.lock.yml b/.github/workflows/changeset.lock.yml index 40697f8d41..1a1bb1eaa4 100644 --- a/.github/workflows/changeset.lock.yml +++ b/.github/workflows/changeset.lock.yml @@ -5801,6 +5801,7 @@ jobs: repositories: ${{ github.event.repository.name }} github-api-url: ${{ github.api_url }} permission-contents: read + permission-discussions: write permission-issues: write permission-pull-requests: write - name: Debug job inputs diff --git a/.github/workflows/daily-file-diet.lock.yml b/.github/workflows/daily-file-diet.lock.yml index cacc4410f6..ed9e17a3b1 100644 --- a/.github/workflows/daily-file-diet.lock.yml +++ b/.github/workflows/daily-file-diet.lock.yml @@ -6508,6 +6508,7 @@ jobs: repositories: ${{ github.event.repository.name }} github-api-url: ${{ github.api_url }} permission-contents: read + permission-discussions: write permission-issues: write permission-pull-requests: write - name: Debug job inputs diff --git a/.github/workflows/issue-classifier.lock.yml b/.github/workflows/issue-classifier.lock.yml index 44eafee6c7..02134fb672 100644 --- a/.github/workflows/issue-classifier.lock.yml +++ b/.github/workflows/issue-classifier.lock.yml @@ -2204,7 +2204,7 @@ jobs: path: /tmp/gh-aw/aw_info.json if-no-files-found: warn - name: Run AI Inference - uses: actions/ai-inference@334892bb203895caaed82ec52d23c1ed9385151e # v2.0.4 + uses: actions/ai-inference@334892bb203895caaed82ec52d23c1ed9385151e # v1 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 658d3b9a1d..0be3614def 100644 --- a/.github/workflows/release.lock.yml +++ b/.github/workflows/release.lock.yml @@ -6017,13 +6017,13 @@ jobs: - name: Download Go modules run: go mod download - name: Generate SBOM (SPDX format) - uses: anchore/sbom-action@43a17d6e7add2b5535efe4dcae9952337c479a93 # v0.20.11 + uses: anchore/sbom-action@43a17d6e7add2b5535efe4dcae9952337c479a93 # v0.20.10 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.11 + uses: anchore/sbom-action@43a17d6e7add2b5535efe4dcae9952337c479a93 # v0.20.10 with: artifact-name: sbom.cdx.json format: cyclonedx-json @@ -6227,7 +6227,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Release with gh-extension-precompile - uses: cli/gh-extension-precompile@9e2237c30f869ad3bcaed6a4be2cd43564dd421b # v2.1.0 + uses: cli/gh-extension-precompile@9e2237c30f869ad3bcaed6a4be2cd43564dd421b # v2 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 144161022a..eee179e885 100644 --- a/.github/workflows/stale-repo-identifier.lock.yml +++ b/.github/workflows/stale-repo-identifier.lock.yml @@ -174,7 +174,7 @@ jobs: ORGANIZATION: ${{ env.ORGANIZATION }} id: stale-repos name: Run stale_repos tool - uses: github/stale-repos@a21e55567b83cf3c3f3f9085d3038dc6cee02598 # v3.0.2 + uses: github/stale-repos@a21e55567b83cf3c3f3f9085d3038dc6cee02598 # v3 - 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 5207834200..4d0e7e71fe 100644 --- a/.github/workflows/super-linter.lock.yml +++ b/.github/workflows/super-linter.lock.yml @@ -6146,7 +6146,7 @@ jobs: persist-credentials: false - name: Super-linter id: super-linter - uses: super-linter/super-linter@47984f49b4e87383eed97890fe2dca6063bbd9c3 # v8.3.1 + uses: super-linter/super-linter@47984f49b4e87383eed97890fe2dca6063bbd9c3 # v8.2.1 env: CREATE_LOG_FILE: "true" DEFAULT_BRANCH: main diff --git a/pkg/workflow/safe_outputs_app.go b/pkg/workflow/safe_outputs_app.go index 08903d19ac..5746f1b814 100644 --- a/pkg/workflow/safe_outputs_app.go +++ b/pkg/workflow/safe_outputs_app.go @@ -218,9 +218,11 @@ func convertPermissionsToAppTokenFields(permissions *Permissions) map[string]str if level, ok := permissions.Get(PermissionOrganizationProj); ok { fields["permission-organization-projects"] = string(level) } + if level, ok := permissions.Get(PermissionDiscussions); ok { + fields["permission-discussions"] = string(level) + } // Note: The following GitHub Actions permissions do NOT have GitHub App equivalents: - // - discussions (no GitHub App permission for this) // - models (no GitHub App permission for this) // - id-token (not applicable to GitHub Apps) // - attestations (no GitHub App permission for this) diff --git a/pkg/workflow/safe_outputs_app_test.go b/pkg/workflow/safe_outputs_app_test.go index d2cd9b851f..c195319a14 100644 --- a/pkg/workflow/safe_outputs_app_test.go +++ b/pkg/workflow/safe_outputs_app_test.go @@ -204,3 +204,46 @@ Test workflow without safe outputs. require.NoError(t, err, "Failed to parse markdown content") assert.Nil(t, workflowData.SafeOutputs, "SafeOutputs should be nil") } + +// TestSafeOutputsAppTokenDiscussionsPermission tests that discussions permission is included +func TestSafeOutputsAppTokenDiscussionsPermission(t *testing.T) { + compiler := NewCompiler(false, "", "1.0.0") + + markdown := `--- +on: issues +safe-outputs: + create-discussion: + category: "General" + app: + app-id: ${{ vars.APP_ID }} + private-key: ${{ secrets.APP_PRIVATE_KEY }} +--- + +# Test Workflow + +Test workflow with discussions permission. +` + + // Create a temporary test file + tmpDir := t.TempDir() + testFile := filepath.Join(tmpDir, "test.md") + err := os.WriteFile(testFile, []byte(markdown), 0644) + require.NoError(t, err, "Failed to write test file") + + workflowData, err := compiler.ParseWorkflowFile(testFile) + require.NoError(t, err, "Failed to parse markdown content") + require.NotNil(t, workflowData.SafeOutputs, "SafeOutputs should not be nil") + require.NotNil(t, workflowData.SafeOutputs.CreateDiscussions, "CreateDiscussions should not be nil") + + // Build the consolidated safe_outputs job + job, _, err := compiler.buildConsolidatedSafeOutputsJob(workflowData, "main", testFile) + require.NoError(t, err, "Failed to build safe_outputs job") + require.NotNil(t, job, "Job should not be nil") + + // Convert steps to string for easier assertion + stepsStr := strings.Join(job.Steps, "") + + // Verify that permission-discussions: write is included in the GitHub App token minting step + assert.Contains(t, stepsStr, "permission-discussions: write", "GitHub App token should include discussions write permission") + assert.Contains(t, stepsStr, "permission-contents: read", "GitHub App token should include contents read permission") +}