ci: move Go test pipeline from CircleCI to GitHub Actions#4250
Conversation
Replace .circleci/config.yml with a go-test.yaml workflow that runs go test -race and uploads coverage to Qlty Cloud via the official qlty-action with OIDC. Update README build-status badges. Closes #4249 Assisted by AI
- Run tests inside golang:1.26.3 container so DNS errors come from glibc
("no such host"), matching the regex used by tests in
crypto/storage/vault, didman/api/v1, policy and others — the GHA
ubuntu-latest runner uses systemd-resolved which returns
"server misbehaving".
- Set persist-credentials: false on actions/checkout (zizmor:
credential persistence through GitHub Actions artifacts).
- Pin qltysh/qlty-action/coverage to v2.2.0 commit SHA (zizmor:
unpinned action reference).
Assisted by AI
- policy: switch loadFromDirectory to os.ReadDir so .json files load in
lexical order. dir.Readdir(0) returned entries in filesystem-defined
order, making duplicate-scope detection non-deterministic across
platforms (the duplicate-detection test asserts which file is reported
as the dupe, which only held on CircleCI's filesystem).
- vault, didman client tests: drop assert.Regexp on DNS error strings —
these matched against Go net package output ("no such host" /
"Temporary failure in name resolution") and didn't verify any
behavior of the code under test. The "got an error + nil result"
assertions cover the actual contract. Aligns with the other
"wrong address" subtests in the same didman file.
- Drop the golang:1.26.3 container workaround from go-test.yaml now
that the underlying brittleness is gone.
Assisted by AI
|
Coverage Impact ⬆️ Merging this pull request will increase total coverage on Modified Files with Diff Coverage (1)
🛟 Help
|
| - 'master' | ||
| - 'V*' | ||
| pull_request: | ||
| branches: |
There was a problem hiding this comment.
Dropped the pull_request.branches filter — PRs targeting any base now trigger the workflow. Kept the push filter on master/V* so we don't double-run on feature-branch pushes (the pull_request event covers those).
stevenvegt
left a comment
There was a problem hiding this comment.
I'd like the test to run on every PR, so we have tests on PRs on feature branches as well.
Per review feedback: tests should fire on PRs to feature branches too. Assisted by AI

Summary
.circleci/config.ymlwith.github/workflows/go-test.yaml:go test ./... -raceon PRs and pushes tomaster/V*.qltysh/qlty-action/coverage(SHA-pinned to v2.2.0) with OIDC — no token secret.actions/checkoutruns withpersist-credentials: false(zizmor finding).README.rst/README_template.rstto point at the new workflow.Single-runner port — drops the 8-way
circleci tests split+ coverage merge. Shard via matrix later only if wall-clock becomes a problem.Drive-by fixes required to keep the new pipeline green
The GHA
ubuntu-latestrunner has different filesystem readdir order and uses systemd-resolved (different DNS error strings) than CircleCI'scimg/goimage, which exposed two existing brittlenesses. Happy to split these into separate PRs if preferred.policy/local.go:dir.Readdir(0)→os.ReadDir(directory). Directory entries now load in lexical order, so duplicate-scope detection reports the same file deterministically across platforms.crypto/storage/vault/vault_test.go,didman/api/v1/client_test.go: dropassert.Regexpagainstno such host|Temporary failure in name resolution. These matched on Go'snetpackage error text and verified nothing about the code under test;assert.Error(t, err)+ nil-result checks remain. Matches the pattern other "wrong address" subtests in the same didman file already use.Closes #4249.
Test plan
Go testworkflow green on this PR.qlty check(zizmor) green.master: coverage shows up on the Qlty project (requires Qlty GitHub App + OIDC trust; fallback is aQLTY_COVERAGE_TOKENsecret withtoken: \${{ secrets.QLTY_COVERAGE_TOKEN }}).Assisted by AI