Skip to content

release

release #10

Workflow file for this run

name: release
# Streaming release: the GitHub release is created up front, then every job
# uploads ITS artifact the moment it's built (gh release upload --clobber).
# A slow leg (aarch64/i686 under QEMU, or the windows vcpkg build) never blocks
# the release or the artifacts that are already done.
#
# Triggers:
# • pushing a tag `vX.Y.Z` → builds that tag, publishes the release
# • manual run (workflow_dispatch) → builds the chosen ref, publishes `tag`
#
# Artifacts: agentty-linux-{x86_64,aarch64,i686}, agentty-macos-{arm64,x86_64},
# agentty-windows-x86_64.exe,
# agentty_<v>_{amd64,arm64}.deb, agentty-<v>-1.{x86_64,aarch64}.rpm,
# agentty-bin-<v>-1-x86_64.pkg.tar.zst, agentty-<v>.tar.gz, SHA256SUMS.
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
tag:
description: 'Release tag to publish (e.g. v0.1.0)'
required: true
default: v0.1.0
permissions:
contents: write
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
env:
GH_TOKEN: ${{ github.token }}
jobs:
# Create/refresh the release immediately + upload the source tarball.
prepare:
name: prepare release
runs-on: ubuntu-latest
outputs:
version: ${{ steps.meta.outputs.version }}
tag: ${{ steps.meta.outputs.tag }}
steps:
- uses: actions/checkout@v4
- name: Init maya submodule (HTTPS)
run: |
git config --global url."https://github.com/".insteadOf "git@github.com:"
git submodule update --init --recursive
- name: Resolve version + tag
id: meta
run: |
V=$(grep -m1 'project(agentty' CMakeLists.txt | sed -E 's/.*VERSION ([0-9.]+).*/\1/')
echo "version=$V" >> "$GITHUB_OUTPUT"
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "tag=${{ inputs.tag }}" >> "$GITHUB_OUTPUT"
else
echo "tag=${GITHUB_REF_NAME}" >> "$GITHUB_OUTPUT"
fi
- name: Ensure release exists + upload source tarball
env:
V: ${{ steps.meta.outputs.version }}
TAG: ${{ steps.meta.outputs.tag }}
run: |
gh release view "$TAG" >/dev/null 2>&1 \
|| gh release create "$TAG" --title "$TAG" \
--notes "See [CHANGELOG.md](https://github.com/1ay1/agentty/blob/master/CHANGELOG.md)."
pipx run git-archive-all "agentty-${V}.tar.gz"
gh release upload "$TAG" "agentty-${V}.tar.gz" --clobber
build-linux:
name: linux ${{ matrix.arch }}
needs: prepare
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- arch: x86_64
platform: linux/amd64
cmarch: avx2
- arch: aarch64
platform: linux/arm64
cmarch: native
- arch: i686
platform: linux/386
cmarch: sse2
env:
TAG: ${{ needs.prepare.outputs.tag }}
steps:
- uses: actions/checkout@v4
- name: Init maya submodule (HTTPS)
run: |
git config --global url."https://github.com/".insteadOf "git@github.com:"
git submodule update --init --recursive
- name: Set up QEMU
if: matrix.platform != 'linux/amd64'
uses: docker/setup-qemu-action@v3
- name: Build static binary (Alpine 3.21 / musl / GCC 14)
run: |
docker run --rm --platform ${{ matrix.platform }} \
-e CMARCH='${{ matrix.cmarch }}' \
-v "$PWD":/src -w /src alpine:3.21 sh -c '
set -ex
apk add --no-cache build-base cmake ninja git linux-headers pkgconfig \
openssl-dev openssl-libs-static nghttp2-dev nghttp2-static zlib-static
git config --global --add safe.directory /src
rm -rf build-rel
cmake -S . -B build-rel -GNinja -DCMAKE_BUILD_TYPE=Release \
-DAGENTTY_STANDALONE=ON -DAGENTTY_FULLY_STATIC=ON \
-DAGENTTY_AUTO_PULL_MAYA=OFF -DAGENTTY_USE_MIMALLOC=OFF \
-DAGENTTY_ARCH="$CMARCH"
cmake --build build-rel -j"$(nproc)"
strip build-rel/agentty
cp build-rel/agentty agentty-linux-${{ matrix.arch }}
'
- name: Upload to release + stash for packaging
run: gh release upload "$TAG" agentty-linux-${{ matrix.arch }} --clobber
- uses: actions/upload-artifact@v4
with:
name: bin-linux-${{ matrix.arch }}
path: agentty-linux-${{ matrix.arch }}
if-no-files-found: error
build-windows:
name: windows x86_64
needs: prepare
runs-on: windows-latest
env:
TAG: ${{ needs.prepare.outputs.tag }}
steps:
- uses: actions/checkout@v4
- name: Init maya submodule (HTTPS)
shell: bash
run: |
git config --global url."https://github.com/".insteadOf "git@github.com:"
git submodule update --init --recursive
- name: Install deps (vcpkg static)
shell: pwsh
run: |
git -C "$env:VCPKG_INSTALLATION_ROOT" fetch --depth 1 origin master
git -C "$env:VCPKG_INSTALLATION_ROOT" reset --hard FETCH_HEAD
& "$env:VCPKG_INSTALLATION_ROOT\bootstrap-vcpkg.bat"
& "$env:VCPKG_INSTALLATION_ROOT\vcpkg.exe" install openssl nghttp2 --triplet x64-windows-static
- name: Configure + build
shell: pwsh
run: |
cmake -B build -DCMAKE_BUILD_TYPE=Release `
-DAGENTTY_STANDALONE=ON -DAGENTTY_AUTO_PULL_MAYA=OFF `
-DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake" `
-DVCPKG_TARGET_TRIPLET=x64-windows-static
cmake --build build --config Release -j
- name: Stage binary
shell: pwsh
run: |
$exe = Get-ChildItem -Recurse build -Filter agentty.exe | Select-Object -First 1
Copy-Item $exe.FullName agentty-windows-x86_64.exe
- name: Upload to release
shell: bash
run: gh release upload "$TAG" agentty-windows-x86_64.exe --clobber
build-macos:
name: macos ${{ matrix.arch }}
needs: prepare
strategy:
fail-fast: false
matrix:
include:
- arch: arm64
runner: macos-15 # Apple Silicon (Xcode 16 / AppleClang 16+ for C++26)
- arch: x86_64
runner: macos-15-intel # Intel (macos-13 retired)
runs-on: ${{ matrix.runner }}
env:
TAG: ${{ needs.prepare.outputs.tag }}
steps:
- uses: actions/checkout@v4
- name: Init maya submodule (HTTPS)
run: |
git config --global url."https://github.com/".insteadOf "git@github.com:"
git submodule update --init --recursive
- name: Install deps (Homebrew)
run: brew install openssl@3 nghttp2 ninja
- name: Configure + build (standalone, static OpenSSL/nghttp2)
run: |
# Pin to GitHub Actions' macOS deployment baseline so the binary
# runs on older OS versions than the runner. STANDALONE statically
# links OpenSSL + nghttp2; only libSystem stays dynamic.
cmake -B build -GNinja -DCMAKE_BUILD_TYPE=Release \
-DAGENTTY_STANDALONE=ON -DAGENTTY_AUTO_PULL_MAYA=OFF \
-DAGENTTY_USE_MIMALLOC=OFF \
-DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 \
-DOPENSSL_ROOT_DIR="$(brew --prefix openssl@3)" \
-DCMAKE_PREFIX_PATH="$(brew --prefix nghttp2)"
cmake --build build -j"$(sysctl -n hw.ncpu)"
strip build/agentty
cp build/agentty agentty-macos-${{ matrix.arch }}
- name: Upload to release
run: gh release upload "$TAG" agentty-macos-${{ matrix.arch }} --clobber
package-linux:
name: packages
needs: [prepare, build-linux]
runs-on: ubuntu-latest
env:
V: ${{ needs.prepare.outputs.version }}
TAG: ${{ needs.prepare.outputs.tag }}
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
path: bins
pattern: bin-linux-*
merge-multiple: true
- name: Tooling
run: sudo apt-get update && sudo apt-get install -y --no-install-recommends rpm
- name: Build + upload .deb / .rpm / .pkg.tar.zst
run: |
mkdir -p dist
chmod +x bins/agentty-linux-*
# deb/build.sh cd's into a tmpdir, so the output dir must be absolute.
bash packaging/deb/build.sh "$V" amd64 bins/agentty-linux-x86_64 "$PWD/dist"
bash packaging/deb/build.sh "$V" arm64 bins/agentty-linux-aarch64 "$PWD/dist"
bash packaging/rpm/build.sh "$V" x86_64 bins/agentty-linux-x86_64 "$PWD/dist"
bash packaging/rpm/build.sh "$V" aarch64 bins/agentty-linux-aarch64 "$PWD/dist"
work="$(mktemp -d)"
sed -e "s/^pkgver=.*/pkgver=$V/" \
-e "s|source_x86_64=.*|source_x86_64=(\"agentty-$V-x86_64::file:///pkg/agentty-linux-x86_64\")|" \
-e "s/sha256sums_x86_64=.*/sha256sums_x86_64=('SKIP')/" \
packaging/arch/PKGBUILD > "$work/PKGBUILD"
cp bins/agentty-linux-x86_64 "$work/agentty-linux-x86_64"
docker run --rm -v "$work":/pkg -w /pkg archlinux:base-devel bash -c '
useradd -m -u 1000 build 2>/dev/null || true
chown -R build:build /pkg
su build -c "cd /pkg && PKGDEST=/pkg makepkg -f --skipinteg --noconfirm"
'
cp "$work"/agentty-bin-*-x86_64.pkg.tar.zst dist/
gh release upload "$TAG" dist/*.deb dist/*.rpm dist/*.pkg.tar.zst --clobber
# Runs last; regenerates SHA256SUMS over whatever is on the release. The
# binaries are already live regardless of whether this finishes — it only
# adds/refreshes the checksum file. `always()` so a single slow/failed build
# leg still gets a checksum file for everything that did land.
checksums:
name: checksums
needs: [prepare, build-linux, build-macos, build-windows, package-linux]
if: always()
runs-on: ubuntu-latest
env:
TAG: ${{ needs.prepare.outputs.tag }}
steps:
- name: Download release assets, hash, re-upload
run: |
mkdir -p dist && cd dist
gh release download "$TAG" --repo "$GITHUB_REPOSITORY" --pattern '*' --skip-existing || true
rm -f SHA256SUMS
sha256sum -- * > SHA256SUMS
gh release upload "$TAG" SHA256SUMS --clobber