Skip to content

CI

CI #238

Workflow file for this run

# Copyright lowRISC contributors.
#
# SPDX-License-Identifier: MIT
name: CI
on:
merge_group:
pull_request:
branches: ["main"]
# Cancel existing runs if a pull request is pushed.
# For branch pushes, this will queue a new run and cancel the existing one. This allows the cache
# of the run to be used by the new run.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
check:
name: Quality Check
runs-on: nixos-24.05
outputs:
matrix: ${{ steps.plan.outputs.MATRIX }}
steps:
- name: checkout
uses: actions/checkout@v4
- name: Install Nix
uses: cachix/install-nix-action@v24
with:
extra_nix_config: |
substituters = https://nix-cache.lowrisc.org/public/ https://cache.nixos.org/
trusted-public-keys = nix-cache.lowrisc.org-public-1:O6JLD0yXzaJDPiQW1meVu32JIDViuaPtGDfjlOopU7o= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
- name: Nix Format Check
run: nix fmt -- . --check
- name: Run Nix Checks
run: nix flake check -L
- name: Generate Build Plan
id: plan
run: |
REBUILD=()
echo '| Package | System | Status |' >> $GITHUB_STEP_SUMMARY
echo '|---------|--------|--------|' >> $GITHUB_STEP_SUMMARY
if ${{ github.event_name == 'pull_request' }}; then
# We only support MacOS with best-effort basis. They take much longer to build so shouldn't block PR.
SYSTEMS=(x86_64-linux)
else
SYSTEMS=(x86_64-linux x86_64-darwin aarch64-darwin)
fi
for SYSTEM in "${SYSTEMS[@]}"; do
# This is a json object with package names as keys and their main outputs as values
PACKAGES=$(nix eval --json ".#packages.$SYSTEM")
for ATTR in $(echo "$PACKAGES" | jq -r 'keys[]'); do
HASH=$(echo "$PACKAGES" | jq -r ".[\"$ATTR\"]" | cut -d '/' -f4 | cut -d '-' -f1)
# Check if the main output is cached by us or upstream.
CACHED=n
if curl -sSfL "https://nix-cache.lowrisc.org/public/$HASH.narinfo"; then
CACHED=y
elif curl -sSfL "https://cache.nixos.org/$HASH.narinfo"; then
CACHED=y
fi
if [[ $CACHED == y ]]; then
echo "| $ATTR | $SYSTEM | ✅ Cached |" | tee -a $GITHUB_STEP_SUMMARY
else
REBUILD+=("$(jq --null-input '{attr: $attr, system: $system}' --arg attr "$ATTR" --arg system "$SYSTEM")")
echo "| $ATTR | $SYSTEM | ⏳ Need Rebuild |" | tee -a $GITHUB_STEP_SUMMARY
fi
done
done
echo 'MATRIX<<EOF' >> $GITHUB_OUTPUT
jq --null-input '$ARGS.positional' --jsonargs -- "${REBUILD[@]}" >> $GITHUB_OUTPUT
echo 'EOF' >> $GITHUB_OUTPUT
build:
needs: check
name: Build
# Matrix can't be empty, so skip the job entirely if nothing needs to be rebuilt.
if: fromJSON(needs.check.outputs.matrix)[0] != null
strategy:
matrix:
include: ${{fromJSON(needs.check.outputs.matrix)}}
# Disable fail-fast for non-PR builds to ensure all outputs have a chance to be built.
fail-fast: ${{ github.event_name == 'pull_request' }}
runs-on: ${{ matrix.system == 'x86_64-darwin' && 'macos-13' || (matrix.system == 'aarch64-darwin' && 'macos-14' || 'nixos-24.05') }}
steps:
- name: checkout
uses: actions/checkout@v4
- name: Install Nix
uses: cachix/install-nix-action@v24
with:
extra_nix_config: |
substituters = https://nix-cache.lowrisc.org/public/ https://cache.nixos.org/
trusted-public-keys = nix-cache.lowrisc.org-public-1:O6JLD0yXzaJDPiQW1meVu32JIDViuaPtGDfjlOopU7o= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
- name: Setup Cache
if: github.event_name != 'pull_request'
run: |
nix profile install nixpkgs#attic-client
attic login --set-default lowrisc https://nix-cache.lowrisc.org/ ${{ secrets.NIX_CACHE_TOKEN }}
- name: Build
run: |
# For derivations with multiple outputs, this produces a list that references all the outputs.
OUTPUTS=$(nix eval .#${{ matrix.attr }} --apply 'd: d.outputs' --json | jq -r 'map(".#${{ matrix.attr }}." + .) | join(" ")')
nix build $OUTPUTS --accept-flake-config -L
- name: Upload Cache
if: github.event_name != 'pull_request'
run: |
attic push public result*
# Summarise check status with a single job for GitHub branch protection rule
status:
needs:
- check
- build
if: ${{ always() }}
name: Status
runs-on: ubuntu-latest
steps:
- name: Check check status
if: ${{ needs.check.result != 'success' }}
run: exit 1
- name: Check build status
if: ${{ needs.build.result != 'success' && needs.build.result != 'skipped' }}
run: exit 1