Release
successSet up job
successactions/checkout@v4 1s
successResolve the tag 2s
set -euo pipefail
# Every variable here is read with a default: this runner does not
# set GITHUB_REF_TYPE, and under `set -u` one missing name is a dead
# job three steps before anything interesting happens.
REF="${GITHUB_REF:-}"
if [ -n "${INPUT_TAG:-}" ]; then
TAG="$INPUT_TAG"
else
case "$REF" in
refs/tags/*) TAG="${REF#refs/tags/}" ;;
*)
# A dispatch: no tag in the ref, so ask the API for the newest.
TAG=$(curl -sSfL -H "Authorization: Bearer $GITHUB_TOKEN" \
"$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/tags" \
| python3 -c "import json,sys; ts=[t['name'] for t in json.load(sys.stdin) if t['name'].startswith('v')]; print(ts[0] if ts else '')")
;;
esac
fi
case "$TAG" in
v*) ;;
*) echo "refusing to release '$TAG': not a v* tag" >&2; exit 1 ;;
esac
# The runner hands a tag build the right tree already; a dispatch
# gets whatever branch it ran on, so move only when we can.
if [ -d .git ]; then
git checkout --detach "$TAG" 2>/dev/null || echo "note: building the checked-out tree, not $TAG"
fi
echo "releasing $TAG"
echo "TAG=$TAG" >> "$GITHUB_ENV"
successInstall Nim and zig 3s
set -euo pipefail
mkdir -p "$HOME/toolchains"
curl -sSfL "https://nim-lang.org/download/nim-${NIM_VERSION}-linux_x64.tar.xz" \
| tar -xJ -C "$HOME/toolchains"
curl -sSfL "https://ziglang.org/download/${ZIG_VERSION}/zig-x86_64-linux-${ZIG_VERSION}.tar.xz" \
| tar -xJ -C "$HOME/toolchains"
echo "$HOME/toolchains/nim-${NIM_VERSION}/bin" >> "$GITHUB_PATH"
echo "$HOME/toolchains/zig-x86_64-linux-${ZIG_VERSION}" >> "$GITHUB_PATH"
successVersions <1s
nim --version | head -1 zig version
successactions/cache@v4 <1s
successTest 2s
nim c -d:ssl --hints:off -r tests/test_nimstatic.nim
successBootstrap nimstatic on the host 3s
nim c -d:release -d:ssl --hints:off -o:nimstatic-host src/nimstatic.nim
successBuild the static binary with itself 13s
set -euo pipefail
VERSION="${TAG#v}"
NAME="nimstatic-${VERSION}-x86_64-linux"
./nimstatic-host src/nimstatic.nim -o "$NAME" -- -d:ssl --passL:-s
# Neither file(1) nor ldd is on the runner image, and `ldd … | grep`
# fails silently when ldd is missing — the pipe eats the error and
# grep just finds nothing. Read the ELF program headers instead: a
# PT_INTERP entry (type 3) is what makes a binary dynamic.
python3 -c "import struct,sys;d=open(sys.argv[1],'rb').read();assert d[:4]==b'\x7fELF';off=struct.unpack_from('<Q',d,0x20)[0];esz=struct.unpack_from('<H',d,0x36)[0];n=struct.unpack_from('<H',d,0x38)[0];t=[struct.unpack_from('<I',d,off+i*esz)[0] for i in range(n)];sys.exit('dynamic: has PT_INTERP' if 3 in t else 0)" "$NAME"
./"$NAME" --help > /dev/null
xz -9e -k "$NAME"
sha256sum "$NAME" "$NAME.xz" > SHA256SUMS
cat SHA256SUMS
echo "NAME=$NAME" >> "$GITHUB_ENV"
successAttach the binaries to the release 3s
set -euo pipefail
api() { curl -sSfL -H "Authorization: Bearer $GITHUB_TOKEN" \
-H "Accept: application/vnd.github+json" "$@"; }
field() { python3 -c "import json,sys; print(json.load(sys.stdin).get(sys.argv[1],''))" "$1"; }
if ! api "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/releases/tags/$TAG" > release.json; then
api -X POST "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/releases" \
-d "{\"tag_name\":\"$TAG\",\"name\":\"nimstatic $TAG\"}" > release.json
fi
# Prefer the upload_url the API advertises; fall back to the
# id-based path when this forge does not send one.
upload_url=$(field upload_url < release.json | cut -d'{' -f1)
if [ -z "$upload_url" ]; then
release_id=$(field id < release.json)
[ -n "$release_id" ] || { echo "no release id in:"; cat release.json; exit 1; }
upload_url="$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/releases/$release_id/assets"
fi
echo "uploading to $upload_url"
for asset in "$NAME" "$NAME.xz" SHA256SUMS; do
# Replace an asset of the same name, so a re-run is idempotent.
existing=$(python3 -c "import json,sys; print(next((a['url'] for a in (json.load(open('release.json')).get('assets') or []) if a['name']==sys.argv[1]),''))" "$asset")
if [ -n "$existing" ]; then
api -X DELETE "$existing" > /dev/null
fi
api -X POST "$upload_url?name=$asset" \
-H "Content-Type: application/octet-stream" \
--data-binary "@$asset" > /dev/null
echo "uploaded $asset"
done
successactions/upload-artifact@v4 5s
Post actions/cache@v4
No test reports for this run.
Tell a job where its test runner writes its report and this tab fills in: how many tests passed, failed and were skipped, a bar of the result at a glance, then every failure first — with the assertion that failed and the output around it — over a per-suite list of cases and their durations. No scrolling a log for the word FAIL.
It is one reports: key on the job — a job key, not a step, so the report is collected whatever the job concluded. JUnit XML and go test -json are both understood, and most runners already emit one of them. reports: is a rickub extension and works only in .rickub/workflows/; in .github/workflows/ it is a parse error on purpose, because those files are also meant to run on github.com.