From 6a2d2762982f2b28b80d235bc9fc5dc1af33659a Mon Sep 17 00:00:00 2001 From: folbrich Date: Mon, 18 May 2026 11:30:21 +0200 Subject: [PATCH 1/3] CI: least-privilege token, dedupe runs, release timeout, Node 24 actions - validate.yaml: add an explicit least-privilege 'permissions: contents: read' block (it previously ran with the repo-default token scope; release.yaml already scopes its token). - validate.yaml: add a concurrency group keyed on workflow + branch/PR so a push and its pull_request no longer run the full 3-OS matrix twice, and superseded runs are cancelled. - release.yaml: add timeout-minutes: 30 to the release job (validate already had a timeout; release had none). - Bump all actions off the deprecated Node 20 runtime (GitHub force- migrates Node 20 actions on 2026-06-02 and removes Node 20 on 2026-09-16): actions/checkout v4->v6, actions/setup-go v5->v6, goreleaser/goreleaser-action v6->v7. All target Node 24. - validate.yaml: build with -o cmd/desync/ to match the project's documented build convention. --- .github/workflows/release.yaml | 7 ++++--- .github/workflows/validate.yaml | 17 ++++++++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index e04967f..af52c6f 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -12,15 +12,16 @@ permissions: jobs: release: runs-on: ubuntu-latest + timeout-minutes: 30 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: fetch-depth: 0 - - uses: actions/setup-go@v5 + - uses: actions/setup-go@v6 with: go-version-file: go.mod - - uses: goreleaser/goreleaser-action@v6 + - uses: goreleaser/goreleaser-action@v7 with: distribution: goreleaser version: '~> v2' diff --git a/.github/workflows/validate.yaml b/.github/workflows/validate.yaml index 932c70b..c836072 100644 --- a/.github/workflows/validate.yaml +++ b/.github/workflows/validate.yaml @@ -11,6 +11,17 @@ on: branches: - '**' +# Least-privilege token; the validate workflow only needs to read the repo. +permissions: + contents: read + +# A push and its pull_request both trigger this workflow on the same +# branch. Group them so only one full matrix runs, and cancel runs that +# are superseded by a newer commit on the same branch/PR. +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} + cancel-in-progress: true + jobs: build: name: Validate on ${{ matrix.os }} @@ -22,13 +33,13 @@ jobs: timeout-minutes: 10 steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 + - uses: actions/checkout@v6 + - uses: actions/setup-go@v6 with: go-version-file: go.mod - run: go test ./... - - run: go build ./cmd/desync + - run: go build -o cmd/desync/ ./cmd/desync - name: Race detector if: runner.os == 'Linux' From 81fdad77e3ffcba41364f93a92a2a97297d859ce Mon Sep 17 00:00:00 2001 From: folbrich Date: Mon, 18 May 2026 12:44:45 +0200 Subject: [PATCH 2/3] CI: fix concurrency key so push and pull_request actually share a group github.ref is refs/heads/ for push but refs/pull/N/merge for pull_request, so the previous key put them in different concurrency groups and the matrix still ran twice. github.ref_name is the bare branch name for push and equals github.head_ref for pull_request, so the two events now share one group and the duplicate run is cancelled. --- .github/workflows/validate.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/validate.yaml b/.github/workflows/validate.yaml index c836072..7c0ab2d 100644 --- a/.github/workflows/validate.yaml +++ b/.github/workflows/validate.yaml @@ -19,7 +19,7 @@ permissions: # branch. Group them so only one full matrix runs, and cancel runs that # are superseded by a newer commit on the same branch/PR. concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} + group: ${{ github.workflow }}-${{ github.head_ref || github.ref_name }} cancel-in-progress: true jobs: From 8e64955383efaea8b6c5888490ec902b4beb0797 Mon Sep 17 00:00:00 2001 From: folbrich Date: Mon, 18 May 2026 12:50:55 +0200 Subject: [PATCH 3/3] CI: scope push trigger to master so PR branches don't double-run cancel-in-progress dedupes the matrix by cancelling the duplicate push run mid-flight, which still starts 3 jobs and leaves a cancelled run in the Actions tab. Restrict the push trigger to master so a feature-branch push with an open PR never creates a push run at all; the pull_request run is the single source of CI for branches. Pushes to master (merges) still run once. The concurrency group stays for cancelling superseded in-progress runs within an event stream. --- .github/workflows/validate.yaml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/validate.yaml b/.github/workflows/validate.yaml index 7c0ab2d..2c7702b 100644 --- a/.github/workflows/validate.yaml +++ b/.github/workflows/validate.yaml @@ -2,11 +2,13 @@ name: Validate on: + # Post-merge validation only. Feature branches are validated by their + # pull_request run, so a branch push with an open PR no longer triggers + # a duplicate (previously cancelled) push run. push: - # Always run when there are new commits branches: - - '**' - # Always run when there are pull requests + - master + # All pull requests. pull_request: branches: - '**'