ci: reduce workflow-level permissions to least privilege (#1033) #3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Package Release | |
| on: | |
| push: | |
| branches: | |
| - main | |
| env: | |
| GH_PACKAGES_TOKEN: ${{ secrets.GH_PACKAGES_TOKEN }} | |
| permissions: | |
| # Enable the use of OIDC for trusted publishing and npm provenance | |
| id-token: write | |
| # Enable the use of GitHub Packages registry | |
| packages: write | |
| # Enable the CI validation workflow to checkout the repository | |
| contents: read | |
| # The release workflow involves many crucial steps that once triggered shouldn't be cancelled until | |
| # finished, otherwise we might end up in an inconsistent state (e.g., published to GitHub Packages | |
| # but not npm), so new workflow runs are queued until the previous one has completely finished. | |
| concurrency: | |
| group: ${{ github.workflow }} | |
| cancel-in-progress: false | |
| jobs: | |
| ci-validation: | |
| name: CI Validation | |
| uses: ./.github/workflows/check-ci-validation.yml | |
| release-and-publish: | |
| name: Release & Publish | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| needs: ci-validation | |
| steps: | |
| - name: Generate release bot token | |
| id: release-bot | |
| uses: actions/create-github-app-token@v3 | |
| with: | |
| app-id: ${{ secrets.DOIST_RELEASE_BOT_ID }} | |
| private-key: ${{ secrets.DOIST_RELEASE_BOT_PRIVATE_KEY }} | |
| permission-contents: write | |
| permission-issues: write | |
| permission-pull-requests: write | |
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| with: | |
| token: ${{ steps.release-bot.outputs.token }} | |
| fetch-depth: 0 | |
| - name: Prepare Node.js environment | |
| uses: actions/setup-node@v6 | |
| with: | |
| cache: npm | |
| node-version-file: .node-version | |
| - name: Cache project 'node_modules' directory | |
| id: node-modules-cache | |
| uses: actions/cache@v5 | |
| with: | |
| key: node-modules-cache-${{ hashFiles('**/package-lock.json', '**/.node-version', 'patches/**') }} | |
| path: node_modules/ | |
| - name: Install project npm dependencies | |
| if: ${{ steps.node-modules-cache.outputs.cache-hit != 'true' }} | |
| run: | | |
| npm ci | |
| - name: Build package | |
| run: | | |
| npm run build | |
| # The Node.js environment is prepared based on the `.npmrc` file in the repo, which | |
| # configures Doist scoped packages to use the public npm registry with OIDC | |
| # authentication for the initial `semantic-release` publish, after which we remove the | |
| # Doist registry configuration, and prepare the Node.js environment for the GitHub | |
| # Packages registry, providing a predictable release workflow for both registries. | |
| - name: Publish package to public npm registry | |
| id: semantic-release | |
| run: | | |
| npx semantic-release | |
| env: | |
| GITHUB_TOKEN: ${{ steps.release-bot.outputs.token }} | |
| GIT_AUTHOR_EMAIL: [email protected] | |
| GIT_AUTHOR_NAME: Doist Bot | |
| GIT_COMMITTER_EMAIL: [email protected] | |
| GIT_COMMITTER_NAME: Doist Bot | |
| - name: Remove Doist registry configuration from `.npmrc` | |
| if: ${{ steps.semantic-release.outputs.package-published == 'true' }} | |
| run: | | |
| npm config delete @doist:registry --location=project | |
| - name: Prepare Node.js environment for GitHub Packages registry | |
| if: ${{ steps.semantic-release.outputs.package-published == 'true' }} | |
| uses: actions/setup-node@v6 | |
| with: | |
| cache: npm | |
| node-version-file: .node-version | |
| registry-url: https://npm.pkg.github.com/ | |
| scope: '@doist' | |
| - name: Publish package to private GitHub Packages registry | |
| if: ${{ steps.semantic-release.outputs.package-published == 'true' }} | |
| run: | | |
| npm publish | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.GH_PACKAGES_TOKEN }} |