Headless Rust gRPC daemon to drive Bluetooth, HLS/DASH playback, and snapcast/shairport-sync/squeezelite on Raspberry Pi audio rigs.
0

Configure Feed

Select the types of activity you want to include in your feed.

Add GitHub Actions release workflow

Tagging a `v*` release now fans out across five build jobs and uploads
prebuilt tarballs (+ sha256) to the GitHub release:

- macOS: aarch64-apple-darwin, x86_64-apple-darwin (native cargo build
via dtolnay/rust-toolchain + brew protoc)
- Linux: x86_64 / aarch64 / armhf (cross + docker buildx; the per-target
Dockerfile handles protoc 25.1 + multiarch dev libs)

taiki-e/install-action installs cross from the prebuilt binary so we
skip the cold cargo install. Swatinem/rust-cache keyed per target.
softprops/action-gh-release@v2 attaches the artifacts with
fail_on_unmatched_files so a missing build fails the release.

README gains an "Install → From a release tarball" section with a
curl one-liner pointing at github.com/tsirysndr/zerod (the GitHub
mirror used for CI/releases; tangled.org/tsiry-sandratraina.com/zerod
remains the canonical source host).

+177 -1
+153
.github/workflows/release.yml
··· 1 + name: release 2 + 3 + # Pushing a `v*` tag (e.g. v0.1.0) builds zerod for every supported triple, 4 + # packages each one as a tarball + sha256, and attaches them to a GitHub 5 + # release. Also dispatchable manually for dry runs. 6 + 7 + on: 8 + push: 9 + tags: 10 + - 'v*' 11 + workflow_dispatch: 12 + inputs: 13 + tag: 14 + description: 'Tag to release (e.g. v0.1.0). Must already exist on a commit.' 15 + required: true 16 + type: string 17 + 18 + env: 19 + CARGO_TERM_COLOR: always 20 + 21 + jobs: 22 + # macOS targets — native build, cross-compile to the other arch via the 23 + # platform's bundled compilers. `protoc` from Homebrew. 24 + build-darwin: 25 + name: build / ${{ matrix.target }} 26 + runs-on: macos-latest 27 + strategy: 28 + fail-fast: false 29 + matrix: 30 + include: 31 + - target: aarch64-apple-darwin 32 + - target: x86_64-apple-darwin 33 + steps: 34 + - uses: actions/checkout@v4 35 + 36 + - name: Install Rust toolchain 37 + uses: dtolnay/rust-toolchain@stable 38 + with: 39 + targets: ${{ matrix.target }} 40 + 41 + - name: Cache cargo 42 + uses: Swatinem/rust-cache@v2 43 + with: 44 + key: ${{ matrix.target }} 45 + 46 + - name: Install protoc 47 + run: brew install protobuf 48 + 49 + - name: cargo build --release 50 + run: cargo build --release --target ${{ matrix.target }} --bin zerod 51 + 52 + - name: Package tarball 53 + id: pkg 54 + run: | 55 + set -euo pipefail 56 + name="zerod-${{ matrix.target }}" 57 + mkdir -p "dist/$name" 58 + cp "target/${{ matrix.target }}/release/zerod" "dist/$name/" 59 + cp README.md LICENSE zerod.toml.example "dist/$name/" 60 + tar -C dist -czf "$name.tar.gz" "$name" 61 + shasum -a 256 "$name.tar.gz" > "$name.tar.gz.sha256" 62 + echo "archive=$name.tar.gz" >> "$GITHUB_OUTPUT" 63 + 64 + - name: Upload artifact 65 + uses: actions/upload-artifact@v4 66 + with: 67 + name: zerod-${{ matrix.target }} 68 + path: | 69 + ${{ steps.pkg.outputs.archive }} 70 + ${{ steps.pkg.outputs.archive }}.sha256 71 + if-no-files-found: error 72 + 73 + # Linux targets — cross + docker buildx. Cross builds each target inside 74 + # the matching `Dockerfile.<triple>`, which already pins protoc 25.1 and 75 + # the multiarch dev libs we need. 76 + build-linux: 77 + name: build / ${{ matrix.target }} 78 + runs-on: ubuntu-latest 79 + strategy: 80 + fail-fast: false 81 + matrix: 82 + include: 83 + - target: x86_64-unknown-linux-gnu 84 + - target: aarch64-unknown-linux-gnu 85 + - target: arm-unknown-linux-gnueabihf 86 + steps: 87 + - uses: actions/checkout@v4 88 + 89 + - name: Install Rust toolchain 90 + uses: dtolnay/rust-toolchain@stable 91 + 92 + - name: Cache cargo 93 + uses: Swatinem/rust-cache@v2 94 + with: 95 + # Cross's target dir lives inside the docker container, but the 96 + # registry / git cache + ~/.cargo cache on the host still help. 97 + key: ${{ matrix.target }} 98 + 99 + - name: Set up Docker Buildx 100 + uses: docker/setup-buildx-action@v3 101 + 102 + - name: Install cross 103 + uses: taiki-e/install-action@v2 104 + with: 105 + tool: cross 106 + 107 + - name: cross build --release 108 + run: cross build --release --target ${{ matrix.target }} --bin zerod 109 + 110 + - name: Package tarball 111 + id: pkg 112 + run: | 113 + set -euo pipefail 114 + name="zerod-${{ matrix.target }}" 115 + mkdir -p "dist/$name" 116 + cp "target/${{ matrix.target }}/release/zerod" "dist/$name/" 117 + cp README.md LICENSE zerod.toml.example "dist/$name/" 118 + tar -C dist -czf "$name.tar.gz" "$name" 119 + sha256sum "$name.tar.gz" > "$name.tar.gz.sha256" 120 + echo "archive=$name.tar.gz" >> "$GITHUB_OUTPUT" 121 + 122 + - name: Upload artifact 123 + uses: actions/upload-artifact@v4 124 + with: 125 + name: zerod-${{ matrix.target }} 126 + path: | 127 + ${{ steps.pkg.outputs.archive }} 128 + ${{ steps.pkg.outputs.archive }}.sha256 129 + if-no-files-found: error 130 + 131 + release: 132 + name: GitHub Release 133 + needs: [build-darwin, build-linux] 134 + runs-on: ubuntu-latest 135 + permissions: 136 + contents: write 137 + steps: 138 + - name: Download all artifacts 139 + uses: actions/download-artifact@v4 140 + with: 141 + path: artifacts 142 + merge-multiple: true 143 + 144 + - name: List artifacts 145 + run: ls -lh artifacts/ 146 + 147 + - name: Create / update GitHub release 148 + uses: softprops/action-gh-release@v2 149 + with: 150 + tag_name: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref_name }} 151 + files: artifacts/* 152 + generate_release_notes: true 153 + fail_on_unmatched_files: true
+24 -1
README.md
··· 44 44 - **Reflection** — `tonic-reflection` is wired up, so `grpcurl 45 45 -plaintext localhost:50151 list` works out of the box. 46 46 47 - ## Build 47 + ## Install 48 + 49 + ### From a release tarball 50 + 51 + Every tagged release (`v*` tag on `main`) publishes prebuilt binaries 52 + for these triples: 53 + 54 + | Platform | Tarball | 55 + | ----------------------------------------- | ------------------------------------------ | 56 + | macOS Apple Silicon | `zerod-aarch64-apple-darwin.tar.gz` | 57 + | macOS Intel | `zerod-x86_64-apple-darwin.tar.gz` | 58 + | Linux x86_64 (NUC, server, …) | `zerod-x86_64-unknown-linux-gnu.tar.gz` | 59 + | Linux ARM64 (Pi 3/4/5, 64-bit SBCs) | `zerod-aarch64-unknown-linux-gnu.tar.gz` | 60 + | Linux ARM v6/v7 (Pi 1 / Zero / Pi OS 32) | `zerod-arm-unknown-linux-gnueabihf.tar.gz` | 61 + 62 + ``` 63 + curl -L https://github.com/tsirysndr/zerod/releases/latest/download/zerod-aarch64-unknown-linux-gnu.tar.gz | tar xz 64 + sudo install zerod-aarch64-unknown-linux-gnu/zerod /usr/local/bin/ 65 + ``` 66 + 67 + Each archive ships `zerod` plus `README.md`, `LICENSE`, and 68 + `zerod.toml.example`, and is accompanied by a `.sha256` checksum file. 69 + 70 + ### From source 48 71 49 72 Native build (whatever host you're on): 50 73