From 732da8a5ce10a304b20ccbcc97f4226a7aebf8cd Mon Sep 17 00:00:00 2001 From: BMAD CI Fix Agent Date: Fri, 4 Sep 2026 22:20:04 -0500 Subject: [PATCH] ci: publish versioned release artifacts --- .github/workflows/package.yml | 9 +++++-- .github/workflows/release.yml | 31 +++++++++++++++++++++++ Makefile | 19 ++++++++++++++- docs/packaging.md | 46 +++++++++++++++++++++++++++++++++++ 4 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index cccff3e..30388ab 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -17,8 +17,13 @@ jobs: go-version-file: go.mod - name: Smoke-test package run: make package-smoke GOOS=linux GOARCH=amd64 + - name: Build release artifact set + run: make release-artifacts VERSION=0.1.0-ci - name: Upload package artifact uses: actions/upload-artifact@v4 with: - name: devrail-router-linux-amd64 - path: dist/*.tar.gz + name: devrail-router-release-artifacts + path: | + dist/*.tar.gz + dist/release/*.tar.gz + dist/release/SHA256SUMS diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..43d5549 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,31 @@ +name: Release + +on: + push: + tags: + - "v*.*.*" + +permissions: + contents: write + +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version-file: go.mod + - name: Build release artifacts + run: | + VERSION="${GITHUB_REF_NAME#v}" + make release-artifacts VERSION="${VERSION}" + - name: Create GitHub release + env: + GH_TOKEN: ${{ github.token }} + run: | + gh release create "${GITHUB_REF_NAME}" \ + dist/release/*.tar.gz \ + dist/release/SHA256SUMS \ + --title "DevRail Router ${GITHUB_REF_NAME}" \ + --notes "Versioned DevRail Router tarballs and checksums for pinned Linux/macOS installs." diff --git a/Makefile b/Makefile index 7546eec..2b38159 100644 --- a/Makefile +++ b/Makefile @@ -27,6 +27,7 @@ VAGRANT_DESTROY ?= 1 DIST_DIR ?= dist BIN_DIR ?= bin PACKAGE_NAME := devrail-router_$(VERSION)_$(GOOS)_$(GOARCH) +RELEASE_TARGETS ?= linux/amd64 linux/arm64 darwin/arm64 DOCKER_RUN := docker run --rm \ -v "$$(pwd):/workspace" \ @@ -54,7 +55,7 @@ HAS_RUST := $(filter rust,$(LANGUAGES)) # --------------------------------------------------------------------------- # .PHONY declarations # --------------------------------------------------------------------------- -.PHONY: help build clean docker-build docker-smoke lint format fix package package-smoke test security scan docs changelog check install-hooks init vagrant-smoke +.PHONY: help build clean docker-build docker-smoke lint format fix package package-smoke release-artifacts test security scan docs changelog check install-hooks init vagrant-smoke .PHONY: _lint _format _fix _test _security _scan _docs _changelog _check _check-config _init # =========================================================================== @@ -161,6 +162,22 @@ package-smoke: package ## Build and smoke-test the tarball package bash -n "$$tmp_dir/$(PACKAGE_NAME)/packaging/linux/install.sh"; \ test -f "$$tmp_dir/$(PACKAGE_NAME)/packaging/systemd/devrail-router.service" +release-artifacts: ## Build versioned release tarballs and SHA256SUMS + @rm -rf "$(DIST_DIR)/release" + @mkdir -p "$(DIST_DIR)/release" + @set -e; \ + for target in $(RELEASE_TARGETS); do \ + goos=$${target%/*}; \ + goarch=$${target#*/}; \ + $(MAKE) package VERSION="$(VERSION)" GOOS="$$goos" GOARCH="$$goarch" DIST_DIR="$(DIST_DIR)/release" BIN_DIR="$(BIN_DIR)/$$goos-$$goarch"; \ + done; \ + cd "$(DIST_DIR)/release"; \ + if command -v sha256sum >/dev/null 2>&1; then \ + sha256sum *.tar.gz > SHA256SUMS; \ + else \ + shasum -a 256 *.tar.gz > SHA256SUMS; \ + fi + scan: ## Run universal scanners (trivy, gitleaks) $(DOCKER_RUN) make _scan diff --git a/docs/packaging.md b/docs/packaging.md index 029f9af..13f3a67 100644 --- a/docs/packaging.md +++ b/docs/packaging.md @@ -27,6 +27,23 @@ Build a Linux AMD64 tarball and run package smoke checks: make package-smoke GOOS=linux GOARCH=amd64 ``` +Build the full release artifact set: + +```sh +make release-artifacts VERSION=0.1.0 +``` + +The release set currently builds: + +- `linux/amd64` +- `linux/arm64` +- `darwin/arm64` +- `SHA256SUMS` + +Tagged releases matching `v*.*.*` publish these artifacts to GitHub Releases. +Downstream automation should pin a tag and checksum instead of installing from +GitHub Actions artifacts. + The generated archive is written to `dist/` with this layout: ```text @@ -157,3 +174,32 @@ macOS support should arrive after the Linux service is stable: - launchd plist - LM Studio adapter using macOS paths - no local GPU assumptions for the first macOS release + +## Future Package Managers + +Native package-manager support should build on the release tarballs rather than +replace them. The tarballs are the stable payload; package managers add metadata, +dependency checks, service hooks, and update UX. + +Prerequisites for apt, rpm, and Homebrew: + +- Immutable SemVer tags such as `v0.1.0`. +- Reproducible release artifacts for each supported OS/architecture. +- `SHA256SUMS` published with every release. +- Stable install paths: `/usr/local/bin/devrail-router`, + `/etc/devrail/router.yaml`, `/var/lib/devrail-router`, and systemd unit name + `devrail-router.service`. +- Upgrade-safe config handling that never overwrites local config unless + explicitly requested. +- Package smoke tests that install, start, health-check, restart, and remove the + service on a fresh Linux system. +- Signed releases before public package repositories are advertised. + +Recommended packaging order: + +1. GitHub Release tarballs plus checksums. +2. Ansible role consuming pinned release artifacts. +3. Debian package generated from the same payload, probably with `nfpm`. +4. RPM package generated from the same payload. +5. Homebrew tap formula for macOS ARM and Linuxbrew users. +6. Omarchy plugin that installs/configures DevRail Router from a pinned release.