diff --git a/.github/workflows/renovate-autoupdate.yaml b/.github/workflows/renovate-autoupdate.yaml index ec30ae8..3b802ac 100644 --- a/.github/workflows/renovate-autoupdate.yaml +++ b/.github/workflows/renovate-autoupdate.yaml @@ -58,10 +58,15 @@ on: type: string default: "chore(deps): update dependencies" admin-merge: - description: "Merge with --admin, which bypasses branch protection" + description: "Merge with --admin, which bypasses branch protection. The workflow token cannot do this, so leave it off unless you pass a token that can." required: false type: boolean - default: true + default: false + release-workflow: + description: "Workflow file to dispatch after the merge, for example release.yaml. It must have a workflow_dispatch trigger and the caller needs actions: write. Empty means no dispatch." + required: false + type: string + default: "" lfs: description: "Enable Git LFS checkout (for repos with large files)" required: false @@ -141,7 +146,7 @@ jobs: uses: renovatebot/github-action@v46.3.6 with: configurationFile: ${{ runner.temp }}/renovate-autoupdate-config.json - token: ${{ secrets.RENOVATE_TOKEN || secrets.HOMEBREW_TAP_TOKEN || github.token }} + token: ${{ github.token }} renovate-version: ${{ inputs.renovate-version }} env: LOG_LEVEL: info @@ -149,7 +154,7 @@ jobs: - name: Find the batch PR id: find-pr env: - GH_TOKEN: ${{ secrets.RENOVATE_TOKEN || secrets.HOMEBREW_TAP_TOKEN || github.token }} + GH_TOKEN: ${{ github.token }} run: | number=$(gh pr list --repo "$GITHUB_REPOSITORY" --head "$BATCH_BRANCH" --state open --json number --jq '.[0].number // empty') echo "pr-number=$number" >> "$GITHUB_OUTPUT" @@ -175,7 +180,7 @@ jobs: uses: actions/checkout@v6 with: ref: ${{ env.BATCH_BRANCH }} - token: ${{ secrets.RENOVATE_TOKEN || secrets.HOMEBREW_TAP_TOKEN || github.token }} + token: ${{ github.token }} lfs: ${{ inputs.lfs }} - name: Record the tested commit @@ -288,7 +293,7 @@ jobs: - name: Report the failure on the PR if: failure() env: - GH_TOKEN: ${{ secrets.RENOVATE_TOKEN || secrets.HOMEBREW_TAP_TOKEN || github.token }} + GH_TOKEN: ${{ github.token }} PR: ${{ needs.renovate.outputs.pr-number }} RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} run: | @@ -302,13 +307,14 @@ jobs: runs-on: ${{ fromJSON(startsWith(inputs.runner || vars.SHARED_ACTIONS_RUNNER || 'ubuntu-latest', '{') && (inputs.runner || vars.SHARED_ACTIONS_RUNNER || 'ubuntu-latest') || format('"{0}"', inputs.runner || vars.SHARED_ACTIONS_RUNNER || 'ubuntu-latest')) }} timeout-minutes: 10 permissions: + actions: write contents: write pull-requests: write steps: - name: Squash-merge the PR env: - # A PAT or App token makes the merge push trigger the release workflow. github.token does not. - GH_TOKEN: ${{ secrets.RENOVATE_TOKEN || secrets.HOMEBREW_TAP_TOKEN || github.token }} + # A push made with github.token does not trigger workflows, so the release is dispatched below. + GH_TOKEN: ${{ github.token }} PR: ${{ needs.renovate.outputs.pr-number }} HEAD_SHA: ${{ needs.test.outputs.head-sha }} SUBJECT: ${{ inputs.commit-subject }} @@ -320,3 +326,12 @@ jobs: --subject "$SUBJECT" \ --body "Automated dependency update. All tests passed." \ ${ADMIN:+--admin} + + - name: Dispatch the release workflow + if: inputs.release-workflow != '' + env: + GH_TOKEN: ${{ github.token }} + RELEASE_WORKFLOW: ${{ inputs.release-workflow }} + run: | + branch=$(gh api "repos/$GITHUB_REPOSITORY" --jq .default_branch) + gh workflow run "$RELEASE_WORKFLOW" --repo "$GITHUB_REPOSITORY" --ref "$branch" diff --git a/README.md b/README.md index 6c58e7a..250ed88 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,7 @@ on: - cron: "0 3 * * *" permissions: + actions: write # only to dispatch release-workflow contents: write pull-requests: write @@ -125,7 +126,7 @@ jobs: uses: lukaszraczylo/shared-actions/.github/workflows/renovate-autoupdate.yaml@main with: go-version: ">=1.24" - secrets: inherit + release-workflow: release.yaml ``` The workflow finds `go.mod` and `package.json` itself and tests what exists. A repo with both, such as a Go backend with a Vue frontend, gets both tested in one run. @@ -143,7 +144,8 @@ The workflow finds `go.mod` and `package.json` itself and tests what exists. A r | `minimum-release-age` | `2 days` | Skip releases younger than this | | `renovate-version` | `44` | Renovate version | | `commit-subject` | `chore(deps): update dependencies` | Squash commit subject | -| `admin-merge` | `true` | Merge with `--admin` | +| `release-workflow` | | Workflow file to dispatch after the merge, for example `release.yaml`. It needs a `workflow_dispatch` trigger. Empty means no dispatch. | +| `admin-merge` | `false` | Merge with `--admin`. The workflow token cannot bypass branch protection. | | `lfs` | `false` | Git LFS checkout | | `runner` | | Runner label or runner group, as in the other workflows | @@ -160,7 +162,10 @@ The workflow finds `go.mod` and `package.json` itself and tests what exists. A r The defaults already cap `typescript` below 7, which breaks `vue-tsc`. -**Token.** The workflow uses `RENOVATE_TOKEN`, then `HOMEBREW_TAP_TOKEN`, then `github.token`. With `github.token` the merge push does not trigger other workflows, so a release workflow on `push` will not run. Use a PAT or App token for repositories that release on push. +**Token.** No secret is needed. Everything runs inside the calling repository with the workflow's own token, which needs `contents: write` and `pull-requests: write`. Two repository settings matter: + +- Settings, Actions, General: tick "Allow GitHub Actions to create and approve pull requests". Without it Renovate cannot open the PR. +- A push made with the workflow token does not trigger other workflows, so a release workflow that runs on `push` will not start after the merge. Set `release-workflow` to dispatch it explicitly, and grant `actions: write`. **Commit message.** The squash commit uses a fixed subject and body without the words `major`, `minor` or `breaking`, because `semver-generator` matches release keywords in commit messages.