143 lines
5 KiB
YAML
143 lines
5 KiB
YAML
name: Nix CI
|
|
|
|
on:
|
|
push:
|
|
branches: [ main, master ]
|
|
pull_request:
|
|
branches: [ main, master ]
|
|
workflow_dispatch:
|
|
|
|
jobs:
|
|
# Detect which workspaces have changed to save CI minutes
|
|
filter:
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
workspaces: ${{ steps.detect.outputs.workspaces }}
|
|
build_targets: ${{ steps.detect.outputs.build_targets }}
|
|
any_changed: ${{ steps.detect.outputs.any_changed }}
|
|
build_changed: ${{ steps.detect.outputs.build_changed }}
|
|
global_changed: ${{ steps.detect.outputs.global_changed }}
|
|
shared_crates: ${{ steps.detect.outputs.shared_crates }}
|
|
shared_crates_changed: ${{ steps.detect.outputs.shared_crates_changed }}
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Collect changed files
|
|
env:
|
|
EVENT_NAME: ${{ github.event_name }}
|
|
BASE_REF: ${{ github.base_ref }}
|
|
BEFORE_SHA: ${{ github.event.before }}
|
|
HEAD_SHA: ${{ github.sha }}
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
if [[ "$EVENT_NAME" == "workflow_dispatch" ]]; then
|
|
printf 'flake.nix\n' > changed-files.txt
|
|
elif [[ "$EVENT_NAME" == "pull_request" ]]; then
|
|
git fetch --no-tags --depth=1 origin "$BASE_REF"
|
|
git diff --name-only "origin/$BASE_REF...$HEAD_SHA" > changed-files.txt
|
|
elif [[ "$BEFORE_SHA" == "0000000000000000000000000000000000000000" ]]; then
|
|
git diff-tree --no-commit-id --name-only -r "$HEAD_SHA" > changed-files.txt
|
|
else
|
|
git diff --name-only "$BEFORE_SHA" "$HEAD_SHA" > changed-files.txt
|
|
fi
|
|
|
|
if [[ ! -f changed-files.txt ]]; then
|
|
: > changed-files.txt
|
|
fi
|
|
|
|
sed -n '1,200p' changed-files.txt
|
|
|
|
- name: Detect changed workspaces
|
|
id: detect
|
|
run: |
|
|
python3 scripts/ci_changed_workspaces.py \
|
|
--config nix/ci/workspaces.json \
|
|
--changed-files-file changed-files.txt \
|
|
--github-output "$GITHUB_OUTPUT"
|
|
|
|
# Run CI gates for changed workspaces
|
|
# Uses the provider-agnostic 'photoncloud-gate' defined in nix/ci/flake.nix
|
|
gate:
|
|
needs: filter
|
|
if: ${{ needs.filter.outputs.any_changed == 'true' }}
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
workspace: ${{ fromJSON(needs.filter.outputs.workspaces) }}
|
|
name: gate (${{ matrix.workspace }})
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: DeterminateSystems/nix-installer-action@v11
|
|
- uses: DeterminateSystems/magic-nix-cache-action@v8
|
|
|
|
- name: Run PhotonCloud Gate
|
|
run: |
|
|
nix run ./nix/ci#gate-ci -- --workspace ${{ matrix.workspace }} --tier 0 --no-logs
|
|
|
|
shared-crates-gate:
|
|
needs: filter
|
|
if: ${{ needs.filter.outputs.shared_crates_changed == 'true' }}
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
crate: ${{ fromJSON(needs.filter.outputs.shared_crates) }}
|
|
name: gate (shared crate: ${{ matrix.crate }})
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: DeterminateSystems/nix-installer-action@v11
|
|
- uses: DeterminateSystems/magic-nix-cache-action@v8
|
|
|
|
- name: Run Shared Crate Gate
|
|
run: |
|
|
nix run ./nix/ci#gate-ci -- --shared-crate ${{ matrix.crate }} --tier 0 --no-logs
|
|
|
|
# Build server packages (tier 1+)
|
|
build:
|
|
needs: [filter, gate]
|
|
if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master') && needs.filter.outputs.build_changed == 'true' }}
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
matrix:
|
|
target: ${{ fromJSON(needs.filter.outputs.build_targets) }}
|
|
name: build (${{ matrix.target.package }})
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: DeterminateSystems/nix-installer-action@v11
|
|
- uses: DeterminateSystems/magic-nix-cache-action@v8
|
|
|
|
- name: Build package
|
|
run: |
|
|
nix build .#${{ matrix.target.package }} --accept-flake-config
|
|
|
|
# Summary job for PR status checks
|
|
ci-status:
|
|
needs: [filter, gate, shared-crates-gate]
|
|
if: always()
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Check CI Status
|
|
run: |
|
|
if [[ "${{ needs.gate.result }}" == "failure" ]]; then
|
|
exit 1
|
|
fi
|
|
if [[ "${{ needs.shared-crates-gate.result }}" == "failure" ]]; then
|
|
exit 1
|
|
fi
|
|
if [[ "${{ needs.filter.outputs.any_changed }}" == "true" || "${{ needs.filter.outputs.global_changed }}" == "true" ]]; then
|
|
if [[ "${{ needs.gate.result }}" == "skipped" ]]; then
|
|
echo "Gate was skipped despite changes. This is unexpected."
|
|
exit 1
|
|
fi
|
|
fi
|
|
if [[ "${{ needs.filter.outputs.shared_crates_changed }}" == "true" ]]; then
|
|
if [[ "${{ needs.shared-crates-gate.result }}" == "skipped" ]]; then
|
|
echo "Shared crates gate was skipped despite crates/** changes. This is unexpected."
|
|
exit 1
|
|
fi
|
|
fi
|
|
echo "CI passed or was correctly skipped."
|