ci: fence the test recipes and rebuild the pipelines around the gate set
Test / test (push) Failing after 24s
Test / test (push) Failing after 24s
Assisted-by: DeepSeek V4.1 Flash
This commit is contained in:
@@ -1,49 +1,33 @@
|
||||
# Release, Go library. Runs on version tags (v1.2.3) pushed to main.
|
||||
# Release, Go library. Runs on a version tag (v1.2.3) pushed to main.
|
||||
#
|
||||
# A library ships no binaries, so there is no build matrix and no smoke test: the release
|
||||
# carries the CHANGELOG section as its body and nothing else. The gates still run first,
|
||||
# in their own job and once, minus the race detector: race never runs on a push path or a
|
||||
# tag, and the local gate raced this tree before the tag was cut. The write permission
|
||||
# sits on the release job alone, and the version the binary reports is the one the
|
||||
# toolchain records from the tag, with nothing injected.
|
||||
# The pipeline does one thing: it publishes the release from the tag, notes and
|
||||
# all. No gate runs here. The tagged tree was tested on every push to
|
||||
# development, the deep suite is the suite workflow's business, and race never
|
||||
# runs in CI at all. A library ships no assets, so there is no build and
|
||||
# nothing to upload.
|
||||
#
|
||||
# Every step is one command, so the step that fails is the gate that failed, and no shell
|
||||
# option has to be trusted for the run to stop. The scripted steps are Perl, not shell and
|
||||
# not Python: Perl behaves the same on both runner images, there is no bashism to trip over
|
||||
# on ash, and it is one language instead of two. The Perl uses builtins only, because
|
||||
# Fedora packages the Perl modules separately and nothing beyond `perl` itself may be
|
||||
# assumed present, which is why the release body is escaped by hand and curl is the
|
||||
# transport.
|
||||
# Every step is one command, and the scripted steps are Perl with builtins
|
||||
# only. Perl drives curl through a list, so no argument is ever word-split,
|
||||
# globbed or quoted wrong.
|
||||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags: ["v*"]
|
||||
|
||||
env:
|
||||
# The box is shared with the forge, so parallelism is bounded on purpose. The gates job
|
||||
# needs it most, since it runs the suite.
|
||||
GOFLAGS: -p=1
|
||||
GOMAXPROCS: "2"
|
||||
|
||||
jobs:
|
||||
gates:
|
||||
release:
|
||||
runs-on: fedora
|
||||
timeout-minutes: 10
|
||||
permissions:
|
||||
# contents: read is required for the checkout: a job that declares any
|
||||
# permissions gets a token scoped to exactly those, and releases: write
|
||||
# alone leaves the fetch with no read access, which Gitea answers with
|
||||
# a 404 "Repository not found". Verified on the instance 2026-09-16.
|
||||
contents: read
|
||||
releases: write
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
# The module is the source of truth for the version, so it cannot drift.
|
||||
go-version-file: go.mod
|
||||
cache: true
|
||||
|
||||
- name: Install Perl
|
||||
# Perl for the steps below. The install is a no-op where the package
|
||||
# is already present.
|
||||
run: dnf install -y perl
|
||||
|
||||
- name: Validate the tag
|
||||
env:
|
||||
VERSION: ${{ gitea.ref_name }}
|
||||
@@ -55,68 +39,12 @@ jobs:
|
||||
print qq{tag $v\n};
|
||||
'
|
||||
|
||||
- name: Format
|
||||
run: |
|
||||
perl -e '
|
||||
open(my $g, q{-|}, q{gofmt}, q{-l}, q{.}) or die qq{gofmt: $!};
|
||||
my @bad = <$g>;
|
||||
close($g);
|
||||
print @bad;
|
||||
exit(@bad ? 1 : 0);
|
||||
'
|
||||
|
||||
- name: Vet
|
||||
run: go vet ./...
|
||||
|
||||
- name: Modernise
|
||||
# Exits non-zero when it has something to rewrite, so it needs no output capture.
|
||||
run: go fix -diff ./...
|
||||
|
||||
- name: Build
|
||||
run: go build ./...
|
||||
|
||||
- name: Tests
|
||||
# Keep the pattern equal to `packages` in the project's justfile.
|
||||
run: go test -count=1 -timeout 10m -coverprofile=coverage.out ./...
|
||||
|
||||
- name: Coverage floor
|
||||
run: |
|
||||
perl -e '
|
||||
open(my $c, q{-|}, q{go}, q{tool}, q{cover}, q{-func=coverage.out}) or die qq{cover: $!};
|
||||
my $total;
|
||||
while (my $l = <$c>) { $total = $1 if $l =~ m{^total:\s+\S+\s+([0-9.]+)%} }
|
||||
close($c);
|
||||
die qq{no total line in coverage.out\n} unless defined $total;
|
||||
printf qq{Total coverage: %s%%\n}, $total;
|
||||
exit($total < 80 ? 1 : 0);
|
||||
'
|
||||
|
||||
release:
|
||||
runs-on: fedora
|
||||
timeout-minutes: 15
|
||||
needs: gates
|
||||
permissions:
|
||||
# contents: read is required for the checkout: a job that declares any
|
||||
# permissions gets a token scoped to exactly those, and releases: write
|
||||
# alone leaves the fetch with no read access, which Gitea answers with
|
||||
# a 404 "Repository not found". Verified on the instance 2026-09-16.
|
||||
contents: read
|
||||
releases: write
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- name: Install Perl
|
||||
# The runner images are minimal and Perl is not guaranteed. The install is a
|
||||
# no-op where it is already present; drop this step once verified on the box.
|
||||
run: dnf install -y perl
|
||||
|
||||
- name: Extract the CHANGELOG section
|
||||
env:
|
||||
VERSION: ${{ gitea.ref_name }}
|
||||
run: |
|
||||
# Each step derives what it needs from the tag, so no value has to travel between
|
||||
# jobs. The separator after the version is never read, so the heading format's
|
||||
# separator stays free.
|
||||
# Each step derives what it needs from the tag, so no value has to travel
|
||||
# between steps.
|
||||
perl -e '
|
||||
my $v = $ENV{VERSION} // q{};
|
||||
$v =~ s{^v}{};
|
||||
@@ -150,8 +78,8 @@ jobs:
|
||||
open(my $in, q{<:raw}, q{release-body.md}) or die qq{release-body.md: $!};
|
||||
my $body = do { local $/; <$in> };
|
||||
close($in);
|
||||
# Byte-oriented escaping: JSON is UTF-8, so non-ASCII passes through and only the
|
||||
# characters JSON forbids are rewritten.
|
||||
# Byte-oriented escaping: JSON is UTF-8, so non-ASCII passes through and
|
||||
# only the characters JSON forbids are rewritten.
|
||||
$body =~ s/([\\"])/\\$1/g;
|
||||
$body =~ s/\t/\\t/g;
|
||||
$body =~ s/\r//g;
|
||||
@@ -188,5 +116,5 @@ jobs:
|
||||
close($r);
|
||||
$code eq q{201} or die qq{ERROR: the release was not created, HTTP $code: $body\n};
|
||||
$body =~ m{"id"\s*:\s*([0-9]+)} or die qq{ERROR: no release id in the response: $body\n};
|
||||
print qq{release id $1\n};
|
||||
print qq{release v$ENV{VERSION} is live (id $1)\n};
|
||||
'
|
||||
|
||||
Reference in New Issue
Block a user