Nightly Build / build (push) Canceled after 6m16s
Cargo decides freshness by mtime, and the Gitea runner deletes the job workspace after each run. So `actions/checkout` stamped every source file with "now" and all 20 workspace crates recompiled regardless of what the commit touched: measured on a JS-only commit, 20 of 722 rlibs rebuilt — the ~700 third-party deps stayed cached, our own code never did. That, not the size of skald-core, was the 4 minutes per architecture. Restore mtimes from git history after checkout (needs the full history, hence fetch-depth: 0 — cheap here, ~170 commits against a Gitea instance on the same machine). Also: - nightly: CARGO_INCREMENTAL=1. Release builds have incremental off by default, the worst case for a 51k-line crate. The nightly trades a marginally less optimised binary for the rebuild time; release does not. - nightly: concurrency with cancel-in-progress. The runner has capacity 1 and the nightly publishes to a fixed filename, so a queued build was 8 minutes spent on a tarball the next one overwrites. - release: its own CARGO_TARGET_DIR. CARGO_INCREMENTAL is part of cargo's profile fingerprint, so one shared cache between a workflow that sets it and one that does not would have each invalidate the other's workspace crates — reintroducing the very rebuild this removes. - packaging steps derive --target-dir from $CARGO_TARGET_DIR instead of repeating the path, so the two cannot drift.
117 lines
5.0 KiB
YAML
117 lines
5.0 KiB
YAML
name: Nightly Build
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- main
|
|
|
|
# A push that lands while a nightly is still building makes that build obsolete:
|
|
# the nightly publishes to a fixed filename, so only the last one survives
|
|
# anyway. The runner has capacity 1, so without this a second push waits out a
|
|
# full 8-minute build whose tarball is overwritten minutes later. Cancelling
|
|
# keeps the queue one deep and the published nightly always the newest commit.
|
|
concurrency:
|
|
group: nightly
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
build:
|
|
runs-on: linux-amd64
|
|
|
|
env:
|
|
CARGO_TARGET_DIR: /home/dguiducci/.cache/skald-ci/target
|
|
# Release builds have incremental compilation OFF by default, which is the
|
|
# worst case for this tree: skald-core is 51k lines in one crate, so a
|
|
# one-line change recodegens all of it. The nightly trades a marginally
|
|
# less optimised binary for the rebuild time. The release workflow
|
|
# deliberately does NOT set this — there the binary quality wins.
|
|
CARGO_INCREMENTAL: 1
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
# `git restore-mtime` dates each file from the last commit that
|
|
# touched it, so it needs the full history. A shallow clone would date
|
|
# every file at HEAD and defeat the whole point. Cheap here: ~170
|
|
# commits, and the Gitea instance runs on this same machine.
|
|
fetch-depth: 0
|
|
|
|
# Cargo decides what to recompile by mtime, and the runner deletes the job
|
|
# workspace after every run — so a fresh clone stamps every source file
|
|
# with "now" and all 20 workspace crates rebuild even on a commit that
|
|
# only touched web/*.js. Measured: 20 of 722 rlibs rebuilt on a JS-only
|
|
# commit, i.e. the ~700 third-party deps stay cached and our own code
|
|
# never does. Restoring mtimes from git history is what makes
|
|
# CARGO_TARGET_DIR actually cache the workspace and not just the deps.
|
|
#
|
|
# Consequence to respect: do NOT reuse this target dir to rebuild an older
|
|
# commit. Mtimes would go backwards and cargo could treat artifacts built
|
|
# from newer code as fresh. Use a separate CARGO_TARGET_DIR for that.
|
|
- name: Restore source mtimes from git history
|
|
run: git restore-mtime
|
|
|
|
- name: Build native (linux/amd64)
|
|
run: |
|
|
RUSTFLAGS="-A warnings" cargo build --release --no-default-features
|
|
RUSTFLAGS="-A warnings" cargo build --release --no-default-features -p skald-setup
|
|
|
|
- name: Cross-compile (linux/arm64)
|
|
env:
|
|
CC_aarch64_unknown_linux_gnu: aarch64-linux-gnu-gcc
|
|
AR_aarch64_unknown_linux_gnu: aarch64-linux-gnu-ar
|
|
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
|
|
run: |
|
|
RUSTFLAGS="-A warnings" cargo build --release --no-default-features --target aarch64-unknown-linux-gnu
|
|
RUSTFLAGS="-A warnings" cargo build --release --no-default-features -p skald-setup --target aarch64-unknown-linux-gnu
|
|
|
|
- name: Package amd64
|
|
run: |
|
|
cd "${GITHUB_WORKSPACE:-.}"
|
|
./ci/package.sh \
|
|
--version nightly \
|
|
--os linux \
|
|
--arch amd64 \
|
|
--target-dir "$CARGO_TARGET_DIR/release" \
|
|
--output dist/
|
|
|
|
- name: Package arm64
|
|
run: |
|
|
cd "${GITHUB_WORKSPACE:-.}"
|
|
./ci/package.sh \
|
|
--version nightly \
|
|
--os linux \
|
|
--arch arm64 \
|
|
--target-dir "$CARGO_TARGET_DIR/aarch64-unknown-linux-gnu/release" \
|
|
--output dist/
|
|
|
|
- name: Deploy to builds.skaldagent.net
|
|
run: |
|
|
cd "${GITHUB_WORKSPACE:-.}"
|
|
DEST=/var/www/builds.skaldagent.net/nightly
|
|
mkdir -p "$DEST"
|
|
# Nightly reuses a fixed filename, so publish atomically: copy to a
|
|
# temp name on the same filesystem, then rename over the target. A
|
|
# concurrent download never sees a half-written tarball.
|
|
for f in dist/*.tar.gz; do
|
|
name="$(basename "$f")"
|
|
cp "$f" "$DEST/.$name.tmp"
|
|
mv -f "$DEST/.$name.tmp" "$DEST/$name"
|
|
done
|
|
echo "[nightly] Deployed:"
|
|
ls -lh "$DEST/"
|
|
|
|
- name: Publish the nightly installer
|
|
run: |
|
|
cd "${GITHUB_WORKSPACE:-.}"
|
|
# install-nightly.sh is served straight from the web root
|
|
# (curl -fsSL https://builds.skaldagent.net/install-nightly.sh | bash),
|
|
# so without this it stays whatever was copied there by hand and drifts
|
|
# from the repo — a fix to the installer would reach every existing box
|
|
# through update.sh but never a new one. Same atomic publish as the
|
|
# tarballs: a client mid-download never sees a half-written script.
|
|
ROOT=/var/www/builds.skaldagent.net
|
|
cp install-nightly.sh "$ROOT/.install-nightly.sh.tmp"
|
|
chmod 644 "$ROOT/.install-nightly.sh.tmp"
|
|
mv -f "$ROOT/.install-nightly.sh.tmp" "$ROOT/install-nightly.sh"
|
|
echo "[nightly] Published install-nightly.sh"
|