name: Release on: push: branches: - release pull_request: branches: - release jobs: # ── PR check: verify the version is not already built ─────────────────────── verify-version: if: github.event_name == 'pull_request' runs-on: linux-amd64 steps: - uses: actions/checkout@v4 - name: Verify version is new run: ./ci/verify-version.sh --builds-dir /var/www/builds.skaldagent.net # ── Push/merge: build, package, and deploy the release ────────────────────── release: if: github.event_name == 'push' runs-on: linux-amd64 outputs: version: ${{ steps.extract-version.outputs.version }} env: # Deliberately NOT the nightly's target dir. No CARGO_INCREMENTAL here — # a release binary is the one people install, so it gets the fully # optimised non-incremental build — and that flag is part of cargo's # profile fingerprint. Sharing one cache between a workflow that sets it # and one that doesn't would make each run invalidate the other's # workspace crates, which is exactly the cost this whole change removes. CARGO_TARGET_DIR: /home/dguiducci/.cache/skald-ci/target-release steps: - uses: actions/checkout@v4 with: # Full history: `git restore-mtime` below dates each file from the # last commit that touched it. fetch-depth: 0 # See the long note in nightly.yml: the runner wipes the job workspace # after every run, so without this every source file is stamped "now" on # checkout and all 20 workspace crates rebuild from scratch regardless of # what the commit changed. This is what lets CARGO_TARGET_DIR cache our # own crates and not just the ~700 third-party deps. - name: Restore source mtimes from git history run: git restore-mtime - name: Extract version from Cargo.toml id: extract-version run: | VER="v$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/')" echo "version=$VER" >> "$GITHUB_OUTPUT" echo "[release] Building version $VER" # Also run verify-version on push to catch any race (belt-and-suspenders) - name: Verify version is new run: ./ci/verify-version.sh --builds-dir /var/www/builds.skaldagent.net - 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 "${{ steps.extract-version.outputs.version }}" \ --os linux \ --arch amd64 \ --target-dir "$CARGO_TARGET_DIR/release" \ --output dist/ - name: Package arm64 run: | cd "${GITHUB_WORKSPACE:-.}" ./ci/package.sh \ --version "${{ steps.extract-version.outputs.version }}" \ --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:-.}" VERSION="${{ steps.extract-version.outputs.version }}" TARGET="/var/www/builds.skaldagent.net/releases/${VERSION}" mkdir -p "$TARGET" # Publish each tarball atomically (temp name + rename) so a client can # never fetch a half-written file. for f in dist/*.tar.gz; do name="$(basename "$f")" cp "$f" "$TARGET/.$name.tmp" mv -f "$TARGET/.$name.tmp" "$TARGET/$name" done echo "[release] Deployed $VERSION:" ls -lh "$TARGET/" - name: Update latest version pointer run: | VERSION="${{ steps.extract-version.outputs.version }}" DEST=/var/www/builds.skaldagent.net/releases # Flip LATEST atomically — install.sh/update.sh read it to decide # whether to upgrade, so it must never be observed empty or partial. printf '%s\n' "$VERSION" > "$DEST/.LATEST.tmp" mv -f "$DEST/.LATEST.tmp" "$DEST/LATEST" echo "[release] Updated releases/LATEST → $VERSION" - name: Publish the release installer run: | cd "${GITHUB_WORKSPACE:-.}" # install.sh is served straight from the web root # (curl -fsSL https://builds.skaldagent.net/install.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. Published here rather than on # every push so the served installer always matches a real release. ROOT=/var/www/builds.skaldagent.net cp install.sh "$ROOT/.install.sh.tmp" chmod 644 "$ROOT/.install.sh.tmp" mv -f "$ROOT/.install.sh.tmp" "$ROOT/install.sh" echo "[release] Published install.sh"