fold/.forgejo/workflows/build.yml
trvon 1ec7f71690
Some checks failed
build / build-linux (push) Failing after 7m32s
build / build-macos (push) Has been cancelled
build / release (push) Has been cancelled
ci: use Forgejo artifact actions; disable unsupported cache
2026-08-30 10:34:24 -06:00

303 lines
11 KiB
YAML

# Forgejo Actions build + release for fold (port of .github/workflows/build.yml).
#
# 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 (Meson+Conan, clang-19), test, coverage floor, smoke,
# upload artifacts (Linux)
# - workflow_dispatch + build_macos=true: macOS build (llvm@22)
# - tag v*: build Linux (and macOS if enabled), create a Forgejo release,
# attach tarballs
#
# Release tarball naming: fold-<version>-<os>-<arch>.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 system deps (linux)
run: |
sudo apt-get update
sudo apt-get install -y \
clang-19 \
llvm-19-dev \
libclang-19-dev \
libclang-cpp19-dev \
libz3-dev libsqlite3-dev \
meson ninja-build pkg-config cmake build-essential \
nlohmann-json3-dev \
libcli11-dev libspdlog-dev libfmt-dev
{
echo "CC=clang-19"
echo "CXX=clang++-19"
echo "LLVM_CONFIG=llvm-config-19"
} >> "$GITHUB_ENV"
- name: Set up Python (for Conan)
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: "3.12"
- name: Install Conan
run: |
python -m pip install --upgrade pip
python -m pip install 'conan>=2,<3'
conan profile detect --force
- name: Install Rust frontend toolchains
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 \
--component rustc-dev --component rustfmt --component llvm-tools-preview
# A newer target nightly exercises Cargo/analyzer skew when available.
# The validation artifact records an explicit skip if it is not newer.
rustup toolchain install nightly-2026-07-28
rustup run nightly-2026-05-28 rustc -Vv
rustup run nightly-2026-07-28 rustc -Vv
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- name: Configure and compile through setup.sh
run: ./setup.sh release
- name: Test
run: meson test -C build/release --print-errorlogs
- name: Set up uv for coverage
uses: astral-sh/setup-uv@e58605a9b6da7c637471fab8847a5e5a6b8df081 # v5
- name: Enforce reviewed coverage floor
env:
COVERAGE_MIN_LINE: "70"
run: ./scripts/coverage.sh
- name: Smoke
run: |
./build/release/src/cli/fold --version
./build/release/src/cli/fold scan \
tests/fixtures/clones \
--std c++20 \
--detectors clone \
--format markdown --output fold-smoke.md \
--processes 1
head -30 fold-smoke.md
- name: Generate quality report
run: |
./build/release/src/cli/fold quality \
--skip-format --skip-tests --skip-policy --skip-diff-scan \
--out-dir quality-report
- name: Package release tarball
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="fold-${VERSION}-${OS}-${ARCH}"
mkdir -p "dist/${NAME}"
cp build/release/src/cli/fold "dist/${NAME}/fold"
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/
- name: Upload smoke report
if: always()
uses: https://code.forgejo.org/forgejo/upload-artifact@16871d9e8cfcf27ff31822cac382bbb5450f1e1e # v4
with:
name: smoke-${{ runner.os }}
path: fold-smoke.md
if-no-files-found: ignore
- name: Upload quality report
if: always()
uses: https://code.forgejo.org/forgejo/upload-artifact@16871d9e8cfcf27ff31822cac382bbb5450f1e1e # v4
with:
name: quality-${{ runner.os }}
path: quality-report/
if-no-files-found: ignore
- name: Upload Rust toolchain evidence
if: always()
uses: https://code.forgejo.org/forgejo/upload-artifact@16871d9e8cfcf27ff31822cac382bbb5450f1e1e # v4
with:
name: rust-toolchain-${{ runner.os }}
path: build/release/meson-logs/rust-toolchain-skew.json
if-no-files-found: ignore
- name: Upload package
uses: https://code.forgejo.org/forgejo/upload-artifact@16871d9e8cfcf27ff31822cac382bbb5450f1e1e # v4
with:
name: fold-${{ 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 system deps (macos)
run: |
brew update
brew install llvm@22 z3 meson ninja pkg-config nlohmann-json cli11 spdlog
echo "LLVM_CONFIG=$(brew --prefix llvm@22)/bin/llvm-config" >> "$GITHUB_ENV"
echo "PKG_CONFIG_PATH=$(brew --prefix z3)/lib/pkgconfig:$(brew --prefix)/lib/pkgconfig" >> "$GITHUB_ENV"
- name: Set up Python (for Conan)
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: "3.12"
- name: Install Conan
run: |
python -m pip install --upgrade pip
python -m pip install 'conan>=2,<3'
conan profile detect --force
- name: Install Rust frontend toolchains
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 \
--component rustc-dev --component rustfmt --component llvm-tools-preview
rustup toolchain install nightly-2026-07-28
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- name: Configure and compile through setup.sh
run: ./setup.sh release
- name: Test
run: meson test -C build/release --print-errorlogs
- name: Smoke
run: |
./build/release/src/cli/fold --version
./build/release/src/cli/fold scan \
tests/fixtures/clones \
--std c++20 \
--detectors clone \
--format markdown --output fold-smoke.md \
--processes 1
head -30 fold-smoke.md
- name: Package release tarball
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="fold-${VERSION}-${OS}-${ARCH}"
mkdir -p "dist/${NAME}"
cp build/release/src/cli/fold "dist/${NAME}/fold"
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: fold-${{ 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"