Release / tsunagi-linux-aarch64 (push) Canceled after 35s
Release / tsunagi-linux-x86_64 (push) Canceled after 0s
Release / tsunagi-macos-aarch64 (push) Canceled after 0s
Release / tsunagi-windows-x86_64 (push) Canceled after 0s
Release / Publish release (push) Canceled after 0s
The github.server_url guard did not keep this workflow from running on Gitea: Gitea reports github.server_url as https://github.com, so the condition was true there too and the jobs ran (and would fail on @v4/gh). Switch both job guards to `vars.GITHUB_RELEASE == 'true'`, a repository variable set only in the GitHub repo's settings. It is deterministic: absent on Gitea, so the jobs skip there and the .gitea workflow is the one that runs; present on GitHub once configured, so it runs there. The header documents how to set it (Settings → Secrets and variables → Actions → Variables → GITHUB_RELEASE=true). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
193 lines
6.7 KiB
YAML
193 lines
6.7 KiB
YAML
name: Release
|
|
|
|
# GitHub version of the release pipeline. The build half mirrors the Gitea one
|
|
# in .gitea/workflows/release.yml (static musl Linux via cargo-zigbuild, native
|
|
# macOS and Windows); only the publish half differs: GitHub needs the v4
|
|
# artifact backend and fills the release with `gh`.
|
|
#
|
|
# Gitea reads both .gitea/workflows and .github/workflows, so without a guard it
|
|
# would also try to run this file and fail on @v4 and `gh`. (Gitea reports
|
|
# github.server_url as https://github.com, so that cannot tell the two apart.)
|
|
# Instead every job is gated on a repository variable GITHUB_RELEASE=true, which
|
|
# is set only in the GitHub repository's settings — so on Gitea, where it is
|
|
# absent, these jobs are skipped and the .gitea file is the one that runs.
|
|
#
|
|
# To enable on GitHub: Settings → Secrets and variables → Actions → Variables →
|
|
# New variable, name GITHUB_RELEASE, value true.
|
|
on:
|
|
push:
|
|
tags: ["v*"]
|
|
|
|
permissions:
|
|
contents: write
|
|
|
|
env:
|
|
CARGO_TERM_COLOR: always
|
|
CARGO_NET_RETRY: "10"
|
|
|
|
jobs:
|
|
build:
|
|
name: ${{ matrix.asset }}
|
|
if: ${{ vars.GITHUB_RELEASE == 'true' }}
|
|
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.
|
|
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 as a run artifact
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: ${{ matrix.asset }}
|
|
path: ${{ matrix.asset }}-*.*
|
|
if-no-files-found: error
|
|
|
|
publish:
|
|
name: Publish release
|
|
needs: build
|
|
if: ${{ vars.GITHUB_RELEASE == 'true' }}
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: write
|
|
steps:
|
|
- name: Download every build artifact
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
path: artifacts
|
|
|
|
- name: Show what was collected
|
|
run: find artifacts -type f
|
|
|
|
- name: Create the release and upload the archives
|
|
shell: bash
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
TAG: ${{ github.ref_name }}
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
# download-artifact@v4 nests each artifact under its own directory, so
|
|
# the archives are artifacts/<asset>/<file>.
|
|
mapfile -t files < <(find artifacts -type f \( -name '*.tar.gz' -o -name '*.zip' \))
|
|
printf 'asset: %s\n' "${files[@]}"
|
|
|
|
prerelease=()
|
|
case "$TAG" in *-*) prerelease=(--prerelease) ;; esac
|
|
|
|
# Create the release on the first run; on a re-run, add/replace assets
|
|
# on the release that is already there.
|
|
if gh release view "$TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
|
|
gh release upload "$TAG" "${files[@]}" --repo "$GITHUB_REPOSITORY" --clobber
|
|
else
|
|
gh release create "$TAG" "${files[@]}" \
|
|
--repo "$GITHUB_REPOSITORY" \
|
|
--title "tsunagi $TAG" \
|
|
--generate-notes \
|
|
--verify-tag \
|
|
"${prerelease[@]}"
|
|
fi
|