Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 23 additions & 17 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@ env:
DOTNET_NOLOGO: true
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
MINVERBUILDMETADATA: build.${{ github.run_id }}.${{ github.run_attempt}}
# On pull requests — especially from forks, where GitHub forces the token to
# read-only — this workflow needs no secrets and no write access: it only builds,
# tests, and uploads .trx artifacts. Test results are published by a separate
# workflow (test-report.yml, triggered via workflow_run) that runs in the
# base-repo context with checks:write. The only steps that touch secrets/OIDC are
# the main-only signing and publishing steps in build-windows, which is the sole
# job granted id-token: write (scoped at the job level below). See issue #4642.
permissions:
id-token: write
contents: read
Comment on lines 20 to 21

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed by scoping id-token: write to the build-windows job only (the workflow default is now contents: read), so the Linux build job and any future job carry no OIDC. I kept signing/publishing in build-windows rather than splitting into a dedicated job because that path only runs on main and is untested-by-CI; restructuring it risks silently breaking releases for a marginal gain. Worth noting the fork escalation specifically isn't reachable: GitHub forces the token read-only for fork pull_request runs and will not honor id-token: write, so forks cannot mint an OIDC token here at all. The residual surface is trusted same-repo collaborators, and the Azure federated credential should be subject-constrained on the Azure side regardless. (commit 8c86567)

checks: write
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
Expand All @@ -37,19 +42,22 @@ jobs:
- name: Build and Test
run: ./Build.ps1
shell: pwsh
- name: Report Test Results
uses: dorny/test-reporter@v1
# Publishing the report needs checks:write, which GitHub forces to read-only
# for pull_request runs from forks. Don't let that fail the build; the test
# step itself already reflects pass/fail.
continue-on-error: true
- name: Upload Test Results
# Publishing happens in test-report.yml, which downloads this artifact.
uses: actions/upload-artifact@v4
if: success() || failure()
with:
name: Test Results (Linux)
name: test-results-Linux
path: artifacts/**/*.trx
reporter: dotnet-trx
if-no-files-found: ignore
build-windows:
needs: build
# id-token:write is required only for the main-only Azure OIDC login used to
# code-sign packages. Granting it here (not at the workflow level) keeps it
# off the Linux build job and the default for any future jobs.
permissions:
id-token: write
contents: read
strategy:
fail-fast: false
runs-on: windows-latest
Expand Down Expand Up @@ -79,16 +87,14 @@ jobs:
- name: Build and Test
run: ./Build.ps1
shell: pwsh
- name: Report Test Results
uses: dorny/test-reporter@v1
# See note on the Linux job: report publishing is best-effort and must
# never fail the build (forked-PR tokens are read-only).
continue-on-error: true
- name: Upload Test Results
# Publishing happens in test-report.yml, which downloads this artifact.
uses: actions/upload-artifact@v4
if: success() || failure()
with:
name: Test Results (Windows)
name: test-results-Windows
path: artifacts/**/*.trx
reporter: dotnet-trx
if-no-files-found: ignore
- name: Sign packages
# Signing uses the Azure Key Vault login above; only runs on main.
if: github.ref == 'refs/heads/main'
Expand Down
36 changes: 36 additions & 0 deletions .github/workflows/test-report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Test Report

# Publishes test results for runs of the CI workflow, including pull requests
# from forks. The CI workflow itself runs with a read-only token (GitHub forces
# this for fork PRs) and only uploads the .trx files as artifacts. This workflow
# is triggered by workflow_run, so it runs in the *base repository* context with
# a writable token and can call the Checks API to publish inline reports.
# See issue #4642.

on:
workflow_run:
workflows: [CI]
types:
- completed

permissions:
contents: read
actions: read
checks: write

jobs:
report:
runs-on: ubuntu-latest
steps:
- name: Publish Test Results
uses: dorny/test-reporter@v1
with:
# Download every test-results-* artifact from the triggering CI run and
# publish one check per platform, e.g. "Test Results (Linux)".
artifact: /test-results-(.*)/
name: Test Results ($1)
path: '**/*.trx'
reporter: dotnet-trx
# A build that fails before producing any .trx shouldn't make this
# report red; the CI run already reflects that failure.
fail-on-empty: 'false'
Loading