Skip to content

self_review

self_review #2714

Workflow file for this run

name: Bencher
on:
workflow_dispatch:
push:
branches: [main, cloud, devel]
tags: [v**]
pull_request:
branches: [main, cloud, devel]
env:
# General
CARGO_TERM_COLOR: always
MOLD_VERSION: 2.34.1
GITHUB_REGISTRY: ghcr.io
DOCKER_HUB_ORGANIZATION: bencherdev
# API
API_DOCKER_IMAGE: bencher-api
LITESTREAM_VERSION: 0.3.13
LITESTREAM_ARCH: amd64
FLY_REGISTRY: registry.fly.io
# CLI
CLI_BIN_NAME: bencher
ZIG_VERSION: 0.13.0
ZIG_BUILD_VERSION: 0.19.3
# Use minimum supported glibc version for Rust Tier 1
# https://doc.rust-lang.org/nightly/rustc/platform-support.html#tier-1-with-host-tools
GLIBC_VERSION: 2.17
# WASM
WASM_BENCHER_VALID: bencher-valid-pkg
# Console
CONSOLE_DOCKER_IMAGE: bencher-console
# Dev Container
DEV_CONTAINER_DOCKER_IMAGE: bencher-dev-container
# Cache
CACHE_NAME: ${{ ((github.ref == 'refs/heads/main' || github.ref == 'refs/heads/cloud' || github.ref == 'refs/heads/devel' || startsWith(github.ref, 'refs/tags/')) && github.ref_name) || (github.event_name == 'pull_request' && github.event.number) }}
jobs:
# Bencher CLI GitHub Action
build_github_action:
name: Build GitHub Action
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Bencher CLI GitHub Action Dependencies
working-directory: ./services/action
run: npm install --include=dev
- name: Build Bencher CLI GitHub Action
working-directory: ./services/action
run: npm run build
- name: Check for changes
continue-on-error: ${{ !startsWith(github.ref, 'refs/tags/') }}
run: git diff --exit-code
test_cli_install:
name: Test CLI Install
strategy:
fail-fast: false
matrix:
include:
# Linux
- os: ubuntu-latest
source: action-main
- os: ubuntu-latest
source: action-devel
- os: ubuntu-latest
source: script-cloud
- os: ubuntu-latest
source: script-gen
- os: ubuntu-latest
source: cargo-main
- os: ubuntu-latest
source: cargo-devel
# MacOS
- os: macos-latest
source: action-main
- os: macos-latest
source: action-devel
- os: macos-latest
source: script-cloud
- os: macos-latest
source: script-gen
- os: macos-latest
source: cargo-main
- os: macos-latest
source: cargo-devel
# Windows
- os: windows-latest
source: action-main
- os: windows-latest
source: action-devel
- os: windows-latest
source: script-cloud
- os: windows-latest
source: script-gen
- os: windows-latest
source: cargo-main
- os: windows-latest
source: cargo-devel
runs-on: ${{ matrix.os }}
# This is expected to fail when tagging a new release
continue-on-error: ${{ startsWith(github.ref, 'refs/tags/') && ( matrix.source == 'action-devel' || matrix.source == 'cargo-devel' || matrix.source == 'cargo-main' ) }}
steps:
- uses: bencherdev/bencher@main
if: matrix.source == 'action-main'
- uses: bencherdev/bencher@devel
if: matrix.source == 'action-devel'
- name: Unix CLI Download Install Script
if: matrix.source == 'script-cloud' && matrix.os != 'windows-latest'
run: curl --proto '=https' --tlsv1.2 -sSfL https://bencher.dev/download/install-cli.sh | sh
- name: Windows CLI Download Install Script
if: matrix.source == 'script-cloud' && matrix.os == 'windows-latest'
run: irm https://bencher.dev/download/install-cli.ps1 | iex
- uses: actions/checkout@v4
if: matrix.source == 'script-gen'
- name: Unix CLI Install Script
if: matrix.source == 'script-gen' && matrix.os != 'windows-latest'
run: cat services/cli/templates/output/install-cli.sh | sh
- name: Windows CLI Install Script
if: matrix.source == 'script-gen' && matrix.os == 'windows-latest'
run: gc -Raw services/cli/templates/output/install-cli.ps1 | iex
- name: Cargo CLI Install main
if: matrix.source == 'cargo-main'
run: cargo install --git https://github.com/bencherdev/bencher --branch main --locked bencher_cli
- name: Cargo CLI Install devel
if: matrix.source == 'cargo-devel'
run: cargo install --git https://github.com/bencherdev/bencher --branch devel --locked bencher_cli
- name: Run current Bencher CLI GitHub Action
run: bencher run --project bencher --token ${{ secrets.BENCHER_API_TOKEN }} --dry-run "bencher mock"
# Pretty Rust
cargo_fmt:
name: Cargo Format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Add fmt
run: rustup component add rustfmt
- name: Run fmt
run: cargo fmt -- --check
cargo_clippy:
name: Cargo Clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/cache@v4
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/cloud' || github.ref == 'refs/heads/devel' || startsWith(github.ref, 'refs/tags/') || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository)
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-all-features
- uses: rui314/setup-mold@v1
with:
mold-version: ${{ env.MOLD_VERSION }}
- name: Add clippy
run: rustup component add clippy
- name: Run clippy
run: cargo clippy --no-deps --all-features -- -Dwarnings
check_generated:
name: Check Generated
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: rui314/setup-mold@v1
with:
mold-version: ${{ env.MOLD_VERSION }}
- name: Generate OpenAPI Spec
run: cargo gen-spec
- name: Check OpenAPI Spec for changes
run: git diff --exit-code
- name: Generate Unix CLI install scripts
run: cargo gen-installer sh
- name: Check Unix CLI install script for changes
run: git diff --exit-code
- name: Generate Windows CLI install scripts
run: cargo gen-installer ps1
- name: Check Windows CLI install script for changes
run: git diff --exit-code
# Cargo Test
cargo_test:
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/cloud' || github.ref == 'refs/heads/devel' || startsWith(github.ref, 'refs/tags/') || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository)
name: Cargo Test
runs-on: ubuntu-latest
env:
TEST_BILLING_KEY: ${{ secrets.TEST_BILLING_KEY }}
steps:
- uses: actions/checkout@v4
- uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-all-features
- uses: rui314/setup-mold@v1
with:
mold-version: ${{ env.MOLD_VERSION }}
- name: cargo test
run: RUST_BACKTRACE=1 cargo test --all-features -- --nocapture
- name: Upload Perf JPEG
uses: actions/upload-artifact@v4
with:
name: perf.jpeg
path: ./lib/bencher_plot/perf.jpeg
if-no-files-found: error
cargo_test_pr:
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository
name: Cargo Test PR
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: rui314/setup-mold@v1
with:
mold-version: ${{ env.MOLD_VERSION }}
- name: cargo test
run: RUST_BACKTRACE=1 cargo test --all-features -- --nocapture
- name: Upload Perf JPEG
uses: actions/upload-artifact@v4
with:
name: perf.jpeg
path: ./lib/bencher_plot/perf.jpeg
if-no-files-found: error
# API Smoke Test
api_smoke_test:
name: API Smoke Test
runs-on: ubuntu-latest
steps:
- uses: jlumbroso/free-disk-space@main
with:
large-packages: false
- uses: actions/checkout@v4
- uses: actions/cache@v4
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/cloud' || github.ref == 'refs/heads/devel' || startsWith(github.ref, 'refs/tags/') || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository)
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-api
- uses: rui314/setup-mold@v1
with:
mold-version: ${{ env.MOLD_VERSION }}
- name: Run Smoke Test
run: cargo test-api smoke ci
release_api_smoke_test:
name: Release API Smoke Test
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
- os: macos-latest
- os: windows-latest
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: rui314/setup-mold@v1
if: matrix.os == 'ubuntu-latest'
with:
mold-version: ${{ env.MOLD_VERSION }}
- name: Run Smoke Test
run: cargo test-api smoke localhost
docker_api_smoke_test:
name: Docker API Smoke Test
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
# https://github.com/actions/runner-images/issues/17#issuecomment-614726536
# - os: macos-latest
# https://github.com/orgs/community/discussions/25491#discussioncomment-3248089
# - os: windows-latest
runs-on: ${{ matrix.os }}
steps:
- uses: jlumbroso/free-disk-space@main
with:
large-packages: false
- uses: actions/checkout@v4
- uses: rui314/setup-mold@v1
if: matrix.os == 'ubuntu-latest'
with:
mold-version: ${{ env.MOLD_VERSION }}
- name: Run Smoke Test
run: cargo test-api smoke docker
# Cargo Check (Minus)
cargo_check_api_minus:
name: Cargo Check API (Minus)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: rui314/setup-mold@v1
with:
mold-version: ${{ env.MOLD_VERSION }}
- name: cargo check
working-directory: ./services/api
run: cargo check --no-default-features
cargo_check_cli_minus:
name: Cargo Check CLI (Minus)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: rui314/setup-mold@v1
with:
mold-version: ${{ env.MOLD_VERSION }}
- name: cargo check
working-directory: ./services/cli
run: cargo check --no-default-features
# Cargo Benchmark
cargo_bench:
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/cloud' || github.ref == 'refs/heads/devel' || startsWith(github.ref, 'refs/tags/') || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository)
name: Cargo Bench
runs-on: ubuntu-latest
# This will fail whenever Bencher Cloud is down
# or there are any breaking changes to the report format
continue-on-error: true
steps:
- uses: actions/checkout@v4
- uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-cli
- uses: rui314/setup-mold@v1
with:
mold-version: ${{ env.MOLD_VERSION }}
- name: Install `bencher` CLI
run: cargo install --debug --path services/cli --locked --force
- name: Dogfooding Benchmarks with Bencher
run: |
bencher run \
--host https://api.bencher.dev \
--project bencher \
--token '${{ secrets.BENCHER_API_TOKEN }}' \
--branch "$GITHUB_REF_NAME" \
--start-point "$GITHUB_BASE_REF" \
--testbed ubuntu-latest \
--adapter rust_criterion \
--err \
--github-actions ${{ secrets.GITHUB_TOKEN }} \
cargo bench --package bencher_adapter
# Cargo Audit
cargo_audit:
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/cloud' || github.ref == 'refs/heads/devel' || startsWith(github.ref, 'refs/tags/') || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository)
name: Cargo Audit
runs-on: ubuntu-latest
continue-on-error: true
steps:
- uses: actions/checkout@v4
- uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-audit
- uses: rui314/setup-mold@v1
with:
mold-version: ${{ env.MOLD_VERSION }}
- run: cargo audit
# Cargo Unused Deps
cargo_udeps:
name: Cargo Unused Deps
runs-on: ubuntu-latest
continue-on-error: ${{ !startsWith(github.ref, 'refs/tags/') }}
steps:
- uses: actions/checkout@v4
- uses: actions/cache@v4
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/cloud' || github.ref == 'refs/heads/devel' || startsWith(github.ref, 'refs/tags/') || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository)
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-nightly
- uses: rui314/setup-mold@v1
with:
mold-version: ${{ env.MOLD_VERSION }}
- name: Install nightly toolchain
run: rustup toolchain install nightly
- name: Install udeps
run: cargo install --version 0.1.50 --locked --force cargo-udeps
- name: Run API udeps
continue-on-error: true
working-directory: ./services/api
run: cargo +nightly udeps --all-targets
- name: Run CLI udeps
continue-on-error: true
working-directory: ./services/cli
run: cargo +nightly udeps --all-targets
# Pretty JS
npx_biome_format:
name: Biome Format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Biome format Action
working-directory: ./services/action
run: |
npm install --include=dev
npx biome ci --linter-enabled false --organize-imports-enabled false .
- name: Biome format Console UI
working-directory: ./services/console
run: |
npm install --include=dev
npx biome ci --linter-enabled false --organize-imports-enabled false .
npx_biome_lint:
name: Biome Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Biome check Action
working-directory: ./services/action
run: |
npm install --include=dev
npx biome ci --formatter-enabled false --organize-imports-enabled false .
- name: Biome check Console UI
working-directory: ./services/console
run: |
npm install --include=dev
npx biome ci --formatter-enabled false --organize-imports-enabled false .
# UI WASM
build_bencher_valid_wasm:
name: Build `bencher_valid` WASM
runs-on: ubuntu-latest
env:
WASM_PACK_BUILD: "wasm-pack build --target web --no-default-features --features plus,wasm"
steps:
- uses: actions/checkout@v4
- uses: actions/cache@v4
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/cloud' || github.ref == 'refs/heads/devel' || startsWith(github.ref, 'refs/tags/') || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository)
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-wasm
- run: cargo install wasm-pack --version 0.12.1 --locked --force
- name: WASM pack `bencher_valid`
working-directory: ./lib/bencher_valid
run: |
$WASM_PACK_BUILD || \
$WASM_PACK_BUILD || \
$WASM_PACK_BUILD || \
$WASM_PACK_BUILD || \
$WASM_PACK_BUILD
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: ${{ env.WASM_BENCHER_VALID }}
path: ./lib/bencher_valid/pkg
if-no-files-found: error
test_bencher_valid_wasm:
name: Test `bencher_valid` WASM
runs-on: ubuntu-latest
needs: build_bencher_valid_wasm
steps:
- uses: actions/checkout@v4
- uses: actions/cache@v4
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/cloud' || github.ref == 'refs/heads/devel' || startsWith(github.ref, 'refs/tags/') || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository)
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-wasm
- uses: rui314/setup-mold@v1
with:
mold-version: ${{ env.MOLD_VERSION }}
- name: cargo test `bencher_valid` WASM
working-directory: ./lib/bencher_valid
run: cargo test --no-default-features --features plus,wasm
# NPM Test
npx_vitest:
name: vitest
runs-on: ubuntu-latest
needs: build_bencher_valid_wasm
steps:
- uses: actions/checkout@v4
- name: Download `bencher_valid` Artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.WASM_BENCHER_VALID }}
path: ./lib/bencher_valid/pkg
- name: npx vitest
working-directory: ./services/console
run: |
npm install --include=dev
npx vitest run
# API Docker
# https://docs.docker.com/build/ci/github-actions/named-contexts/#using-with-a-container-builder
# https://www.kenmuse.com/blog/implementing-docker-layer-caching-in-github-actions/
build_api_docker:
name: Build API Docker
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Setup Docker buildx
uses: docker/setup-buildx-action@v3
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.GITHUB_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build API Docker Image
uses: docker/build-push-action@v5
with:
context: .
file: ./services/api/Dockerfile
tags: ${{ env.API_DOCKER_IMAGE }}
build-args: |
MOLD_VERSION=${{ env.MOLD_VERSION }}
LITESTREAM_VERSION=${{ env.LITESTREAM_VERSION }}
LITESTREAM_ARCH=${{ env.LITESTREAM_ARCH }}
cache-from: type=registry,ref=${{ env.GITHUB_REGISTRY }}/${{ github.repository_owner }}/${{ env.API_DOCKER_IMAGE }}:cache-${{ env.CACHE_NAME }}
cache-to: type=registry,ref=${{ env.GITHUB_REGISTRY }}/${{ github.repository_owner }}/${{ env.API_DOCKER_IMAGE }}:cache-${{ env.CACHE_NAME }},mode=max
load: true
push: false
- name: Save API Docker Image
run: |
docker save ${{ env.API_DOCKER_IMAGE }} \
| gzip > ${{ env.API_DOCKER_IMAGE }}.tar.gz
- name: Upload API Docker Image Artifact
uses: actions/upload-artifact@v4
with:
name: ${{ env.API_DOCKER_IMAGE }}.tar.gz
path: ./${{ env.API_DOCKER_IMAGE }}.tar.gz
if-no-files-found: error
# CLI
build_cli:
name: Build CLI
strategy:
fail-fast: false
matrix:
include:
# Linux
- build: linux-x86-64
os: ubuntu-latest
target: x86_64-unknown-linux-gnu
- build: linux-arm-64
os: ubuntu-latest
target: aarch64-unknown-linux-gnu
# MacOS
- build: macos-x86-64
os: macos-latest
target: x86_64-apple-darwin
- build: macos-arm-64
os: macos-latest
target: aarch64-apple-darwin
# Windows
- build: windows-x86-64
os: windows-latest
target: x86_64-pc-windows-msvc
- build: windows-arm-64
os: windows-latest
target: aarch64-pc-windows-msvc
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
# Install
- name: Install Rust target
run: rustup target add ${{ matrix.target }}
- uses: mlugg/setup-zig@v1
if: startsWith(matrix.build, 'linux')
with:
version: ${{ env.ZIG_VERSION }}
- name: Install zigbuild
if: startsWith(matrix.build, 'linux')
run: cargo install --version ${{ env.ZIG_BUILD_VERSION }} --locked --force cargo-zigbuild
# Build
- name: cargo zigbuild Linux CLI
if: startsWith(matrix.build, 'linux')
working-directory: ./services/cli
run: cargo zigbuild --profile release-small --target ${{ matrix.target }}.${{ env.GLIBC_VERSION }}
- name: cargo zigbuild macos CLI
if: startsWith(matrix.build, 'macos')
working-directory: ./services/cli
run: cargo build --profile release-small --target ${{ matrix.target }}
- name: cargo build Windows CLI
if: startsWith(matrix.build, 'windows')
working-directory: ./services/cli
run: cargo build --profile release-small --target ${{ matrix.target }}
# Rename
- name: Rename Unix CLI bin
if: (!startsWith(matrix.build, 'windows'))
run: mv ./target/${{ matrix.target }}/release-small/${{ env.CLI_BIN_NAME }} ${{ env.CLI_BIN_NAME }}-${{ github.ref_name }}-${{ matrix.build }}
- name: Rename Windows CLI bin
if: startsWith(matrix.build, 'windows')
run: mv ./target/${{ matrix.target }}/release-small/${{ env.CLI_BIN_NAME }}.exe ${{ env.CLI_BIN_NAME }}-${{ github.ref_name }}-${{ matrix.build }}.exe
# Upload
- name: Upload Unix CLI Artifact
if: (!startsWith(matrix.build, 'windows'))
uses: actions/upload-artifact@v4
with:
name: ${{ env.CLI_BIN_NAME }}-${{ github.ref_name }}-${{ matrix.build }}
path: ${{ env.CLI_BIN_NAME }}-${{ github.ref_name }}-${{ matrix.build }}
if-no-files-found: error
- name: Upload Windows CLI Artifact
if: startsWith(matrix.build, 'windows')
uses: actions/upload-artifact@v4
with:
name: ${{ env.CLI_BIN_NAME }}-${{ github.ref_name }}-${{ matrix.build }}.exe
path: ${{ env.CLI_BIN_NAME }}-${{ github.ref_name }}-${{ matrix.build }}.exe
if-no-files-found: error
package_cli:
name: Package CLI
strategy:
fail-fast: false
matrix:
include:
# Linux
- build: linux-x86-64
os: ubuntu-latest
target: x86_64-unknown-linux-gnu
arch: amd64
- build: linux-arm-64
os: ubuntu-latest
target: aarch64-unknown-linux-gnu
arch: arm64
runs-on: ${{ matrix.os }}
needs: build_cli
env:
CLI_DEB_DIR: deb
steps:
- uses: actions/checkout@v4
- name: Download CLI Artifact
if: (!startsWith(matrix.build, 'windows'))
uses: actions/download-artifact@v4
with:
name: ${{ env.CLI_BIN_NAME }}-${{ github.ref_name }}-${{ matrix.build }}
- uses: rui314/setup-mold@v1
if: startsWith(matrix.build, 'linux')
with:
mold-version: ${{ env.MOLD_VERSION }}
# Debian .deb
- name: Build .deb package
if: startsWith(matrix.build, 'linux')
run: cargo gen-pkg deb --dir ${{ env.CLI_DEB_DIR }} --arch ${{ matrix.arch }} ${{ env.CLI_BIN_NAME }}-${{ github.ref_name }}-${{ matrix.build }}
- name: Test install .deb package
if: matrix.build == 'linux-x86-64'
run: sudo dpkg -i ${{ env.CLI_DEB_DIR }}/${{ env.CLI_BIN_NAME }}-${{ github.ref_name }}-${{ matrix.build }}.deb
- name: Sanity test .deb package installation
if: matrix.build == 'linux-x86-64'
run: |
bencher --version
bencher mock
man bencher
- name: Upload .deb Artifact
if: startsWith(matrix.build, 'linux')
uses: actions/upload-artifact@v4
with:
name: ${{ env.CLI_BIN_NAME }}-${{ github.ref_name }}-${{ matrix.build }}.deb
path: ${{ env.CLI_DEB_DIR }}/${{ env.CLI_BIN_NAME }}-${{ github.ref_name }}-${{ matrix.build }}.deb
if-no-files-found: error
build_console_docker:
name: Build Console Docker
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Setup Docker buildx
uses: docker/setup-buildx-action@v3
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.GITHUB_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build Console Docker Image
uses: docker/build-push-action@v5
with:
context: .
file: ./services/console/Dockerfile
tags: ${{ env.CONSOLE_DOCKER_IMAGE }}
cache-from: type=registry,ref=${{ env.GITHUB_REGISTRY }}/${{ github.repository_owner }}/${{ env.CONSOLE_DOCKER_IMAGE }}:cache-${{ env.CACHE_NAME }}
cache-to: type=registry,ref=${{ env.GITHUB_REGISTRY }}/${{ github.repository_owner }}/${{ env.CONSOLE_DOCKER_IMAGE }}:cache-${{ env.CACHE_NAME }},mode=max
load: true
push: false
- name: Save Console Docker Image
run: |
docker save ${{ env.CONSOLE_DOCKER_IMAGE }} \
| gzip > ${{ env.CONSOLE_DOCKER_IMAGE }}.tar.gz
- name: Upload Console Docker Image Artifact
uses: actions/upload-artifact@v4
with:
name: ${{ env.CONSOLE_DOCKER_IMAGE }}.tar.gz
path: ./${{ env.CONSOLE_DOCKER_IMAGE }}.tar.gz
if-no-files-found: error
build_console:
if: (!startsWith(github.ref, 'refs/tags/'))
name: Build Console UI
runs-on: ubuntu-latest
needs: build_bencher_valid_wasm
steps:
- uses: actions/checkout@v4
- name: Download `bencher_valid` Artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.WASM_BENCHER_VALID }}
path: ./lib/bencher_valid/pkg
- name: Build Console UI
working-directory: ./services/console
run: npm run netlify
- name: Test Links
continue-on-error: true
uses: lycheeverse/[email protected]
with:
args: --config ./services/console/lychee.toml ./services/console/dist
# API Fly.io
deploy_api_fly_dev:
if: github.ref == 'refs/heads/devel'
name: Deploy API to Fly.io Dev
runs-on: ubuntu-latest
needs:
- build_api_docker
- build_console
env:
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
steps:
- uses: actions/checkout@v4
- name: Download Local Artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.API_DOCKER_IMAGE }}.tar.gz
- name: Load & Tag Local Image
run: |
docker load < ${{ env.API_DOCKER_IMAGE }}.tar.gz
docker tag ${{ env.API_DOCKER_IMAGE }} ${{ env.FLY_REGISTRY }}/bencher-api-dev
- uses: superfly/flyctl-actions/setup-flyctl@master
- name: Deploy Local API to Fly.io
working-directory: ./services/api
run: flyctl deploy --local-only --config fly/fly.dev.toml --wait-timeout 300
- uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-cli
- uses: rui314/setup-mold@v1
with:
mold-version: ${{ env.MOLD_VERSION }}
- name: Run Smoke Test
run: cargo test-api smoke dev
deploy_api_fly_test:
if: github.ref == 'refs/heads/cloud' || github.ref == 'refs/heads/devel'
name: Deploy API to Fly.io Test
runs-on: ubuntu-latest
needs: build_api_docker
env:
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
steps:
- uses: actions/checkout@v4
- name: Download Litestream Artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.API_DOCKER_IMAGE }}.tar.gz
- name: Load & Tag Litestream Image
run: |
docker load < ${{ env.API_DOCKER_IMAGE }}.tar.gz
docker tag ${{ env.API_DOCKER_IMAGE }} ${{ env.FLY_REGISTRY }}/bencher-api-test
- uses: superfly/flyctl-actions/setup-flyctl@master
- name: Deploy Litestream API to Fly.io Test
working-directory: ./services/api
run: flyctl deploy --local-only --config fly/fly.test.toml --wait-timeout 300
- uses: rui314/setup-mold@v1
with:
mold-version: ${{ env.MOLD_VERSION }}
- name: Run Smoke Test
run: cargo test-api smoke test
backup_database:
if: github.ref == 'refs/heads/cloud'
name: Backup Database
runs-on: ubuntu-latest
# This will fail whenever Bencher Cloud is down
continue-on-error: true
timeout-minutes: 5
needs:
# Lint
- cargo_fmt
- cargo_clippy
- npx_biome_format
- npx_biome_lint
- check_generated
# Test
- cargo_test
- api_smoke_test
- cargo_bench
- test_bencher_valid_wasm
- npx_vitest
# Build
- build_api_docker
- build_console
steps:
- uses: actions/checkout@v4
- uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-cli
- uses: rui314/setup-mold@v1
with:
mold-version: ${{ env.MOLD_VERSION }}
- name: Install `bencher` CLI
run: cargo install --debug --path services/cli --locked --force
- name: Backup API Server Database
run: |
bencher server backup \
--host https://api.bencher.dev \
--token ${{ secrets.BENCHER_API_TOKEN_ADMIN }} \
--compress \
--data-store aws_s3 \
--rm
deploy_api_fly:
name: Deploy API to Fly.io Prod
runs-on: ubuntu-latest
needs:
- deploy_api_fly_test
- backup_database
env:
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download Litestream Artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.API_DOCKER_IMAGE }}.tar.gz
- name: Load & Tag Litestream Image
run: |
docker load < ${{ env.API_DOCKER_IMAGE }}.tar.gz
docker tag ${{ env.API_DOCKER_IMAGE }} ${{ env.FLY_REGISTRY }}/bencher-api
- uses: superfly/flyctl-actions/setup-flyctl@master
- name: Deploy API to Fly.io Prod
working-directory: ./services/api
run: flyctl deploy --local-only --config fly/fly.toml --wait-timeout 300
- name: Rebase main on cloud
run: |
git fetch origin cloud
git checkout cloud
git pull
git fetch origin main
git checkout main
git pull
git rebase origin/cloud
git push
# UI Netlify
deploy_console_netlify_dev:
name: Deploy Console UI to Netlify Dev
runs-on: ubuntu-latest
needs: deploy_api_fly_dev
steps:
- uses: actions/checkout@v4
- name: Download `bencher_valid` Artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.WASM_BENCHER_VALID }}
path: ./lib/bencher_valid/pkg
- name: Build Console UI
working-directory: ./services/console
run: npm run netlify
- name: Install Netlify CLI
run: npm install --save-dev [email protected]
- name: Deploy Console UI to Netlify Dev
env:
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
DEPLOY_MESSAGE: "${{ github.event.head_commit.message }}"
run: |
npx netlify-cli \
deploy \
--alias ${GITHUB_REF#refs/*/} \
--message "$DEPLOY_MESSAGE" \
--json \
| tee netlify.json
- uses: rui314/setup-mold@v1
with:
mold-version: ${{ env.MOLD_VERSION }}
- name: Run Netlify Dev Test
run: cargo test-netlify dev ${{ github.ref_name }}
deploy_console_netlify:
name: Deploy Console UI to Netlify Prod
runs-on: ubuntu-latest
needs: deploy_api_fly
steps:
- uses: actions/checkout@v4
- name: Download `bencher_valid` Artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.WASM_BENCHER_VALID }}
path: ./lib/bencher_valid/pkg
- name: Build Console UI
working-directory: ./services/console
run: npm run netlify
- name: Install Netlify CLI
run: npm install --save-dev [email protected]
- name: Deploy Console UI to Netlify
env:
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
DEPLOY_MESSAGE: "${{ github.event.head_commit.message }}"
run: |
npx netlify-cli \
deploy \
--prod \
--alias ${GITHUB_REF#refs/*/} \
--message "$DEPLOY_MESSAGE" \
--json \
| tee netlify.json
- uses: rui314/setup-mold@v1
with:
mold-version: ${{ env.MOLD_VERSION }}
- name: Run Netlify Test
run: cargo test-netlify prod ${{ github.ref_name }}
# Release
release_bencher:
if: startsWith(github.ref, 'refs/tags/')
name: Release Bencher
runs-on: ubuntu-latest
needs:
# Lint
- cargo_fmt
- cargo_clippy
- npx_biome_format
- npx_biome_lint
- check_generated
# Test
- cargo_test
- api_smoke_test
- release_api_smoke_test
- cargo_check_api_minus
- cargo_check_cli_minus
- cargo_bench
- cargo_audit
- cargo_udeps
- test_bencher_valid_wasm
- npx_vitest
# Integrations
- build_github_action
# Build
- build_api_docker
- build_console_docker
- package_cli
env:
BUILD_LINUX_X86_64: linux-x86-64
BUILD_LINUX_ARM_64: linux-arm-64
BUILD_MACOS_X86_64: macos-x86-64
BUILD_MACOS_ARM_64: macos-arm-64
BUILD_WINDOWS_X86_64: windows-x86-64
BUILD_WINDOWS_ARM_64: windows-arm-64
steps:
- uses: actions/checkout@v4
# Download Docker
- name: Download API Docker Artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.API_DOCKER_IMAGE }}.tar.gz
- name: Download Console Docker Artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.CONSOLE_DOCKER_IMAGE }}.tar.gz
# Download CLI
- name: Download CLI Linux x86_64 Artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.CLI_BIN_NAME }}-${{ github.ref_name }}-${{ env.BUILD_LINUX_X86_64 }}
- name: Download CLI Linux ARM64 Artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.CLI_BIN_NAME }}-${{ github.ref_name }}-${{ env.BUILD_LINUX_ARM_64 }}
- name: Download CLI MacOS x86_64 Artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.CLI_BIN_NAME }}-${{ github.ref_name }}-${{ env.BUILD_MACOS_X86_64 }}
- name: Download CLI MacOS ARM64 Artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.CLI_BIN_NAME }}-${{ github.ref_name }}-${{ env.BUILD_MACOS_ARM_64 }}
- name: Download CLI Windows x86_64 Artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.CLI_BIN_NAME }}-${{ github.ref_name }}-${{ env.BUILD_WINDOWS_X86_64 }}.exe
- name: Download CLI Windows ARM64 Artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.CLI_BIN_NAME }}-${{ github.ref_name }}-${{ env.BUILD_WINDOWS_ARM_64 }}.exe
# Download CLI Packages
- name: Download CLI Linux x86_64 .deb Artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.CLI_BIN_NAME }}-${{ github.ref_name }}-${{ env.BUILD_LINUX_X86_64 }}.deb
- name: Download CLI Linux ARM64 .deb Artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.CLI_BIN_NAME }}-${{ github.ref_name }}-${{ env.BUILD_LINUX_ARM_64 }}.deb
# Load
- name: Load API Image
run: docker load < ${{ env.API_DOCKER_IMAGE }}.tar.gz
- name: Load Console Image
run: docker load < ${{ env.CONSOLE_DOCKER_IMAGE }}.tar.gz
# Login GHCR
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.GITHUB_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# Tag & Push
- name: Tag & Push API Image
run: |
export GITHUB_IMAGE=${{ env.GITHUB_REGISTRY }}/${{ github.repository_owner }}/${{ env.API_DOCKER_IMAGE }}
docker tag ${{ env.API_DOCKER_IMAGE }} ${GITHUB_IMAGE}:latest
docker tag ${{ env.API_DOCKER_IMAGE }} ${GITHUB_IMAGE}:${GITHUB_REF#refs/*/}
docker push ${GITHUB_IMAGE}:latest
docker push ${GITHUB_IMAGE}:${GITHUB_REF#refs/*/}
- name: Tag & Push Console Image
run: |
export GITHUB_IMAGE=${{ env.GITHUB_REGISTRY }}/${{ github.repository_owner }}/${{ env.CONSOLE_DOCKER_IMAGE }}
docker tag ${{ env.CONSOLE_DOCKER_IMAGE }} ${GITHUB_IMAGE}:latest
docker tag ${{ env.CONSOLE_DOCKER_IMAGE }} ${GITHUB_IMAGE}:${GITHUB_REF#refs/*/}
docker push ${GITHUB_IMAGE}:latest
docker push ${GITHUB_IMAGE}:${GITHUB_REF#refs/*/}
# Mirror to Docker Hub
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_TOKEN }}
- name: Tag & Push API Image to Docker Hub
run: |
export DOCKER_HUB_IMAGE=${{ env.DOCKER_HUB_ORGANIZATION }}/${{ env.API_DOCKER_IMAGE }}
docker tag ${{ env.API_DOCKER_IMAGE }} ${DOCKER_HUB_IMAGE}:latest
docker tag ${{ env.API_DOCKER_IMAGE }} ${DOCKER_HUB_IMAGE}:${GITHUB_REF#refs/*/}
docker push ${DOCKER_HUB_IMAGE}:latest
docker push ${DOCKER_HUB_IMAGE}:${GITHUB_REF#refs/*/}
- name: Tag & Push Console Image to Docker Hub
run: |
export DOCKER_HUB_IMAGE=${{ env.DOCKER_HUB_ORGANIZATION }}/${{ env.CONSOLE_DOCKER_IMAGE }}
docker tag ${{ env.CONSOLE_DOCKER_IMAGE }} ${DOCKER_HUB_IMAGE}:latest
docker tag ${{ env.CONSOLE_DOCKER_IMAGE }} ${DOCKER_HUB_IMAGE}:${GITHUB_REF#refs/*/}
docker push ${DOCKER_HUB_IMAGE}:latest
docker push ${DOCKER_HUB_IMAGE}:${GITHUB_REF#refs/*/}
- uses: rui314/setup-mold@v1
with:
mold-version: ${{ env.MOLD_VERSION }}
- name: Generate Release Notes
run: cargo gen-notes
- name: GitHub Release
uses: softprops/action-gh-release@v2
with:
prerelease: ${{ endsWith(github.ref, '-rc*') }}
body_path: release-notes.md
files: |
${{ env.API_DOCKER_IMAGE }}.tar.gz
${{ env.CONSOLE_DOCKER_IMAGE }}.tar.gz
${{ env.CLI_BIN_NAME }}-${{ github.ref_name }}-${{ env.BUILD_LINUX_X86_64 }}
${{ env.CLI_BIN_NAME }}-${{ github.ref_name }}-${{ env.BUILD_LINUX_ARM_64 }}
${{ env.CLI_BIN_NAME }}-${{ github.ref_name }}-${{ env.BUILD_MACOS_X86_64 }}
${{ env.CLI_BIN_NAME }}-${{ github.ref_name }}-${{ env.BUILD_MACOS_ARM_64 }}
${{ env.CLI_BIN_NAME }}-${{ github.ref_name }}-${{ env.BUILD_WINDOWS_X86_64 }}.exe
${{ env.CLI_BIN_NAME }}-${{ github.ref_name }}-${{ env.BUILD_WINDOWS_ARM_64 }}.exe
${{ env.CLI_BIN_NAME }}-${{ github.ref_name }}-${{ env.BUILD_LINUX_X86_64 }}.deb
${{ env.CLI_BIN_NAME }}-${{ github.ref_name }}-${{ env.BUILD_LINUX_ARM_64 }}.deb
# Dev Container
build_dev_container:
if: github.ref == 'refs/heads/devel'
name: Build dev container
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Setup Docker buildx
uses: docker/setup-buildx-action@v3
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.GITHUB_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Pre-build dev container image
uses: devcontainers/[email protected]
with:
imageName: ${{ env.GITHUB_REGISTRY }}/${{ github.repository_owner }}/${{ env.DEV_CONTAINER_DOCKER_IMAGE }}
cacheFrom: ${{ env.GITHUB_REGISTRY }}/${{ github.repository_owner }}/${{ env.DEV_CONTAINER_DOCKER_IMAGE }}
push: always