Skip to content

Improve GitHub Workflow performance#507

Open
fdcastel wants to merge 5 commits into
openpubkey:mainfrom
fdcastel:improve-gha-performance
Open

Improve GitHub Workflow performance#507
fdcastel wants to merge 5 commits into
openpubkey:mainfrom
fdcastel:improve-gha-performance

Conversation

@fdcastel
Copy link
Copy Markdown
Contributor

@fdcastel fdcastel commented Apr 1, 2026

Based on #506


This branch speeds up GitHub Actions in three ways:

  1. Expensive ARM coverage no longer runs on every fork push.
  2. Workflows only trigger when relevant files change.
  3. Superseded runs on the same branch or PR are cancelled automatically.

The biggest improvement is the Windows GitHub provider workflow on forks.

  • Before: 15m 00s
  • After: 2m 21s
  • Improvement: 12m 39s faster, about 84.3%

That reduction comes from moving the windows-11-arm provider job to upstream-only coverage instead of running it on every fork push.

Baseline Runs

Baseline branch: fix-gha-go-run

Optimized branch: improve-gha-performance

Measured Differences

Workflow Before After Delta Notes
Test GitHub Provider Windows 15m 00s 2m 21s -12m 39s (-84.3%) Fork runs now skip the ARM64 provider leg
CI 6m 20s 5m 56s -0m 24s (-6.3%) ARM64 CI jobs are upstream-only; x64 distro coverage still runs on forks
Build 2m 01s 1m 56s -0m 05s (-4.1%) Narrower trigger and setup-go caching restored
GitHub Actions Security Analysis with zizmor 0m 50s 0m 22s -0m 28s (-56.0%) Trigger now limited to workflow automation changes
Go Checks n/a on workflow-only baseline push 0m 45s n/a Now cancels superseded runs and skips redundant go mod download
Test GitHub Provider no comparable branch-push baseline 2m 21s n/a Added workflow_dispatch so branch changes can be validated on demand

Worst Offender: Windows GitHub Provider ARM64

Baseline run: https://github.com/fdcastel/opkssh/actions/runs/23825106132

Baseline job timings:

  • Test on Windows 11 ARM64: 14m 55s
  • Test on Windows Server 2022: 2m 47s
  • Test on Windows Server 2025: 1m 37s

Optimized run: https://github.com/fdcastel/opkssh/actions/runs/23827343256

Optimized job timings on the fork:

  • Test on Windows Server 2022: 2m 18s
  • Test on Windows Server 2025: 1m 41s
  • Test on Windows 11 ARM64: skipped by design on forks

The root cause is not Go compilation. The ARM64 job spends most of its time installing OpenSSH Server on the runner. In the baseline run, Install OpenSSH Server alone took 12m 37s on windows-11-arm.

That means the right optimization is scheduling or scoping that coverage, not micro-optimizing the Go steps.

What Changed

1. Fork pushes now stay on the fast path

Updated workflows:

  • .github/workflows/ci.yml
  • .github/workflows/gha-windows.yml

Changes:

  • Split expensive ARM64 coverage out of the default fork path.
  • ARM64 jobs now run only for openpubkey/opkssh on main, or when manually dispatched.
  • Forks still keep useful coverage on x64 Linux and standard Windows runners.

2. Workflows only run for relevant changes

Updated workflows:

  • .github/workflows/build.yml
  • .github/workflows/ci.yml
  • .github/workflows/gha-windows.yml
  • .github/workflows/gha.yml
  • .github/workflows/go.yml
  • .github/workflows/staging.yml
  • .github/workflows/zizmor.yml

Changes:

  • Added paths filters so docs-only or unrelated changes do not fan out into full CI.
  • zizmor now runs only when workflow automation changes.
  • The Linux GitHub provider workflow now runs automatically only when its code or Docker inputs change.

3. Superseded branch runs are cancelled

Added concurrency to:

  • .github/workflows/build.yml
  • .github/workflows/ci.yml
  • .github/workflows/cli-docs.yml
  • .github/workflows/gha-windows.yml
  • .github/workflows/gha.yml
  • .github/workflows/go.yml
  • .github/workflows/release-drafter.yml
  • .github/workflows/staging.yml
  • .github/workflows/zizmor.yml

This does not make a single run faster, but it removes wasted queue time and stale feedback when pushing multiple times to the same branch.

4. Redundant Go dependency steps were removed

Updated workflows:

  • .github/workflows/ci.yml
  • .github/workflows/gha-windows.yml
  • .github/workflows/gha.yml
  • .github/workflows/go.yml

Changes:

  • Removed explicit go mod download where actions/setup-go already restores module/build cache or where the actual go build or go test step will download what it needs.
  • Re-enabled default setup-go caching in the snapshot/release build path by removing cache: false in .github/workflows/build.yml and .github/workflows/release.yml.

5. Upstream-only automation is now explicit

Updated workflows:

  • .github/workflows/cli-docs.yml
  • .github/workflows/release-drafter.yml
  • .github/workflows/release.yml
  • .github/workflows/staging.yml

Changes:

  • Auto PR creation for CLI docs only runs on openpubkey/opkssh.
  • Release drafting only runs on openpubkey/opkssh.
  • Coverage publishing only runs on openpubkey/opkssh.
  • The published release workflow only runs on openpubkey/opkssh.

The fork-specific release workflow was already correctly separated in .github/workflows/release-fork.yml, so it was left unchanged.

Official Repo vs Fork Behavior After This Change

Forks like fdcastel/opkssh

  • Build runs on relevant code and packaging changes.
  • Go Checks runs on Go changes and its own workflow changes.
  • CI runs Linux x64 integration coverage and standard Windows coverage.
  • Test GitHub Provider Windows runs on Windows Server 2022 and 2025.
  • Test GitHub Provider can be run manually on a branch with workflow_dispatch.
  • zizmor runs only when GitHub Actions automation changes.

Official repo openpubkey/opkssh

  • Everything above still works.
  • Additional ARM64 CI jobs run on main and via manual dispatch.
  • Additional ARM64 Windows provider coverage runs on main and via manual dispatch.
  • CLI docs automation, release drafting, coverage publishing, and release publishing run only here.

Remaining Follow-up Ideas

These were not implemented in this branch, but they are the next places to look if more reduction is needed:

  1. Move upstream ARM64 coverage to a scheduled workflow instead of every main push if faster feedback on main matters more than immediate ARM validation.
  2. Extract the duplicated Windows provider job steps into a reusable workflow or composite action to cut maintenance cost.
  3. If GitHub runner images ever ship OpenSSH Server preinstalled on ARM64, restore ARM validation to the default path and re-measure.

fdcastel added 2 commits April 2, 2026 14:18
Upgrade the following actions to versions that use the Node.js 24 runtime:

- golangci/golangci-lint-action: v8.0.0 -> v9.2.0
- release-drafter/release-drafter: v6.1.0 -> v7.1.1
- docker/setup-buildx-action: v3.12.0 -> v4.0.0
- docker/build-push-action: v6.18.0 -> v7.0.0

Closes openpubkey#494
@fdcastel fdcastel force-pushed the improve-gha-performance branch from ac7e12f to 301455f Compare April 2, 2026 17:48
@fdcastel
Copy link
Copy Markdown
Contributor Author

fdcastel commented Apr 2, 2026

Rebased this branch onto #508 (fix/issue-494-upgrade-node20-actions) so the Node.js 24 action upgrades are included.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants