The musl release build now links cleanly through cargo-zigbuild, but rustc's new linker_messages lint echoed zig's "ignoring deprecated linker optimization setting '1'" note — zig's linker declining the -O1 GNU-ld flag Rust passes. It is cosmetic and the binary is correct, so allow that one lint, scoped to the zig build step only. macOS and Windows keep full linker diagnostics, and a real link error still fails the build. No behaviour change to the produced binaries; takes effect on the next tag. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
182 lines
6.6 KiB
YAML
182 lines
6.6 KiB
YAML
name: Release
|
|
|
|
# Build the agent for every supported target on a version tag and attach the
|
|
# archives to a release. Linux is a fully static musl binary (built with
|
|
# cargo-zigbuild) so one artifact runs on any distro — Arch, Alpine, NixOS, old
|
|
# glibc systems alike — and can then be repackaged however a distro prefers.
|
|
#
|
|
# Targeted at Gitea Actions: the release assets are uploaded straight to the
|
|
# Gitea release API with curl, rather than through actions/upload-artifact and
|
|
# `gh`, because the v4 artifact backend and the GitHub REST API are not
|
|
# available there. The only runner tools it needs are curl and coreutils.
|
|
on:
|
|
push:
|
|
tags: ["v*"]
|
|
|
|
permissions:
|
|
contents: write
|
|
|
|
env:
|
|
CARGO_TERM_COLOR: always
|
|
CARGO_NET_RETRY: "10"
|
|
|
|
jobs:
|
|
build:
|
|
name: ${{ matrix.asset }}
|
|
runs-on: ${{ matrix.os }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- os: ubuntu-latest
|
|
target: x86_64-unknown-linux-musl
|
|
asset: tsunagi-linux-x86_64
|
|
archive: tar.gz
|
|
zig: true
|
|
- os: ubuntu-latest
|
|
target: aarch64-unknown-linux-musl
|
|
asset: tsunagi-linux-aarch64
|
|
archive: tar.gz
|
|
zig: true
|
|
- os: macos-latest
|
|
target: aarch64-apple-darwin
|
|
asset: tsunagi-macos-aarch64
|
|
archive: tar.gz
|
|
zig: false
|
|
- os: windows-latest
|
|
target: x86_64-pc-windows-msvc
|
|
asset: tsunagi-windows-x86_64
|
|
archive: zip
|
|
zig: false
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
targets: ${{ matrix.target }}
|
|
|
|
- uses: Swatinem/rust-cache@v2
|
|
with:
|
|
key: ${{ matrix.target }}
|
|
|
|
# aws-lc-sys (iroh's rustls backend) and the bundled sqlite are C, and the
|
|
# musl targets have no prebuilt bindings, so bindgen needs libclang and the
|
|
# C build needs cmake. zig is the cross C compiler cargo-zigbuild drives.
|
|
- name: Install musl build tooling
|
|
if: matrix.zig
|
|
run: sudo apt-get update && sudo apt-get install -y --no-install-recommends cmake clang libclang-dev
|
|
- name: Install zig
|
|
if: matrix.zig
|
|
uses: mlugg/setup-zig@v2
|
|
with:
|
|
# Pin a real, archived Zig release. Left unpinned the action resolves
|
|
# to the newest version it knows of (a yet-unreleased 0.16.0-dev),
|
|
# whose tarball 404s on ziglang.org while the community mirrors flake.
|
|
# A concrete release always has a permanent official URL, so the
|
|
# download succeeds even if mirrors are down, and the version stays
|
|
# compatible with cargo-zigbuild.
|
|
version: 0.14.1
|
|
- name: Install cargo-zigbuild
|
|
if: matrix.zig
|
|
uses: taiki-e/install-action@v2
|
|
with:
|
|
tool: cargo-zigbuild
|
|
|
|
- name: Build
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
if [[ "${{ matrix.zig }}" == "true" ]]; then
|
|
# zig's linker ignores the `-O1` GNU-ld optimization flag Rust passes
|
|
# and says so on stderr, which rustc now surfaces as a linker_messages
|
|
# warning. It is cosmetic — the binary is correct — so quiet just that
|
|
# one lint to keep the musl build log clean. A real link error still
|
|
# fails the build.
|
|
export RUSTFLAGS="${RUSTFLAGS:-} -A linker_messages"
|
|
cargo zigbuild --release --locked --target "${{ matrix.target }}" --bin tsunagi
|
|
else
|
|
cargo build --release --locked --target "${{ matrix.target }}" --bin tsunagi
|
|
fi
|
|
|
|
- name: Package
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
version="${GITHUB_REF_NAME#v}"
|
|
stage="dist/pkg/${{ matrix.asset }}"
|
|
mkdir -p "$stage"
|
|
|
|
bin="tsunagi"
|
|
[[ "${{ runner.os }}" == "Windows" ]] && bin="tsunagi.exe"
|
|
cp "target/${{ matrix.target }}/release/${bin}" "$stage/"
|
|
|
|
# The top-level README, plus the per-OS install notes and integration
|
|
# files, so the archive carries what the platform needs to set up.
|
|
cp README.md "$stage/"
|
|
case "${{ runner.os }}" in
|
|
Linux)
|
|
cp dist/linux/tsunagi.service dist/linux/install.sh "$stage/"
|
|
cp dist/linux/README.md "$stage/INSTALL.md"
|
|
;;
|
|
macOS)
|
|
cp dist/macos/cy.hexor.tsunagi.plist "$stage/"
|
|
cp dist/macos/README.md "$stage/INSTALL.md"
|
|
;;
|
|
Windows)
|
|
cp dist/windows/README.md "$stage/INSTALL.md"
|
|
;;
|
|
esac
|
|
|
|
archive="${{ matrix.asset }}-${version}.${{ matrix.archive }}"
|
|
if [[ "${{ matrix.archive }}" == "zip" ]]; then
|
|
(cd dist/pkg && 7z a "../../${archive}" "${{ matrix.asset }}")
|
|
else
|
|
tar -C dist/pkg -czf "${archive}" "${{ matrix.asset }}"
|
|
fi
|
|
|
|
- name: Upload the archive to the release
|
|
shell: bash
|
|
env:
|
|
# Gitea injects this with write access to the current repository.
|
|
TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
run: |
|
|
set -u
|
|
|
|
version="${GITHUB_REF_NAME#v}"
|
|
archive="${{ matrix.asset }}-${version}.${{ matrix.archive }}"
|
|
tag="${GITHUB_REF_NAME}"
|
|
api="${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}"
|
|
auth="Authorization: token ${TOKEN}"
|
|
|
|
prerelease=false
|
|
case "$tag" in *-*) prerelease=true ;; esac
|
|
|
|
# The release id for this tag, or empty if there is no release yet.
|
|
# Parsed with grep so the job needs no jq on the runner image.
|
|
get_id() {
|
|
curl -fsSL -H "$auth" "$api/releases/tags/$tag" 2>/dev/null \
|
|
| grep -o '"id":[0-9]*' | head -n1 | cut -d: -f2
|
|
}
|
|
|
|
# Create the release if it is not there. Several matrix jobs can race
|
|
# here, so a create that loses the race is ignored and the id is then
|
|
# read back by tag.
|
|
id="$(get_id)"
|
|
if [ -z "$id" ]; then
|
|
curl -fsS -X POST -H "$auth" -H 'Content-Type: application/json' \
|
|
-d "{\"tag_name\":\"$tag\",\"name\":\"tsunagi $tag\",\"prerelease\":$prerelease}" \
|
|
"$api/releases" >/dev/null 2>&1 || true
|
|
id="$(get_id)"
|
|
fi
|
|
if [ -z "$id" ]; then
|
|
echo "could not create or find a release for $tag at $api" >&2
|
|
exit 1
|
|
fi
|
|
|
|
curl -fsS -X POST -H "$auth" \
|
|
-F "attachment=@${archive}" \
|
|
"$api/releases/$id/assets?name=${archive}" >/dev/null
|
|
echo "uploaded $archive to release $tag (id $id)"
|