# Forgejo Actions build + release for brick. # # Requires act_runner(s) registered on git.trevon.dev with label # `ubuntu-latest` (Linux). The macOS job is gated behind a manual # workflow_dispatch input because it needs a runner labelled `macos-latest` # (register one on a Mac, then run this workflow with "Build macOS packages" # checked — or change the gate to always-on). # # - push / PR: build, test, lint, upload artifacts (Linux) # - workflow_dispatch + build_macos=true: macOS build (needs macos-latest runner) # - tag v*: build Linux (and macOS if enabled), create a Forgejo release, # attach tarballs # # Release tarball naming: brick---.tar.gz # os: linux | macos # arch: x86_64 | aarch64 name: build on: push: branches: [main, master] tags: ["v*"] pull_request: workflow_dispatch: inputs: build_macos: description: Build macOS packages (requires macos-latest runner) type: boolean default: false permissions: contents: read concurrency: group: build-${{ github.ref }} cancel-in-progress: true jobs: build-linux: runs-on: ubuntu-latest steps: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - name: Install Rust toolchain run: | set -euxo pipefail if ! command -v rustup >/dev/null 2>&1; then curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o /tmp/rustup-init.sh sh /tmp/rustup-init.sh -y --profile minimal --default-toolchain none # shellcheck disable=SC1091 . "$HOME/.cargo/env" fi rustup toolchain install nightly-2026-05-28 --profile minimal --component clippy --component rustfmt rustup override set nightly-2026-05-28 echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" - name: Quality gate (fmt + test + clippy) run: ./scripts/quality-gate.sh - name: Build release binary run: cargo build --release --locked - name: Smoke run: | ./target/release/brick --help | head -5 ./target/release/brick build . --json /tmp/brick-smoke.json test -s /tmp/brick-smoke.json && echo "smoke ok" - name: Package run: | set -euo pipefail VERSION="${GITHUB_REF_NAME#v}" [ -n "$VERSION" ] || VERSION="$(git describe --tags --always 2>/dev/null || echo dev)" case "$RUNNER_OS" in Linux) OS=linux ;; macOS) OS=macos ;; esac case "$(uname -m)" in x86_64) ARCH=x86_64 ;; arm64) ARCH=aarch64 ;; esac NAME="brick-${VERSION}-${OS}-${ARCH}" mkdir -p "dist/${NAME}" cp target/release/brick "dist/${NAME}/" cp README.md "dist/${NAME}/" 2>/dev/null || true cp LICENSE* "dist/${NAME}/" 2>/dev/null || true (cd dist && tar czf "${NAME}.tar.gz" "${NAME}") (cd dist && shasum -a 256 "${NAME}.tar.gz" > "SHA256SUMS-${NAME}.txt") ls -la dist/ - uses: https://code.forgejo.org/forgejo/upload-artifact@16871d9e8cfcf27ff31822cac382bbb5450f1e1e # v4 with: name: brick-${{ runner.os }}-${{ runner.arch }} path: dist/ if-no-files-found: error build-macos: if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.build_macos == 'true' }} runs-on: macos-latest steps: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - name: Install Rust toolchain run: | set -euxo pipefail if ! command -v rustup >/dev/null 2>&1; then curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o /tmp/rustup-init.sh sh /tmp/rustup-init.sh -y --profile minimal --default-toolchain none # shellcheck disable=SC1091 . "$HOME/.cargo/env" fi rustup toolchain install nightly-2026-05-28 --profile minimal --component clippy --component rustfmt rustup override set nightly-2026-05-28 echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" - name: Build release binary run: cargo build --release --locked - name: Package run: | set -euo pipefail VERSION="${GITHUB_REF_NAME#v}" [ -n "$VERSION" ] || VERSION="$(git describe --tags --always 2>/dev/null || echo dev)" case "$RUNNER_OS" in Linux) OS=linux ;; macOS) OS=macos ;; esac case "$(uname -m)" in x86_64) ARCH=x86_64 ;; arm64) ARCH=aarch64 ;; esac NAME="brick-${VERSION}-${OS}-${ARCH}" mkdir -p "dist/${NAME}" cp target/release/brick "dist/${NAME}/" cp README.md "dist/${NAME}/" 2>/dev/null || true cp LICENSE* "dist/${NAME}/" 2>/dev/null || true (cd dist && tar czf "${NAME}.tar.gz" "${NAME}") (cd dist && shasum -a 256 "${NAME}.tar.gz" > "SHA256SUMS-${NAME}.txt") ls -la dist/ - uses: https://code.forgejo.org/forgejo/upload-artifact@16871d9e8cfcf27ff31822cac382bbb5450f1e1e # v4 with: name: brick-${{ runner.os }}-${{ runner.arch }} path: dist/ if-no-files-found: error release: if: startsWith(github.ref, 'refs/tags/') needs: [build-linux, build-macos] runs-on: ubuntu-latest permissions: contents: write steps: - uses: https://code.forgejo.org/forgejo/download-artifact@d8d0a99033603453ad2255e58720b460a0555e1e # v4 with: path: dist merge-multiple: true - name: Create Forgejo release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | set -euo pipefail TAG="${GITHUB_REF_NAME}" curl -fsS -X POST "https://git.trevon.dev/api/v1/repos/${GITHUB_REPOSITORY}/releases" \ -H "Authorization: token ${GITHUB_TOKEN}" \ -H "Content-Type: application/json" \ -d "{\"tag_name\":\"${TAG}\",\"name\":\"${TAG}\",\"draft\":false,\"prerelease\":false}" \ > /tmp/release.json || { curl -fsS "https://git.trevon.dev/api/v1/repos/${GITHUB_REPOSITORY}/releases/tags/${TAG}" \ -H "Authorization: token ${GITHUB_TOKEN}" > /tmp/release.json } RELEASE_ID="$(python3 -c "import json;print(json.load(open('/tmp/release.json'))['id'])")" echo "release id: ${RELEASE_ID}" for f in dist/*.tar.gz; do [ -f "$f" ] || continue echo "uploading $(basename "$f")" curl -fsS -X POST "https://git.trevon.dev/api/v1/repos/${GITHUB_REPOSITORY}/releases/${RELEASE_ID}/assets?name=$(basename "$f")" \ -H "Authorization: token ${GITHUB_TOKEN}" \ -H "Content-Type: application/octet-stream" \ --data-binary "@$f" done for f in dist/SHA256SUMS-*.txt; do [ -f "$f" ] || continue curl -fsS -X POST "https://git.trevon.dev/api/v1/repos/${GITHUB_REPOSITORY}/releases/${RELEASE_ID}/assets?name=$(basename "$f")" \ -H "Authorization: token ${GITHUB_TOKEN}" \ -H "Content-Type: text/plain" \ --data-binary "@$f" done echo "release ${TAG} ready"