ci: attach .deb and .rpm packages to releases and nightlies
Built by nfpm from the static musl binaries, with the man page and the bash, zsh and fish completions. The names carry no version, so releases/latest/download/soulseek-rs-amd64.deb stays a working link; the nightly pair replaces itself on the rolling prerelease.
This commit is contained in:
@@ -105,6 +105,12 @@ jobs:
|
|||||||
dry-run: true
|
dry-run: true
|
||||||
dry-run-intended: true
|
dry-run-intended: true
|
||||||
|
|
||||||
|
- name: Build .deb and .rpm
|
||||||
|
if: endsWith(matrix.target, '-musl')
|
||||||
|
env:
|
||||||
|
TARGET: ${{ matrix.target }}
|
||||||
|
run: sh scripts/package-linux.sh "target/$TARGET/release/soulseek-rs" "$SOULSEEK_RS_VERSION" "$TARGET" . soulseek-rs-nightly
|
||||||
|
|
||||||
- name: Store packaged binary
|
- name: Store packaged binary
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
@@ -112,6 +118,8 @@ jobs:
|
|||||||
path: |
|
path: |
|
||||||
${{ steps.package.outputs.tar || steps.package.outputs.zip }}
|
${{ steps.package.outputs.tar || steps.package.outputs.zip }}
|
||||||
${{ steps.package.outputs.sha256 }}
|
${{ steps.package.outputs.sha256 }}
|
||||||
|
soulseek-rs-nightly-*.deb
|
||||||
|
soulseek-rs-nightly-*.rpm
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
retention-days: 1
|
retention-days: 1
|
||||||
|
|
||||||
@@ -147,6 +155,10 @@ jobs:
|
|||||||
soulseek-rs-nightly-aarch64-apple-darwin.sha256
|
soulseek-rs-nightly-aarch64-apple-darwin.sha256
|
||||||
soulseek-rs-nightly-x86_64-pc-windows-msvc.sha256
|
soulseek-rs-nightly-x86_64-pc-windows-msvc.sha256
|
||||||
soulseek-rs-nightly-aarch64-pc-windows-msvc.sha256
|
soulseek-rs-nightly-aarch64-pc-windows-msvc.sha256
|
||||||
|
soulseek-rs-nightly-amd64.deb
|
||||||
|
soulseek-rs-nightly-arm64.deb
|
||||||
|
soulseek-rs-nightly-x86_64.rpm
|
||||||
|
soulseek-rs-nightly-aarch64.rpm
|
||||||
)
|
)
|
||||||
printf '%s\n' "${expected[@]}" | sort > "$RUNNER_TEMP/expected-assets"
|
printf '%s\n' "${expected[@]}" | sort > "$RUNNER_TEMP/expected-assets"
|
||||||
find dist -maxdepth 1 -type f -exec basename {} \; | sort > "$RUNNER_TEMP/actual-assets"
|
find dist -maxdepth 1 -type f -exec basename {} \; | sort > "$RUNNER_TEMP/actual-assets"
|
||||||
@@ -234,6 +246,7 @@ jobs:
|
|||||||
timeout-minutes: 5
|
timeout-minutes: 5
|
||||||
env:
|
env:
|
||||||
VERSION: ${{ needs.source.outputs.version }}
|
VERSION: ${{ needs.source.outputs.version }}
|
||||||
|
DOWNLOAD: https://github.com/${{ github.repository }}/releases/download/nightly
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
@@ -260,3 +273,19 @@ jobs:
|
|||||||
PATH="$RUNNER_TEMP/wget-path" /bin/sh website/public/install.sh --nightly
|
PATH="$RUNNER_TEMP/wget-path" /bin/sh website/public/install.sh --nightly
|
||||||
"$SOULSEEK_RS_INSTALL_DIR/soulseek-rs" --version | grep -F "$VERSION"
|
"$SOULSEEK_RS_INSTALL_DIR/soulseek-rs" --version | grep -F "$VERSION"
|
||||||
|
|
||||||
|
- name: Install the .deb
|
||||||
|
run: |
|
||||||
|
curl -fsSLO "$DOWNLOAD/soulseek-rs-nightly-amd64.deb"
|
||||||
|
sudo apt-get install -y ./soulseek-rs-nightly-amd64.deb
|
||||||
|
soulseek-rs --version | grep -F "$VERSION"
|
||||||
|
dpkg -L soulseek-rs | grep -Fx /usr/share/man/man1/soulseek-rs.1.gz
|
||||||
|
dpkg -L soulseek-rs | grep -Fx /usr/share/zsh/vendor-completions/_soulseek-rs
|
||||||
|
|
||||||
|
- name: Install the .rpm
|
||||||
|
run: |
|
||||||
|
docker run --rm fedora:latest sh -ec "
|
||||||
|
dnf install -y '$DOWNLOAD/soulseek-rs-nightly-x86_64.rpm'
|
||||||
|
soulseek-rs --version | grep -F '$VERSION'
|
||||||
|
rpm -ql soulseek-rs | grep -Fx /usr/share/man/man1/soulseek-rs.1.gz
|
||||||
|
rpm -ql soulseek-rs | grep -Fx /usr/share/zsh/site-functions/_soulseek-rs
|
||||||
|
"
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
name: Packaging
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- 'Cargo.lock'
|
||||||
|
- 'Cargo.toml'
|
||||||
|
- 'packaging/**'
|
||||||
|
- 'scripts/package-linux.sh'
|
||||||
|
- 'soulseek-rs/src/cli.rs'
|
||||||
|
- 'soulseek-rs/src/run.rs'
|
||||||
|
- 'soulseek-rs/src/commands/**'
|
||||||
|
- '.github/workflows/packaging.yml'
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: packaging-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
env:
|
||||||
|
CARGO_TERM_COLOR: always
|
||||||
|
VERSION: 0.0.0+git202601010000.0000000
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
packages:
|
||||||
|
name: .deb and .rpm
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 20
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
|
with:
|
||||||
|
targets: x86_64-unknown-linux-musl
|
||||||
|
|
||||||
|
- uses: Swatinem/rust-cache@v2
|
||||||
|
|
||||||
|
- name: Install musl toolchain
|
||||||
|
run: sudo apt-get update && sudo apt-get install -y musl-tools
|
||||||
|
|
||||||
|
- name: Build the packages
|
||||||
|
env:
|
||||||
|
SOULSEEK_RS_VERSION: ${{ env.VERSION }}
|
||||||
|
TARGET: x86_64-unknown-linux-musl
|
||||||
|
run: |
|
||||||
|
cargo build --locked --release --target "$TARGET" --package soulseek-rs
|
||||||
|
sh scripts/package-linux.sh "target/$TARGET/release/soulseek-rs" "$VERSION" "$TARGET" . soulseek-rs-nightly
|
||||||
|
|
||||||
|
- name: Install the .deb
|
||||||
|
run: |
|
||||||
|
sudo apt-get install -y ./soulseek-rs-nightly-amd64.deb
|
||||||
|
soulseek-rs --version | grep -F "$VERSION"
|
||||||
|
dpkg -L soulseek-rs | grep -Fx /usr/share/man/man1/soulseek-rs.1.gz
|
||||||
|
dpkg -L soulseek-rs | grep -Fx /usr/share/zsh/vendor-completions/_soulseek-rs
|
||||||
|
|
||||||
|
- name: Install the .rpm
|
||||||
|
run: |
|
||||||
|
docker run --rm -v "$PWD:/packages:ro" fedora:latest sh -ec "
|
||||||
|
dnf install -y /packages/soulseek-rs-nightly-x86_64.rpm
|
||||||
|
soulseek-rs --version | grep -F '$VERSION'
|
||||||
|
rpm -ql soulseek-rs | grep -Fx /usr/share/man/man1/soulseek-rs.1.gz
|
||||||
|
rpm -ql soulseek-rs | grep -Fx /usr/share/zsh/site-functions/_soulseek-rs
|
||||||
|
"
|
||||||
@@ -200,6 +200,16 @@ jobs:
|
|||||||
ref: refs/tags/${{ needs.release.outputs.tag }}
|
ref: refs/tags/${{ needs.release.outputs.tag }}
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build and upload .deb and .rpm
|
||||||
|
if: endsWith(matrix.target, '-musl') && hashFiles('scripts/package-linux.sh') != ''
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
TAG: ${{ needs.release.outputs.tag }}
|
||||||
|
TARGET: ${{ matrix.target }}
|
||||||
|
run: |
|
||||||
|
sh scripts/package-linux.sh "target/$TARGET/release/soulseek-rs" "${TAG#v}" "$TARGET" dist
|
||||||
|
gh release upload "$TAG" dist/* --clobber
|
||||||
|
|
||||||
# The tap regenerates its formula from whatever `gh release view` calls latest,
|
# The tap regenerates its formula from whatever `gh release view` calls latest,
|
||||||
# so it only needs a nudge once every archive and .sha256 is on the release —
|
# so it only needs a nudge once every archive and .sha256 is on the release —
|
||||||
# hence `needs: binaries` rather than firing alongside it. The tap also polls
|
# hence `needs: binaries` rather than firing alongside it. The tap also polls
|
||||||
|
|||||||
+14
-3
@@ -28,6 +28,11 @@ Releases are automated by [release-plz](https://release-plz.dev). You do not run
|
|||||||
| `soulseek-rs-vX.Y.Z-x86_64-pc-windows-msvc.zip` | |
|
| `soulseek-rs-vX.Y.Z-x86_64-pc-windows-msvc.zip` | |
|
||||||
| `soulseek-rs-vX.Y.Z-aarch64-pc-windows-msvc.zip` | |
|
| `soulseek-rs-vX.Y.Z-aarch64-pc-windows-msvc.zip` | |
|
||||||
|
|
||||||
|
- packages the two Linux binaries as `soulseek-rs-amd64.deb`, `soulseek-rs-arm64.deb`,
|
||||||
|
`soulseek-rs-x86_64.rpm` and `soulseek-rs-aarch64.rpm`, with the man page and the
|
||||||
|
bash, zsh and fish completions. The names carry no version, so
|
||||||
|
`releases/latest/download/soulseek-rs-amd64.deb` is a link that keeps working,
|
||||||
|
|
||||||
- rewrites `Formula/soulseek-rs.rb` in the `michel/homebrew-tap` repository so
|
- rewrites `Formula/soulseek-rs.rb` in the `michel/homebrew-tap` repository so
|
||||||
`brew install michel/tap/soulseek-rs` picks up the new macOS and Linux archives,
|
`brew install michel/tap/soulseek-rs` picks up the new macOS and Linux archives,
|
||||||
- merges `master` back into `develop`, so the branch the work happens on carries the
|
- merges `master` back into `develop`, so the branch the work happens on carries the
|
||||||
@@ -44,9 +49,15 @@ conflict.
|
|||||||
|
|
||||||
`.github/workflows/nightly.yml` builds the tip of `develop` at 02:17 UTC every
|
`.github/workflows/nightly.yml` builds the tip of `develop` at 02:17 UTC every
|
||||||
day. It resolves the commit once, builds the same six targets as a numbered
|
day. It resolves the commit once, builds the same six targets as a numbered
|
||||||
release, verifies all twelve archives and checksum files as one set, then
|
release, packages the two Linux ones as `soulseek-rs-nightly-*.deb` and `.rpm`,
|
||||||
replaces the mutable `nightly` prerelease and tag. The published release is
|
verifies all sixteen files as one set, then replaces the mutable `nightly`
|
||||||
smoke-tested through both the curl and wget installer paths.
|
prerelease and tag. Every nightly binary reports `X.Y.Z+git<commit time, UTC>.<sha>`
|
||||||
|
instead of the crate version. The published release is smoke-tested through the
|
||||||
|
curl and wget installer paths, and by installing the `.deb` and the `.rpm`.
|
||||||
|
|
||||||
|
Never enable GitHub's Immutable Releases on this repository: nightly replaces
|
||||||
|
its assets and moves its tag, and a tag name burnt by that setting cannot be
|
||||||
|
reused.
|
||||||
|
|
||||||
Use **Actions → Nightly → Run workflow** to force a build. The workflow always
|
Use **Actions → Nightly → Run workflow** to force a build. The workflow always
|
||||||
checks out `develop`, regardless of the ref selected in the dispatch form. The
|
checks out `develop`, regardless of the ref selected in the dispatch form. The
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
name: soulseek-rs
|
||||||
|
arch: ${PKG_ARCH}
|
||||||
|
platform: linux
|
||||||
|
version: ${PKG_VERSION}
|
||||||
|
version_schema: none
|
||||||
|
release: "1"
|
||||||
|
section: net
|
||||||
|
priority: optional
|
||||||
|
maintainer: Michel de Graaf <michel@re-invention.nl>
|
||||||
|
description: |
|
||||||
|
Soulseek client for the terminal
|
||||||
|
A TUI, a scriptable command line and a daemon for the Soulseek
|
||||||
|
peer-to-peer network.
|
||||||
|
vendor: Michel de Graaf
|
||||||
|
homepage: https://re-invention.nl/soulseek-rs/
|
||||||
|
license: MIT
|
||||||
|
suggests:
|
||||||
|
- gnome-keyring
|
||||||
|
contents:
|
||||||
|
- src: target/nfpm/soulseek-rs
|
||||||
|
dst: /usr/bin/soulseek-rs
|
||||||
|
file_info:
|
||||||
|
mode: 0755
|
||||||
|
- src: target/nfpm/soulseek-rs.1.gz
|
||||||
|
dst: /usr/share/man/man1/soulseek-rs.1.gz
|
||||||
|
- src: target/nfpm/soulseek-rs.bash
|
||||||
|
dst: /usr/share/bash-completion/completions/soulseek-rs
|
||||||
|
- src: target/nfpm/soulseek-rs.fish
|
||||||
|
dst: /usr/share/fish/vendor_completions.d/soulseek-rs.fish
|
||||||
|
- src: target/nfpm/_soulseek-rs
|
||||||
|
dst: /usr/share/zsh/vendor-completions/_soulseek-rs
|
||||||
|
packager: deb
|
||||||
|
- src: target/nfpm/_soulseek-rs
|
||||||
|
dst: /usr/share/zsh/site-functions/_soulseek-rs
|
||||||
|
packager: rpm
|
||||||
|
- dst: /usr/share/doc/soulseek-rs
|
||||||
|
type: dir
|
||||||
|
packager: rpm
|
||||||
|
- dst: /usr/share/licenses/soulseek-rs
|
||||||
|
type: dir
|
||||||
|
packager: rpm
|
||||||
|
- src: README.md
|
||||||
|
dst: /usr/share/doc/soulseek-rs/README.md
|
||||||
|
packager: deb
|
||||||
|
- src: README.md
|
||||||
|
dst: /usr/share/doc/soulseek-rs/README.md
|
||||||
|
packager: rpm
|
||||||
|
type: doc
|
||||||
|
- src: LICENSE
|
||||||
|
dst: /usr/share/doc/soulseek-rs/copyright
|
||||||
|
packager: deb
|
||||||
|
- src: LICENSE
|
||||||
|
dst: /usr/share/licenses/soulseek-rs/LICENSE
|
||||||
|
packager: rpm
|
||||||
|
type: license
|
||||||
Executable
+54
@@ -0,0 +1,54 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
umask 022
|
||||||
|
|
||||||
|
[ $# -ge 4 ] || {
|
||||||
|
echo "usage: $0 <binary> <version> <target-triple> <out-dir> [<package-basename>]" >&2
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
|
|
||||||
|
NFPM_VERSION=2.47.0
|
||||||
|
|
||||||
|
binary=$1
|
||||||
|
PKG_VERSION=$2
|
||||||
|
target=$3
|
||||||
|
out=$4
|
||||||
|
package=${5:-soulseek-rs}
|
||||||
|
|
||||||
|
case "$target" in
|
||||||
|
x86_64-*) PKG_ARCH=amd64 rpm_arch=x86_64 ;;
|
||||||
|
aarch64-*) PKG_ARCH=arm64 rpm_arch=aarch64 ;;
|
||||||
|
*) echo "no package architecture for $target" >&2; exit 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$(uname -s)-$(uname -m)" in
|
||||||
|
Linux-x86_64) nfpm_asset=Linux_x86_64 nfpm_sha256=0660ca602b2d2d2ae4781a06c692b3eeb9d437ffea05b831d76e41f4a3188783 ;;
|
||||||
|
Linux-aarch64) nfpm_asset=Linux_arm64 nfpm_sha256=1c0f5f2999b9a974bfb04fdb0cc3306096de530ac5dbb25d739cc5f5219c919c ;;
|
||||||
|
*) echo "no pinned nfpm build for this machine" >&2; exit 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
root=$(cd "$(dirname "$0")/.." && pwd)
|
||||||
|
work=$(mktemp -d)
|
||||||
|
trap 'rm -rf "$work"' EXIT
|
||||||
|
stage=$root/target/nfpm
|
||||||
|
rm -rf "$stage"
|
||||||
|
mkdir -p "$stage" "$out"
|
||||||
|
out=$(cd "$out" && pwd)
|
||||||
|
|
||||||
|
cp "$binary" "$stage/soulseek-rs"
|
||||||
|
"$binary" completions print bash > "$stage/soulseek-rs.bash"
|
||||||
|
"$binary" completions print zsh > "$stage/_soulseek-rs"
|
||||||
|
"$binary" completions print fish > "$stage/soulseek-rs.fish"
|
||||||
|
"$binary" man > "$stage/soulseek-rs.1"
|
||||||
|
gzip -9n "$stage/soulseek-rs.1"
|
||||||
|
|
||||||
|
archive=nfpm_${NFPM_VERSION}_$nfpm_asset.tar.gz
|
||||||
|
curl -fsSL -o "$work/$archive" \
|
||||||
|
"https://github.com/goreleaser/nfpm/releases/download/v$NFPM_VERSION/$archive"
|
||||||
|
echo "$nfpm_sha256 $work/$archive" | sha256sum -c - >/dev/null
|
||||||
|
tar -xzf "$work/$archive" -C "$work" nfpm
|
||||||
|
|
||||||
|
export PKG_ARCH PKG_VERSION
|
||||||
|
cd "$root"
|
||||||
|
"$work/nfpm" package --config packaging/nfpm.yaml --packager deb --target "$out/$package-$PKG_ARCH.deb"
|
||||||
|
"$work/nfpm" package --config packaging/nfpm.yaml --packager rpm --target "$out/$package-$rpm_arch.rpm"
|
||||||
Reference in New Issue
Block a user