diff --git a/.github/aur/pkgbuild.sh b/.github/aur/pkgbuild.sh new file mode 100755 index 0000000..a3d6323 --- /dev/null +++ b/.github/aur/pkgbuild.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash +# Prints the PKGBUILD of the AUR package for a release, e.g. `pkgbuild.sh v0.3.0`, building it from +# the source archive of the release's tag. +set -euo pipefail + +tag=$1 +version=${tag#v} +repo=abusch/sinuous + +sha256=$(curl -fsSL "https://github.com/$repo/archive/refs/tags/$tag.tar.gz" | sha256sum | cut -d ' ' -f 1) + +# Follows https://wiki.archlinux.org/title/Rust_package_guidelines. +cat < + +pkgname=sinuous +pkgver=$version +pkgrel=1 +pkgdesc="A simple TUI for controlling local Sonos speakers" +url="https://github.com/$repo" +license=('MIT') +arch=('x86_64' 'aarch64') +depends=('gcc-libs' 'glibc') +makedepends=('cargo') +# The release profile already strips the binary, so the debug package would be empty. +options=('!lto' '!debug') +source=("\$pkgname-\$pkgver.tar.gz::\$url/archive/refs/tags/v\$pkgver.tar.gz") +sha256sums=('$sha256') + +prepare() { + cd "\$pkgname-\$pkgver" + export RUSTUP_TOOLCHAIN=stable + cargo fetch --locked --target "\$(rustc -vV | sed -n 's/host: //p')" +} + +build() { + cd "\$pkgname-\$pkgver" + export RUSTUP_TOOLCHAIN=stable + export CARGO_TARGET_DIR=target + cargo build --frozen --release +} + +check() { + cd "\$pkgname-\$pkgver" + export RUSTUP_TOOLCHAIN=stable + cargo test --frozen +} + +package() { + cd "\$pkgname-\$pkgver" + install -Dm755 target/release/\$pkgname -t "\$pkgdir/usr/bin/" + install -Dm644 LICENSE -t "\$pkgdir/usr/share/licenses/\$pkgname/" + install -Dm644 README.md -t "\$pkgdir/usr/share/doc/\$pkgname/" +} +EOF diff --git a/.github/workflows/aur.yml b/.github/workflows/aur.yml new file mode 100644 index 0000000..e3611cf --- /dev/null +++ b/.github/workflows/aur.yml @@ -0,0 +1,102 @@ +name: AUR package + +# Updates the `sinuous` AUR package to a release. +on: + # From release-plz.yml, once it has created a release: GitHub doesn't run workflows for releases + # made with GITHUB_TOKEN, so this can't be triggered by the release itself. + workflow_call: + inputs: + tag: + type: string + required: true + # To update the package to an existing release. + workflow_dispatch: + inputs: + tag: + description: The tag of the release, e.g. v0.2.0 + type: string + required: true + +permissions: + contents: read + +defaults: + run: + shell: bash + +jobs: + # Check that the package builds before publishing it. This runs the build scripts of all the + # dependencies, so it's kept apart from the job that has the AUR key. + build: + name: Build + if: github.repository_owner == 'abusch' + runs-on: ubuntu-latest + # makepkg needs Arch Linux. + container: archlinux:base-devel + timeout-minutes: 60 + steps: + - name: Install tools + run: pacman -Syu --noconfirm --needed git rust + - name: Checkout repository + uses: actions/checkout@v7 + - name: Write the PKGBUILD + env: + TAG: ${{ inputs.tag }} + run: | + # makepkg refuses to run as root. + useradd --create-home builder + mkdir /tmp/pkg + .github/aur/pkgbuild.sh "$TAG" > /tmp/pkg/PKGBUILD + chown -R builder /tmp/pkg + - name: Build the package + working-directory: /tmp/pkg + run: runuser -u builder -- makepkg --noconfirm + + # Publish the package. This writes its own PKGBUILD rather than taking the one from the build job, + # and runs no code from the dependencies. + publish: + name: Publish + needs: build + runs-on: ubuntu-latest + container: archlinux:base-devel + steps: + - name: Install tools + run: pacman -Syu --noconfirm --needed git openssh + - name: Checkout repository + uses: actions/checkout@v7 + - name: Write the PKGBUILD and .SRCINFO + env: + TAG: ${{ inputs.tag }} + run: | + # makepkg refuses to run as root. + useradd --create-home builder + mkdir /tmp/pkg + .github/aur/pkgbuild.sh "$TAG" > /tmp/pkg/PKGBUILD + chown -R builder /tmp/pkg + cd /tmp/pkg + runuser -u builder -- makepkg --printsrcinfo > .SRCINFO + - name: Publish the package + env: + AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }} + TAG: ${{ inputs.tag }} + run: | + mkdir -p ~/.ssh + chmod 700 ~/.ssh + echo "$AUR_SSH_PRIVATE_KEY" > ~/.ssh/aur + chmod 600 ~/.ssh/aur + # From https://aur.archlinux.org. + echo "aur.archlinux.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEuBKrPzbawxA/k2g6NcyV5jmqwJ2s+zpgZGZ7tpLIcN" > ~/.ssh/known_hosts + export GIT_SSH_COMMAND="ssh -i ~/.ssh/aur -o IdentitiesOnly=yes" + + git clone ssh://aur@aur.archlinux.org/sinuous.git aur + cp /tmp/pkg/PKGBUILD /tmp/pkg/.SRCINFO aur/ + cd aur + git add PKGBUILD .SRCINFO + if git diff --cached --quiet; then + echo "The package is already up to date" + exit 0 + fi + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git commit -m "Update to ${TAG#v}" + git push diff --git a/.github/workflows/release-plz.yml b/.github/workflows/release-plz.yml index ec5296f..d206fad 100644 --- a/.github/workflows/release-plz.yml +++ b/.github/workflows/release-plz.yml @@ -52,6 +52,17 @@ jobs: # For the token of the Homebrew tap. secrets: inherit + # Update the AUR package to the release just made. + release-aur: + name: AUR package + needs: release-plz-release + if: needs.release-plz-release.outputs.tag != '' + uses: ./.github/workflows/aur.yml + with: + tag: ${{ needs.release-plz-release.outputs.tag }} + # For the SSH key of the AUR account. + secrets: inherit + # Create a PR with the new versions and changelog, preparing the next release. release-plz-pr: name: Release-plz PR diff --git a/README.md b/README.md index 7883ca9..16c2041 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,13 @@ On macOS and Linux, install it with [Homebrew](https://brew.sh): brew install abusch/tap/sinuous ``` +On Arch Linux, install the [`sinuous` AUR package](https://aur.archlinux.org/packages/sinuous) +with your AUR helper, e.g.: + +```sh +paru -S sinuous +``` + Or download the binary for your platform from the [releases page](https://github.com/abusch/sinuous/releases), or install it with [Cargo](https://rustup.rs):