Skip to content

Release Workflow

The .github/workflows/release.yml workflow builds cross-compiled static binaries for linux/amd64, linux/arm64, linux/mipsle, windows/amd64, windows/arm64, darwin/amd64 and darwin/arm64, generates a combined SHA-256 checksums file, signs every binary with cosign, and publishes them as a GitHub Release when a version tag is pushed.

Trigger Events

EventFilterDescription
pushtags: ['v*']Runs when a tag matching v* is pushed

The workflow does not trigger on branch pushes, pull requests, or tags that do not match the v* pattern.

Permissions

The workflow declares a minimal permissions block:

ScopeAccessReason
contentswriteRequired for creating releases and uploading assets

No other permission scopes are granted. The workflow uses GITHUB_TOKEN (not personal access tokens).

Jobs

The workflow has two jobs: build runs once per target via a matrix strategy, and release runs after all matrix builds complete.

build

Cross-compiles a static binary for each target and uploads it with its checksum as a GitHub Actions artifact.

StepCommand / ActionPurpose
Checkoutactions/checkout@v4Clone repository at the tagged commit
Setup Goactions/setup-go@v5 (go-version: '1.26')Install Go with module caching
Build binarygo build -ldflags "..." -o plexd-$GOOS-$GOARCH$EXT ./cmd/plexdCross-compile static binary
Generate checksumsha256sum plexd-$GOOS-$GOARCH$EXT > plexd-$GOOS-$GOARCH$EXT.sha256Create per-artifact checksum file
Upload artifactactions/upload-artifact@v4Upload binary and checksum for release job

The build step sets CGO_ENABLED=0 and takes GOOS, GOARCH and GOMIPS from the matrix, producing a fully static binary with no shared library dependencies. Every target cross-compiles on ubuntu-latest; no Windows or macOS runner is involved.

Matrix strategy:

goosgoarchgomipsext
linuxamd64(unset)(unset)
linuxarm64(unset)(unset)
linuxmipslesoftfloat(unset)
windowsamd64(unset).exe
windowsarm64(unset).exe
darwinamd64(unset)(unset)
darwinarm64(unset)(unset)

The matrix uses an include list so each entry can set its own parameters. The mipsle build sets GOMIPS=softfloat for OpenWRT hardware without an FPU. ext is the binary's file extension and expands to the empty string on every entry that omits it, which is what keeps the Linux asset names unchanged.

Each matrix entry produces one artifact named plexd-{goos}-{goarch} containing both the binary and its .sha256 checksum file.

.github/workflows/build.yml carries the same matrix and runs on every pull request. internal/cicheck fails if the two drift apart, so a target is added to both files or neither.

release

Downloads all build artifacts and creates a GitHub Release with auto-generated notes.

StepCommand / ActionPurpose
Download artifactsactions/download-artifact@v4 (merge-multiple: true)Download all matrix artifacts into one directory
Generate combined checksumscat plexd-*.sha256 > checksums.sha256Combine per-binary checksums into single file
Install cosignsigstore/cosign-installer@v4Provide the cosign binary
Sign release binariescosign sign-blob --bundle <binary>.sigstore.json <binary>Sign each binary, keyless
Create GitHub Releasesoftprops/action-gh-release@v2 (generate_release_notes: true)Create release and upload assets

The release job has needs: build, ensuring it only runs after all matrix builds succeed. The merge-multiple: true option on download-artifact merges all artifacts into a single flat directory.

The signing step is keyless, which is why the job requests id-token: write in addition to contents: write. The bundle's name is the binary's file name plus .sigstore.json, .exe included, so plexd-windows-amd64.exe is signed into plexd-windows-amd64.exe.sigstore.json. internal/upgrade derives the bundle name the same way.

Build Arguments and Ldflags

The build step injects version metadata via Go linker flags matching the pattern used in the Dockerfile:

-s -w -X main.version=${VERSION} -X main.commit=${COMMIT} -X main.date=${DATE}
FlagSourceExample Value
-s -w(static flags)Strips debug info and DWARF symbols
-X main.version=...GITHUB_REF_NAMEv1.2.3
-X main.commit=...GITHUB_SHA (first 8 chars)a1b2c3d4
-X main.date=...date -u +%Y-%m-%dT%H:%M:%SZ2025-01-15T12:00:00Z

Release Assets

FileDescription
plexd-linux-amd64Static binary for Linux x86_64
plexd-linux-arm64Static binary for Linux ARM64
plexd-linux-mipsleStatic binary for MIPS little-endian (softfloat)
plexd-windows-amd64.exeStatic binary for Windows x86_64
plexd-windows-arm64.exeStatic binary for Windows ARM64
plexd-darwin-amd64Static binary for macOS Intel
plexd-darwin-arm64Static binary for macOS Apple silicon
<binary>.sigstore.jsonSigstore bundle for each of the seven binaries
checksums.sha256Combined SHA-256 checksums for all binaries

Binary names follow the plexd-{goos}-{goarch} convention, with a .exe suffix on Windows. The three Linux names are the ones deploy/install.sh and internal/upgrade/fetcher.go resolve, so they cannot change.

The per-binary .sha256 files are build artifacts only. They are folded into checksums.sha256 and are not published as release assets.

Checksum Format

The checksums.sha256 file contains one line per binary in standard sha256sum output format:

<64-char hex hash>  plexd-linux-amd64
<64-char hex hash>  plexd-linux-arm64
<64-char hex hash>  plexd-linux-mipsle
<64-char hex hash>  plexd-windows-amd64.exe
<64-char hex hash>  plexd-windows-arm64.exe
<64-char hex hash>  plexd-darwin-amd64
<64-char hex hash>  plexd-darwin-arm64

Two spaces separate the hash from the filename. This format is compatible with sha256sum --check for verification and with install.sh, which downloads checksums.sha256 and greps for the target binary name.

Action Versions

All actions are pinned to full SHA hashes for supply-chain hardening. The checkout and setup-go pins match those in ci.yml.

ActionVersionSHAPurpose
actions/checkoutv4.3.134e114876b0b11c390a56381ad16ebd13914f8d5Repository checkout
actions/setup-gov5.6.040f1582b2485089dde7abd97c1529aa768e1baffGo installation and module cache
actions/upload-artifactv4.6.2ea165f8d65b6e75b540449e92b4886f43607fa02Upload build artifacts
actions/download-artifactv4.3.0d3f86a106a0bac45b974a628896c90dbdf5c8093Download artifacts in release job
sigstore/cosign-installerv4.1.26f9f17788090df1f26f669e9d70d6ae9567deba6Install cosign for keyless signing
softprops/action-gh-releasev2.5.0a06a81a03ee405af7f2048a818ed3f03bbf83c7bCreate GitHub Release with assets

Creating a Release

See Cutting a Release for the tag-driven release procedure and the versioning policy.