rewrite #1548
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| workflow_dispatch: | |
| push: | |
| branches: [devel, cloud] | |
| tags: [v**] | |
| pull_request: | |
| branches: [main, cloud, devel, 'u/**'] | |
| env: | |
| GITHUB_REGISTRY: ghcr.io | |
| DEV_CONTAINER_DOCKER_IMAGE: bencher-dev-container | |
| # Cancel in-progress runs for the same branch | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| jobs: | |
| # Determine what changed | |
| changes: | |
| name: Detect Changes | |
| runs-on: ubuntu-22.04 | |
| outputs: | |
| rust: ${{ steps.filter.outputs.rust }} | |
| console: ${{ steps.filter.outputs.console }} | |
| action: ${{ steps.filter.outputs.action }} | |
| cli: ${{ steps.filter.outputs.cli }} | |
| docker: ${{ steps.filter.outputs.docker }} | |
| runner: ${{ steps.filter.outputs.runner }} | |
| nix: ${{ steps.filter.outputs.nix }} | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1 | |
| id: filter | |
| with: | |
| filters: | | |
| rust: | |
| - 'Cargo.toml' | |
| - 'Cargo.lock' | |
| - 'lib/**' | |
| - 'plus/**' | |
| - 'services/api/**' | |
| - 'docker/bench.Dockerfile' | |
| - 'services/cli/**' | |
| - 'services/runner/**' | |
| - 'tasks/**' | |
| - 'xtask/**' | |
| console: | |
| - 'services/console/**' | |
| - 'lib/bencher_valid/**' | |
| action: | |
| - 'services/action/**' | |
| - 'services/api/openapi.json' | |
| cli: | |
| - 'services/cli/**' | |
| - 'lib/bencher_adapter/**' | |
| - 'lib/bencher_client/**' | |
| - 'lib/bencher_comment/**' | |
| - 'lib/bencher_context/**' | |
| - 'lib/bencher_json/**' | |
| - 'lib/bencher_noise/**' | |
| - 'lib/bencher_parser/**' | |
| - 'lib/bencher_valid/**' | |
| - 'services/api/openapi.json' | |
| docker: | |
| - 'services/api/Dockerfile' | |
| - 'services/cli/Dockerfile' | |
| - 'services/console/Dockerfile' | |
| - 'docker/**' | |
| runner: | |
| - 'lib/bencher_context/**' | |
| - 'lib/bencher_json/**' | |
| - 'lib/bencher_parser/**' | |
| - 'lib/bencher_valid/**' | |
| - 'plus/bencher_init/**' | |
| - 'plus/bencher_oci/**' | |
| - 'plus/bencher_output_protocol/**' | |
| - 'plus/bencher_rootfs/**' | |
| - 'plus/bencher_runner/**' | |
| - 'services/runner/**' | |
| - 'tasks/test_runner/**' | |
| - 'tasks/update_sandbox/**' | |
| nix: | |
| - 'flake.nix' | |
| - 'flake.lock' | |
| lint: | |
| name: Lint | |
| if: github.ref != 'refs/heads/cloud' | |
| uses: ./.github/workflows/lint.yml | |
| with: | |
| mold-version: "2.34.1" | |
| typeshare-version: "1.13.2" | |
| zizmor-version: "v1.25.2" | |
| cli: | |
| name: CLI | |
| needs: changes | |
| if: github.ref != 'refs/heads/cloud' | |
| uses: ./.github/workflows/cli.yml | |
| with: | |
| bencher-version: "0.6.12" | |
| mold-version: "2.34.1" | |
| zig-build-version: "0.19.3" | |
| zig-version: "0.13.0" | |
| # 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" | |
| check-cli: ${{ needs.changes.outputs.cli == 'true' || github.ref == 'refs/heads/devel' }} | |
| is-fork: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository }} | |
| build-cli: ${{ needs.changes.outputs.cli == 'true' || github.ref == 'refs/heads/devel' || startsWith(github.ref, 'refs/tags/') }} | |
| secrets: | |
| BENCHER_API_KEY: ${{ secrets.BENCHER_API_KEY }} | |
| runner: | |
| name: Runner | |
| needs: changes | |
| # On cloud pushes, the runner is only rebuilt when runner code changed | |
| # (avoids pointless canary fleet updates) and skips the scenario tests | |
| # (the same commits already ran them on devel). | |
| # "Changed" on cloud pushes means changed since the last deploy: the | |
| # changes filter has no explicit base, so it diffs against the default | |
| # branch (main), which CI resets to cloud after each successful deploy. | |
| if: ${{ needs.changes.outputs.runner == 'true' || github.ref == 'refs/heads/devel' || startsWith(github.ref, 'refs/tags/') }} | |
| uses: ./.github/workflows/runner.yml | |
| with: | |
| mold-version: "2.34.1" | |
| zig-version: "0.13.0" | |
| zig-build-version: "0.19.3" | |
| build-only: ${{ github.ref == 'refs/heads/cloud' }} | |
| # Publish the cloud branch runner build to the rolling `canary` prerelease. | |
| # Canary channel runners poll this release's checksums and self-update when | |
| # the published binary changes. | |
| publish_runner_canary: | |
| name: Publish Runner Canary | |
| permissions: | |
| contents: write | |
| needs: runner | |
| if: ${{ !failure() && !cancelled() && github.ref == 'refs/heads/cloud' && needs.runner.result == 'success' }} | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - name: Download Runner Artifacts | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| pattern: runner-canary-linux-* | |
| merge-multiple: true | |
| - name: Publish to canary prerelease | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| GH_REPO: ${{ github.repository }} | |
| run: | | |
| set -euo pipefail | |
| if ! gh release view canary > /dev/null 2>&1; then | |
| gh release create canary \ | |
| --prerelease \ | |
| --latest=false \ | |
| --target "$GITHUB_SHA" \ | |
| --title "Runner Canary" \ | |
| --notes "Rolling prerelease of the runner, rebuilt on cloud branch deploys." | |
| fi | |
| # Binaries first, checksums last: the server triggers updates off | |
| # the .sha256 files, so a partial upload never advertises a binary | |
| # that is not yet in place. | |
| gh release upload canary --clobber \ | |
| runner-canary-linux-x86-64 \ | |
| runner-canary-linux-arm-64 | |
| gh release upload canary --clobber \ | |
| runner-canary-linux-x86-64.sha256 \ | |
| runner-canary-linux-arm-64.sha256 | |
| # Keep the canary tag pointing at the commit the assets were built | |
| # from. Downloads are by asset, so this is purely for humans | |
| # inspecting the release; tag moves do not trigger CI (tags: v**). | |
| gh api --method PATCH "repos/{owner}/{repo}/git/refs/tags/canary" \ | |
| -f "sha=$GITHUB_SHA" -F force=true > /dev/null | |
| gh release edit canary --notes "Rolling prerelease of the runner, rebuilt on cloud branch deploys. Currently built from $GITHUB_SHA." | |
| test: | |
| name: Test | |
| permissions: | |
| contents: read | |
| checks: write | |
| needs: changes | |
| if: ${{ github.ref != 'refs/heads/cloud' && (needs.changes.outputs.rust == 'true' || github.ref == 'refs/heads/devel' || startsWith(github.ref, 'refs/tags/')) }} | |
| uses: ./.github/workflows/test.yml | |
| with: | |
| mold-version: "2.34.1" | |
| go-version: "1.25" | |
| is-fork: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository }} | |
| secrets: | |
| TEST_BILLING_KEY: ${{ secrets.TEST_BILLING_KEY }} | |
| BENCHER_API_KEY: ${{ secrets.BENCHER_API_KEY }} | |
| build: | |
| name: Build | |
| permissions: | |
| contents: read | |
| packages: write | |
| needs: changes | |
| uses: ./.github/workflows/build.yml | |
| with: | |
| mold-version: "2.34.1" | |
| wasm-pack-version: "0.12.1" | |
| litestream-version: "0.5.16" | |
| cargo-chef-version: "0.1.77" | |
| sccache-version: "0.16.0" | |
| is-fork: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository }} | |
| build-action: ${{ needs.changes.outputs.action == 'true' || github.ref == 'refs/heads/devel' || github.ref == 'refs/heads/cloud' || startsWith(github.ref, 'refs/tags/') }} | |
| build-docker: ${{ !startsWith(github.ref, 'refs/tags/') && (needs.changes.outputs.docker == 'true' || github.ref == 'refs/heads/devel' || (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'deploy'))) }} | |
| deploy-only: ${{ github.ref == 'refs/heads/cloud' }} | |
| # The console build is environment-specific, so it has to match the deploy | |
| # this run will perform. Anything that does not deploy dev builds the | |
| # top-level (production) configuration. | |
| cloudflare-env: ${{ (github.ref == 'refs/heads/devel' || (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'deploy'))) && 'dev' || '' }} | |
| # Only runs that deploy upload sourcemaps, and only from this repository: | |
| # fork pull requests get no secrets, and uploading without a token fails the build. | |
| sentry-upload: ${{ github.ref == 'refs/heads/devel' || github.ref == 'refs/heads/cloud' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && contains(github.event.pull_request.labels.*.name, 'deploy')) }} | |
| secrets: | |
| R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} | |
| R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }} | |
| SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} | |
| docker: | |
| name: Docker | |
| permissions: | |
| contents: read | |
| packages: write | |
| if: ${{ github.ref != 'refs/heads/cloud' && (github.ref == 'refs/heads/devel' || startsWith(github.ref, 'refs/tags/') || (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'docker'))) }} | |
| uses: ./.github/workflows/docker.yml | |
| with: | |
| mold-version: "2.34.1" | |
| litestream-version: "0.5.16" | |
| cargo-chef-version: "0.1.77" | |
| sccache-version: "0.16.0" | |
| is-fork: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository }} | |
| secrets: | |
| R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} | |
| R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }} | |
| nix: | |
| name: Nix | |
| needs: changes | |
| if: github.ref != 'refs/heads/cloud' | |
| uses: ./.github/workflows/nix.yml | |
| with: | |
| nix-lint: ${{ needs.changes.outputs.nix == 'true' }} | |
| nix-build: ${{ needs.changes.outputs.nix == 'true' || needs.changes.outputs.cli == 'true' }} | |
| deploy: | |
| name: Deploy | |
| permissions: | |
| contents: write | |
| packages: read | |
| needs: [lint, cli, test, build] | |
| if: ${{ !failure() && !cancelled() && (github.ref == 'refs/heads/devel' || github.ref == 'refs/heads/cloud' || (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'deploy'))) }} | |
| uses: ./.github/workflows/deploy.yml | |
| with: | |
| mold-version: "2.34.1" | |
| go-version: "1.25" | |
| deploy-dev: ${{ github.ref == 'refs/heads/devel' || (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'deploy')) }} | |
| deploy-test: ${{ github.ref == 'refs/heads/devel' || github.ref == 'refs/heads/cloud' }} | |
| deploy-prod: ${{ github.ref == 'refs/heads/cloud' }} | |
| secrets: | |
| FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} | |
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| BENCHER_USER_AGENT: ${{ secrets.BENCHER_USER_AGENT }} | |
| release: | |
| name: Release | |
| permissions: | |
| contents: write | |
| packages: write | |
| if: ${{ !failure() && !cancelled() && github.ref != 'refs/heads/cloud' && (needs.changes.outputs.rust == 'true' || github.ref == 'refs/heads/devel' || startsWith(github.ref, 'refs/tags/')) }} | |
| needs: [changes, lint, cli, runner, test, build, docker, nix] | |
| uses: ./.github/workflows/release.yml | |
| with: | |
| mold-version: "2.34.1" | |
| go-version: "1.25" | |
| secrets: | |
| DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }} | |
| DOCKER_HUB_TOKEN: ${{ secrets.DOCKER_HUB_TOKEN }} | |
| ci-success: | |
| name: CI Success | |
| if: always() | |
| needs: [lint, cli, runner, publish_runner_canary, test, build, docker, deploy, release] | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - name: Check all jobs passed | |
| run: | | |
| if [[ "${{ needs.lint.result }}" != "success" && "${{ needs.lint.result }}" != "skipped" ]]; then | |
| echo "Lint failed" | |
| exit 1 | |
| fi | |
| if [[ "${{ needs.cli.result }}" != "success" && "${{ needs.cli.result }}" != "skipped" ]]; then | |
| echo "CLI failed" | |
| exit 1 | |
| fi | |
| if [[ "${{ needs.runner.result }}" != "success" && "${{ needs.runner.result }}" != "skipped" ]]; then | |
| echo "Runner failed" | |
| exit 1 | |
| fi | |
| if [[ "${{ needs.publish_runner_canary.result }}" != "success" && "${{ needs.publish_runner_canary.result }}" != "skipped" ]]; then | |
| echo "Publish Runner Canary failed" | |
| exit 1 | |
| fi | |
| if [[ "${{ needs.test.result }}" != "success" && "${{ needs.test.result }}" != "skipped" ]]; then | |
| echo "Test failed" | |
| exit 1 | |
| fi | |
| if [[ "${{ needs.build.result }}" != "success" ]]; then | |
| echo "Build failed" | |
| exit 1 | |
| fi | |
| if [[ "${{ needs.docker.result }}" != "success" && "${{ needs.docker.result }}" != "skipped" ]]; then | |
| echo "Docker failed" | |
| exit 1 | |
| fi | |
| if [[ "${{ needs.deploy.result }}" != "success" && "${{ needs.deploy.result }}" != "skipped" ]]; then | |
| echo "Deploy failed" | |
| exit 1 | |
| fi | |
| if [[ "${{ needs.release.result }}" != "success" && "${{ needs.release.result }}" != "skipped" ]]; then | |
| echo "Release failed" | |
| exit 1 | |
| fi | |
| echo "All required jobs passed!" | |
| build_dev_container: | |
| name: Build dev container | |
| permissions: | |
| contents: read | |
| packages: write | |
| if: ${{ github.ref == 'refs/heads/devel' }} | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0 | |
| - name: Setup Docker buildx | |
| uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 | |
| - name: Log in to the Container registry | |
| uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 | |
| with: | |
| registry: ${{ env.GITHUB_REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Pre-build dev container image | |
| uses: devcontainers/ci@b63b30de439b47a52267f241112c5b453b673db5 # v0.3.1900000449 | |
| 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 | |