ci: coverage gates, CI workflow rebuild, release tag-ordering fix - #151
Merged
Conversation
Joins the nine-repo CI family: hack/coverage-gate.sh, hack/patch-coverage.sh and hack/coverage-gate.test.sh are byte-identical copies of the family reference, with a 75% hard line-coverage floor in hack/coverage-floors. Backend line coverage 71.8% -> 77.5% via new tests for the Hue Bridge Pro CLIP v2 resource layer, the SSDP header parser and M-SEARCH responder, the mDNS/DNS name parser and the config persistence path. Release: the git tag was created BEFORE the image build, so a failed build left an orphan tag and permanently burned that version number. The tag now follows a successful image push, is created via the REST create-ref call the rest of the family uses, and is accompanied by a GitHub Release. A paths-ignore block stops doc-only commits from cutting a release. Removes the Dependabot auto-merge workflow: dependency PRs are merged by hand across this family. cleanup-images.yaml is deliberately untouched.
dist/ is gitignored and has no tracked files, so it can never appear in a push diff and paths-ignore has no bearing on it either way.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Brings
relume-tvinto the nine-repo CI family whose reference istrick77/peeq.Coverage gates
hack/coverage-gate.sh,hack/patch-coverage.shandhack/coverage-gate.test.share byte-identical copies of the family reference — verified withdiff -q. They auto-detect whether the Go module sits atbackend/or the repo root, so they work here unmodified.hack/coverage-floorssets a hard 75% line-coverage floor (the unusedui=75.0line is kept so the file matches the rest of the family).hack/coverage-gate.test.shpasses locally:coverage-gate: all checks passed.Backend coverage: 71.8% -> 77.5%
This was the only repo in the family below the floor. Measured with the exact command CI runs (
-race -covermode=atomic -coverpkg=./..., then a Cobertura conversion,cmd/excluded). New tests, all asserting real behaviour rather than absence of panics:internal/bridgepro/resources_test.goBridgeInfoname-via-owning-device resolution and its best-effort fallbacks,Lightscapability decoding (the pointer sub-objects that distinguish "cannot do colour" from "colour is 0,0"), stable ID sorting,EntertainmentConfigs, and theErrUnreachable/ErrQueueFull/HTTP-status error taxonomy including a certificate-pin mismatchinternal/bridgepro/pair_test.goPair(was 0%): app key + DTLS clientkey extraction,generateclientkeyin the request body, the "link button not pressed" rejection, empty/malformed/unexpected responses; plusHTTPClientForpinning — matching pin accepted, wrong pin refusedinternal/ssdp/parse_test.goparseHeaders(key uppercasing, value trimming, colons inside values, malformed lines),logDatagram, andhandle: one 200 OK per SSDP variant with correct LOCATION/hue-bridgeid/CACHE-CONTROL, NOTIFY datagrams ignored, and bail-on-first-write-errorinternal/diag/dnsparse_test.godnsQuestionNames/readName: compression-pointer following, pointer-loop and self-pointer termination (the decompression bomb this parser guards against on untrusted multicast input), truncated labels/pointers, over-stated QDCOUNT; plusinspectfiltering anddeadlineinternal/config/psk_test.goPSKForUserhex decoding and its rejection paths,save/writeFileSyncatomic-write behaviour: 0600 mode, O_TRUNC, parent-dir creation, error surfacing, and no temp file left behind after a failed rename;generateSerialshape and randomnessNetwork-touching code is tested at its pure boundaries (parsers, encoders, response construction). The only sockets opened are loopback UDP pairs in the SSDP
handletests — no multicast, so nothing here can go flaky in CI.Gate verification (mandatory step, done)
A scratch exported function was added, coverage regenerated, and
patch-coverage.shrun againstorigin/master:RED
GREEN (after adding a covering test)
The scratch code and its test were then deleted entirely;
git ls-files | grep -i scratchreturns nothing and the branch history was reset so they never appear in a commit.test.yaml->ci.yamlRenamed via
git mv,name: CI, job display nameBackend (build + test).pull_request: branches: [master]+workflow_dispatch. Master no longer runs tests — it builds and pushes the image.permissions: contents: readand aci-${{ github.ref }}concurrency group withcancel-in-progress.actions/setup-go@v6->@v7; the pinnedgo-version: "1.26"is replaced bygo-version-file: go.mod, so the toolchain can never drift from the module.fetch-depth: 0on the checkout plus an explicit "Fetch base ref" step —patch-coverage.shdiffs against the PR base, which is not resolvable otherwise.actions/setup-python@v6+diff-cover==10.3.0.go vet(go vetdoes not cover formatting). The tree is gofmt-clean today; this keeps it that way.-race(henceCGO_ENABLED: "1") and-coverpkg=./..., then converts to Cobertura — Go's own tooling reports statements only and exposes no line metric.Coverage summaryandupload-artifactsteps: they only reported a number nobody enforced. The two gates replace them.No golangci-lint in this PR — separate pass.
release.yaml
Tag-ordering bug (the real fix here). The tag was created and pushed at roughly line 57, before
setup-buildxandbuild-push. A failed image build therefore left an orphan tag behind — and since the next run computes its version fromgit tag --list ... --sort=-v:refname | head -n1, that version number was permanently burned: the release that failed still consumed it, and no later run could ever reuse it. Tag creation now happens only after the image push succeeds.Mechanism. Switched from
git tag+git push originto the family's REST create-ref, and added a GitHub Release. Both approaches work; create-ref needs no git credentials configured in the checkout and is a single atomic call, and every repo in the family uses it so the release workflows stay directly comparable.paths-ignore. Added to the push trigger so doc-only commits stop cutting full versions, multi-arch builds, GHCR pushes, tags and releases. Deliberately an ignore-list, not an allow-list: a new top-level directory starts out releasing, which is the safe default — forgetting to add a path costs one redundant release, whereas forgetting to add one to an allow-list would silently skip a needed release.dist/**is deliberately not ignored, since it holds shipped assets the image serves.workflow_dispatchstays unfiltered, so a release can always be forced by hand.permissionsalready hadcontents: writeandpackages: write; unchanged.Deliberate: Dependabot auto-merge removed
.github/workflows/dependabot-auto-merge.yamlis deleted on purpose, not by accident. This is a decision taken across all nine repos: dependency PRs get reviewed and merged by hand.Deliberate:
cleanup-images.yamluntouchedZero changes to that file, also on purpose. It uses
dataaxiom/ghcr-cleanup-action@v1rather than thesnok/container-retention-policythe rest of the family uses, because this repo builds multi-arch (qemu + buildx, amd64/arm64) and that action is manifest-list aware, withkeep-n-tagged: 10anddelete-untagged: true. Switching it would risk breaking multi-arch cleanup for no benefit.Local verification