diff --git a/.github/workflows/ci-shared.yml b/.github/workflows/ci-shared.yml index 13315fb..223a394 100644 --- a/.github/workflows/ci-shared.yml +++ b/.github/workflows/ci-shared.yml @@ -26,14 +26,21 @@ on: default: auto type: string -permissions: - contents: read +# Deliberately no workflow-level `permissions` here. A called workflow cannot elevate +# above what its caller granted, and a `permissions` block at this level becomes the +# ceiling for the pipelines dispatched below. `contents: read` here meant dotnet.yml's +# release job -- which needs `contents: write` and `packages: write` -- could never be +# satisfied, and the run failed at startup with no jobs at all. Leaving it unset lets the +# caller's grant flow through; `detect`, which only reads repository metadata, drops to +# read-only on its own. jobs: detect: name: Classify repository runs-on: ubuntu-latest timeout-minutes: 5 + permissions: + contents: read outputs: stack: ${{ steps.classify.outputs.stack }} private: ${{ steps.classify.outputs.private }} diff --git a/docs/shared-ci.md b/docs/shared-ci.md index 42ef753..a0a725b 100644 --- a/docs/shared-ci.md +++ b/docs/shared-ci.md @@ -74,6 +74,15 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +# The caller grants; a called workflow can only reduce. This is the union of what the +# pipelines request -- dotnet.yml's release job needs contents and packages, its security +# job needs id-token -- and a pipeline that needs a permission missing here fails the run +# at startup, before any job exists to report it. +permissions: + contents: write + packages: write + id-token: write + jobs: ci: uses: ktsu-dev/.github/.github/workflows/ci-shared.yml@release