Files
noitu/.github/workflows/proto.yml
T
tiennm99 b2cad42b0c build: package the game as a container image and wire CI
One distroless image of about 25 MB carries the binary, the built frontend and
the derived dictionary. The 179 MB upstream release is downloaded in a builder
stage and never reaches the final image; the derived wordlist is copied in as
its own layer alongside its licence, attribution and notice, because CC BY-SA
4.0 applies wherever that data is distributed and an image is distribution.

FIXTURE_DICT=1 builds the same Dockerfile against the checked-in word sample,
so the image is built and smoke-tested on every push rather than only at
release. An image built only at release time is an image that breaks at release
time.

CI runs the Go suite under race detection, the frontend type check and tests,
the browser suite, and the image with its licence assertions. The wire contract
keeps its own workflow; the test steps it duplicated were removed from it.

docs/deployment.md covers configuration, the reverse-proxy settings that each
break the game in a way that looks like something else, and what a restart
costs.
2026-09-05 14:18:18 +07:00

75 lines
2.5 KiB
YAML

# Guards the WebSocket wire contract: the schema is well-formed, it has not
# broken compatibility, and the committed generated code matches it.
#
# The suites that decode the cross-language fixtures run in ci.yml, where the
# rest of the tests are. Nothing here downloads the 179 MB upstream dictionary.
name: proto
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
jobs:
contract:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
# buf breaking compares against main, which needs real history.
fetch-depth: 0
- uses: bufbuild/buf-setup-action@v1
with:
version: 1.69.0
- uses: actions/setup-go@v5
with:
go-version-file: server/go.mod
cache-dependency-path: server/go.sum
- uses: actions/setup-node@v4
with:
node-version: 24
cache: npm
cache-dependency-path: web/package-lock.json
- run: npm ci
working-directory: web
- name: Lint the schema
run: buf lint
# Skipped only until this contract first lands on main; after that the
# baseline always exists and the check is unconditional.
- name: Look for a breaking-change baseline on main
id: baseline
run: |
if git cat-file -e origin/main:proto/noitu/v1/game.proto 2>/dev/null; then
echo "exists=true" >> "$GITHUB_OUTPUT"
else
echo "exists=false" >> "$GITHUB_OUTPUT"
echo "::notice::no schema on main yet, skipping the breaking-change check"
fi
# ref=origin/main, not branch=main: a pull_request checkout is a detached
# HEAD with no local main, and branch=main fails there with a git clone
# error rather than a breaking-change report.
- name: Reject breaking changes
if: steps.baseline.outputs.exists == 'true'
run: buf breaking --against '.git#ref=origin/main'
# A committed generated tree that no longer matches the schema is worse
# than no generated tree at all: it compiles, and it is wrong.
# --intent-to-add first: git diff ignores untracked files, so without it
# a plugin that starts emitting a new file passes this check while the
# committed tree is incomplete.
- name: Verify the committed generated code is in sync
run: |
buf generate
git add --intent-to-add -- server/gen web/src/lib/proto
git diff --exit-code -- server/gen web/src/lib/proto