Answer stability round 1: 0 🔴, 3 🟡; fail when the latest release can't be read, build every platform's binaries when Go changes, and test main() and the Unreleased heading

This commit is contained in:
2026-10-13 23:53:53 +02:00
committed by Lillem4n
parent a82279c6a4
commit b9ae602399
5 changed files with 38 additions and 21 deletions
+2 -1
View File
@@ -66,7 +66,8 @@ jobs:
GH_TOKEN: ${{ github.token }} GH_TOKEN: ${{ github.token }}
TAG: ${{ inputs.tag }} TAG: ${{ inputs.tag }}
run: | run: |
if [ "$(gh release view --repo "$GITHUB_REPOSITORY" --json tagName --jq .tagName)" = "$TAG" ]; then latest="$(gh release view --repo "$GITHUB_REPOSITORY" --json tagName --jq .tagName)"
if [ "$latest" = "$TAG" ]; then
echo "latest=true" >> "$GITHUB_OUTPUT" echo "latest=true" >> "$GITHUB_OUTPUT"
else else
echo "skip=--skip=homebrew,scoop,aur" >> "$GITHUB_OUTPUT" echo "skip=--skip=homebrew,scoop,aur" >> "$GITHUB_OUTPUT"
+1 -1
View File
@@ -32,7 +32,7 @@ jobs:
else else
echo "code=true" >> "$GITHUB_OUTPUT" echo "code=true" >> "$GITHUB_OUTPUT"
fi fi
if git diff --quiet "$base"...HEAD -- release-tooling Dockerfile .dockerignore LICENSE DATA-LICENSES.md .github/workflows/packages.yml .github/workflows/test.yml; then if git diff --quiet "$base"...HEAD -- '*.go' go.mod go.sum release-tooling Dockerfile .dockerignore LICENSE DATA-LICENSES.md .github/workflows/packages.yml .github/workflows/test.yml; then
echo "packaging=false" >> "$GITHUB_OUTPUT" echo "packaging=false" >> "$GITHUB_OUTPUT"
else else
echo "packaging=true" >> "$GITHUB_OUTPUT" echo "packaging=true" >> "$GITHUB_OUTPUT"
+4 -3
View File
@@ -1219,9 +1219,10 @@ docker build --build-arg GO_VERSION=1.22.12 --target portable . # lowest support
GO_VERSION=1.22.12 docker compose run --rm test # the same tests, without the image build GO_VERSION=1.22.12 docker compose run --rm test # the same tests, without the image build
``` ```
A change to `release-tooling/`, the `Dockerfile`, `.dockerignore`, the licence files or A change to Go code, `release-tooling/`, the `Dockerfile`, `.dockerignore`, the licence
either workflow also builds the apt, dnf and apk repositories from snapshot packages, files or either workflow also builds the release binaries for every platform, the apt, dnf
signs them with throwaway keys, and installs fejkdata from each: and apk repositories from their packages, signed with throwaway keys, and installs
fejkdata from each:
```sh ```sh
docker build -f release-tooling/package-repos.Dockerfile --target throwaway-keys --output /tmp/fejkdata-keys . docker build -f release-tooling/package-repos.Dockerfile --target throwaway-keys --output /tmp/fejkdata-keys .
+1 -5
View File
@@ -1,8 +1,4 @@
# The apt, dnf and apk repositories GitHub Pages serves, signed, from the .deb, .rpm and # A release's packages replace the snapshot ones through `--build-context packages=<dir>`.
# .apk files of the `packages` stage: a snapshot built from the source here, or a release's
# when `--build-context packages=<dir>` replaces it. The checks target installs fejkdata
# from each repository, and where EXPECTED_VERSION is set, checks it prints that tag; the
# README's Development section shows the commands.
ARG BASE_URL=https://larvit.github.io/fejkdata ARG BASE_URL=https://larvit.github.io/fejkdata
ARG EXPECTED_VERSION ARG EXPECTED_VERSION
+30 -11
View File
@@ -16,6 +16,19 @@ def not_found(path):
return urllib.error.HTTPError(path, 404, "Not Found", None, None) return urllib.error.HTTPError(path, 404, "Not Found", None, None)
def forge(responses, created):
def request(path, data=None):
if data is not None:
created.append(data)
return {"html_url": "https://forge.example/release"}
response = responses.get(path)
if response is None:
raise not_found(path)
return response
return request
class TagGuard(unittest.TestCase): class TagGuard(unittest.TestCase):
def setUp(self): def setUp(self):
cwd = os.getcwd() cwd = os.getcwd()
@@ -31,17 +44,7 @@ class TagGuard(unittest.TestCase):
def publish(self, responses): def publish(self, responses):
created = [] created = []
with mock.patch.object(publish_release, "request", forge(responses, created)), \
def request(path, data=None):
if data is not None:
created.append(data)
return {"html_url": "https://forge.example/release"}
response = responses.get(path)
if response is None:
raise not_found(path)
return response
with mock.patch.object(publish_release, "request", request), \
redirect_stdout(io.StringIO()), redirect_stderr(io.StringIO()): redirect_stdout(io.StringIO()), redirect_stderr(io.StringIO()):
code, self.tag = publish_release.publish() code, self.tag = publish_release.publish()
return code, created return code, created
@@ -70,6 +73,22 @@ class TagGuard(unittest.TestCase):
self.assertEqual(created, [{"body": "- A change.", "name": "v1.2.3", "tag_name": "v1.2.3", "target_commitish": SHA}]) self.assertEqual(created, [{"body": "- A change.", "name": "v1.2.3", "tag_name": "v1.2.3", "target_commitish": SHA}])
self.assertEqual(self.tag, "v1.2.3") self.assertEqual(self.tag, "v1.2.3")
def test_an_unreleased_heading_publishes_nothing(self):
with open("CHANGELOG.md", "w", encoding="utf-8") as f:
f.write("# Changelog\n\n## [Unreleased]\n\n- A change.\n")
code, created = self.publish({})
self.assertEqual((code, created, self.tag), (0, [], None))
def test_main_names_only_a_published_tag_to_ci(self):
for responses, output in (({}, "tag=v1.2.3\n"), ({"releases/tags/v1.2.3": {"html_url": "https://forge.example/release"}}, "")):
open("output", "w").close()
with mock.patch.dict(os.environ, {"GITHUB_OUTPUT": os.path.abspath("output")}), \
mock.patch.object(publish_release, "request", forge(responses, [])), \
redirect_stdout(io.StringIO()):
self.assertEqual(publish_release.main(), 0)
with open("output", encoding="utf-8") as f:
self.assertEqual(f.read(), output)
def test_a_published_release_publishes_nothing(self): def test_a_published_release_publishes_nothing(self):
code, created = self.publish({"releases/tags/v1.2.3": {"html_url": "https://forge.example/release"}}) code, created = self.publish({"releases/tags/v1.2.3": {"html_url": "https://forge.example/release"}})
self.assertEqual((code, created, self.tag), (0, [], None)) self.assertEqual((code, created, self.tag), (0, [], None))