87 lines
3.4 KiB
Makefile
87 lines
3.4 KiB
Makefile
# Repetitive workflows. Anything a release or a review runs twice belongs here,
|
|
# so a step cannot be forgotten by hand (v0.0.7 first failed on an unbumped
|
|
# build.zig.zon that only verify-dist caught, one CI round too late).
|
|
|
|
repo := "mokhtar/nxdns"
|
|
forge := "https://git.mial.net"
|
|
|
|
# every recipe, described
|
|
default:
|
|
@just --list
|
|
|
|
# unit suite
|
|
test:
|
|
zig build test
|
|
|
|
# unit + integration suite
|
|
itest:
|
|
zig build test -Dintegration
|
|
|
|
# admin: typecheck, tests, lint, formatting
|
|
admin-check:
|
|
cd admin && npx tsc -b && npx vitest run && npx oxlint && npx prettier --check .
|
|
|
|
# regenerate the contract goldens from live responses
|
|
goldens:
|
|
zig build test -Dintegration -Dcontract-samples-out="{{justfile_directory()}}/admin/src/lib/contractSamples.gen.ts"
|
|
|
|
# the binary with the real admin UI embedded (the default build embeds a placeholder)
|
|
build:
|
|
cd admin && npm run build
|
|
zig build -Dadmin-dist=admin/dist
|
|
|
|
# everything CI gates on, locally
|
|
verify: test itest admin-check
|
|
zig fmt --check src/ tools/
|
|
|
|
# cut a release: preflight, bump, push, wait for CI, signed tag, watch the run.
|
|
# Requires: clean tree, master, CHANGELOG section for the version already written.
|
|
release version:
|
|
#!/usr/bin/env sh
|
|
set -eu
|
|
v="{{version}}"
|
|
[ -z "$(git status --porcelain)" ] || { echo "release: tree is dirty"; exit 1; }
|
|
[ "$(git branch --show-current)" = "master" ] || { echo "release: not on master"; exit 1; }
|
|
grep -q "^## \[$v\]" CHANGELOG.md || { echo "release: CHANGELOG.md has no ## [$v] section"; exit 1; }
|
|
git ls-remote --exit-code --tags origin "v$v" >/dev/null 2>&1 && { echo "release: tag v$v already on origin"; exit 1; }
|
|
if ! grep -q "\.version = \"$v\"" build.zig.zon; then
|
|
sed -i "s/\.version = \"[^\"]*\"/.version = \"$v\"/" build.zig.zon
|
|
grep -q "\.version = \"$v\"" build.zig.zon || { echo "release: version bump failed"; exit 1; }
|
|
git add build.zig.zon
|
|
git commit -S -m "build: bump version to $v"
|
|
fi
|
|
git push origin master
|
|
sha=$(git rev-parse HEAD)
|
|
echo "release: waiting for CI on $sha"
|
|
while :; do
|
|
state=$(curl -sf "{{forge}}/api/v1/repos/{{repo}}/commits/$sha/status" | python3 -c "import json,sys; print(json.load(sys.stdin).get('state') or 'pending')") || state=pending
|
|
case "$state" in
|
|
success) break ;;
|
|
pending) sleep 30 ;;
|
|
*) echo "release: CI is $state on $sha — not tagging"; exit 1 ;;
|
|
esac
|
|
done
|
|
git tag -s "v$v" -m "v$v" "$sha"
|
|
git push origin "v$v"
|
|
echo "release: tag v$v pushed, watching the release run"
|
|
while :; do
|
|
line=$(curl -sf "{{forge}}/api/v1/repos/{{repo}}/actions/runs?limit=10" | python3 -c "
|
|
import json,sys
|
|
for r in json.load(sys.stdin).get('workflow_runs', []):
|
|
if r.get('path','').startswith('release.yml') and r.get('head_sha') == '$sha':
|
|
print(r.get('status',''), r.get('conclusion','') or ''); break
|
|
") || line=""
|
|
set -- $line ""
|
|
if [ "${1:-}" = "completed" ]; then
|
|
[ "$2" = "success" ] || { echo "release: workflow concluded $2 — read the publish job log"; exit 1; }
|
|
break
|
|
fi
|
|
sleep 60
|
|
done
|
|
curl -sf "{{forge}}/api/v1/repos/{{repo}}/releases/tags/v$v" | python3 -c "
|
|
import json,sys
|
|
d = json.load(sys.stdin)
|
|
print('release: published', d['tag_name'], 'with', len(d.get('assets', [])), 'assets')
|
|
for a in d.get('assets', []): print(' ', a['name'])
|
|
"
|