release.yml stopped running with the GitHub account, and nothing replaced
it: no tag has been cut since, so the publish job had nothing to build.
This ports its decision unchanged -- release only when main has commits
since the newest published release, and only if the tag does not already
exist -- to a job run by a Monday 09:17 UTC pipeline schedule. The schedule
lives on the project and sets RELEASE_WEEKLY=1; DRY_RUN=1 stops after the
decision.
The release, and so the tag, is created with a project access token rather
than the job token. That makes the tag an ordinary push, which starts the
tag pipeline and its publish job, replacing release.yml's direct call of
publish.yml. The checks are skipped in the release pipeline, as they were
on GitHub: main has already passed them.
publish.yml passed the computed version into the image build, and the
first port of it to GitLab CI did not. A tag pushed with that port would
have shipped an image reporting itself unversioned (or, for ihasvpn, with a
stray leading "v" no earlier build had), and tagged it with the git tag
rather than the version string.
The version is now computed the way publish.yml computed it and passed as
the build arg, and the image is tagged with it, '+' turned into '-' where a
Docker tag needs that.
The proxy test failed with ECONNREFUSED on 127.0.0.1 for a server bound
to ::1. That is not resolution order, so --dns-result-order was treating
the wrong cause and is removed: with no non-loopback IPv6 address on the
container, getaddrinfo's AI_ADDRCONFIG drops ::1 from the results
altogether and localhost can only ever come back IPv4.
The runner now puts jobs on a docker network created with --ipv6, which
is where the fix belongs. Verified by reproducing the failure on the old
network and watching it pass on the new one.
Three tests failed on the runner and pass locally, all because the job
container differs from a workstation rather than because anything
regressed: config.test.ts chmods a directory and expects the write to be
refused, which root ignores; imageproxy.test.ts binds to ::1 and asks for
localhost, which resolves to IPv4 first here; and version.test.ts shells
out to git, which the slim image does not ship.
So the job installs git, runs the suite as the image's unprivileged node
user, and asks Node for the address order the proxy test was written
against. No test changed.
GitHub Actions stopped being reachable when the account was suspended, so
this ports ci.yml and publish.yml to a .gitlab-ci.yml running on a group
runner on Web_Host. The Actions workflows stay in the tree: they are the
reference this was written from, and they work again unchanged if the
appeal succeeds.
Two differences worth knowing. Images are pinned by digest rather than the
workflows' SHA-pinned actions, because GitLab has no action allowlist to
back a tag with. And arm64 is built under QEMU instead of on a native
runner, which is slow enough that publish is tag-only.