From 240660c4e366a557c90c6849a9bb70e16e6aaf45 Mon Sep 17 00:00:00 2001 From: Phil Leggetter Date: Mon, 2 Nov 2026 15:27:43 +0000 Subject: [PATCH] ci: build Linux on Dependabot PRs without secrets; drop the workflow_run rerun build-linux was skipped on Dependabot pull_request runs because it logs in to Docker Hub with secrets those runs do not get. A skipped required check counts as passing. The workflow_run rerun meant to cover it checked out the default branch, not the PR, so the Linux build and Docker snapshot never ran against a dependency bump before merge. It also ran test against main for every PR, because "Dependabot PR Check" completes even when its job skips. A --snapshot build never pushes images, so the Docker Hub login only authenticates the pull of the public alpine base image. Log in when the credentials exist and pull anonymously when they do not, and run build-linux on every pull_request. Remove the workflow_run trigger and the "Dependabot PR Check" workflow, which existed only to drive it. No run now checks out PR code in a privileged context, so neither a Dependabot PR nor a fork PR is built with secrets. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/dependabot_pr.yml | 12 ------------ .github/workflows/test.yml | 30 ++++++++++++++++++++++++----- 2 files changed, 25 insertions(+), 17 deletions(-) delete mode 100644 .github/workflows/dependabot_pr.yml diff --git a/.github/workflows/dependabot_pr.yml b/.github/workflows/dependabot_pr.yml deleted file mode 100644 index ad182c8f..00000000 --- a/.github/workflows/dependabot_pr.yml +++ /dev/null @@ -1,12 +0,0 @@ -### .github/workflows/dependabot_pr.yml -### This workflow doesn't have access to secrets and has a read-only token -name: Dependabot PR Check -on: - pull_request - -jobs: - check-dependabot: - runs-on: ubuntu-latest - if: ${{ github.actor == 'dependabot[bot]' }} - steps: - - run: echo "PR created by Dependabot" \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c1648b9f..9dd1ff7d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,10 +1,12 @@ name: test on: - workflow_run: - workflows: ["Dependabot PR Check"] - types: - - completed + # No workflow_run trigger. It used to run this workflow again after the + # "Dependabot PR Check" workflow, to give build-linux the Docker Hub secrets + # that Dependabot's pull_request runs do not get. But a workflow_run run + # checks out the default branch, not the PR, so it never built the + # dependency bump. Checking out the PR there instead would build untrusted + # code with secrets. build-linux now runs on pull_request without secrets. pull_request: branches: - main @@ -79,9 +81,14 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GORELEASER_GITHUB_TOKEN }} + # Runs on every pull request, including Dependabot and fork PRs, which get no + # secrets. A --snapshot build never pushes images ("snapshot build: will not + # push any images"), so Docker Hub credentials are only used to authenticate + # the pull of the public alpine base image. Log in when they are available and + # pull anonymously when they are not, rather than skipping the job: a skipped + # required check counts as passing. build-linux: runs-on: ubuntu-latest - if: ${{ github.actor != 'dependabot[bot]' || github.event.workflow_run.conclusion == 'success' }} env: # https://goreleaser.com/customization/docker_manifest/ DOCKER_CLI_EXPERIMENTAL: "enabled" @@ -90,7 +97,20 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 + # A step's `if` cannot read `secrets` directly, so check for them here. + - name: Check for Docker Hub credentials + id: docker-creds + env: + DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} + run: | + if [ -n "$DOCKER_USERNAME" ]; then + echo "available=true" >> "$GITHUB_OUTPUT" + else + echo "available=false" >> "$GITHUB_OUTPUT" + echo "::notice::No Docker Hub credentials in this run (Dependabot or fork PR); pulling base images anonymously." + fi - name: Docker Login + if: steps.docker-creds.outputs.available == 'true' uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }}