Files
Igor SirotinandClaude Fable 5 294adeee6b ci: cut CI wall clock from ~17 to ~6 min (#73)
* ci: bump logoscore-py pin to pick up Attic-cached smoke image

logoscore-py a58573e adds the Logos Attic substituters to the smoke
image's build stage (logos-co/logos-logoscore-py#12). The CLI pin moves
to 665ac28 in lockstep — logoscore-py bumped its flake pin in #10.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci: run e2e-tests in parallel with build-and-test

The job builds everything it needs itself (Attic-cached), so waiting
for both build-and-test legs — including the slower macos one — only
added ~4 min of wall clock.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci: cache smoke image layers via buildx gha backend

The logoscore-py pin makes the docker build input-identical between
runs, so with mode=max every layer — including the ~5 min inner
nix build — replays from cache until the pin is bumped. Same pattern
as logoscore-py's own CI; build_smoke_image.sh forwards the env vars.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci: expose Actions runtime env so the buildx gha cache actually works

type=gha needs ACTIONS_RUNTIME_TOKEN/ACTIONS_CACHE_URL, which GitHub
injects into actions but not run steps — buildx called from
build_smoke_image.sh silently skipped the cache. (logoscore-py's own
CI has the same latent no-op.)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 14:00:20 +01:00

129 lines
4.1 KiB
YAML

name: CI
on:
pull_request:
branches: [master, main]
push:
branches: [master, main]
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
build-and-test:
environment: ${{ github.ref == 'refs/heads/master' && 'public-cache' || '' }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
timeout-minutes: 45
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Nix and Logos cache
uses: logos-co/setup-nix-cache-action@v1
with:
attic-token-ci: ${{ secrets.ATTIC_TOKEN_CI }}
attic-token-public: ${{ secrets.ATTIC_TOKEN_PUBLIC }}
- name: Build module
run: nix build -L
- name: Run tests
run: nix build .#unit-tests -L
- name: Pre-warm cache for install-portable
if: matrix.os == 'ubuntu-latest'
run: nix build -L .#install-portable
e2e-tests:
environment: ${{ github.ref == 'refs/heads/master' && 'public-cache' || '' }}
runs-on: ubuntu-latest
timeout-minutes: 50
continue-on-error: true
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Nix and Logos cache
uses: logos-co/setup-nix-cache-action@v1
with:
attic-token-ci: ${{ secrets.ATTIC_TOKEN_CI }}
attic-token-public: ${{ secrets.ATTIC_TOKEN_PUBLIC }}
# The gha cache backend needs the docker-container driver;
# the default docker driver can't export type=gha.
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# type=gha needs ACTIONS_RUNTIME_TOKEN/ACTIONS_CACHE_URL, which
# GitHub only injects into actions — this exposes them to run
# steps, so buildx invoked from build_smoke_image.sh can reach
# the cache API. Without it the gha cache is silently a no-op.
- name: Expose Actions runtime for buildx gha cache
uses: crazy-max/ghaction-github-runtime@v3
- name: Build delivery-module (install-portable layout)
run: |
nix build -L .#install-portable
echo "LOGOS_MODULES_DIR=$PWD/result/modules" >> $GITHUB_ENV
- name: Checkout logoscore-py and build smoke image
env:
BUILDX_CACHE_FROM: type=gha
BUILDX_CACHE_TO: type=gha,mode=max
run: |
git clone https://github.com/logos-co/logos-logoscore-py.git /tmp/logoscore-py
cd /tmp/logoscore-py
git checkout a58573eb2c33916c0da2ba08ecb1ceca2fbb7617
bash tests/docker_smoke/build_smoke_image.sh
echo "LOGOSCORE_IMAGE=logoscore:smoke-portable" >> $GITHUB_ENV
- name: Build logoscore CLI binary (host PATH)
# Must match the daemon commit baked into the smoke image above.
run: |
nix build -L --out-link /tmp/logoscore-cli "github:logos-co/logos-logoscore-cli/665ac28bc77f45e3c610f40fef975a12609de531#cli"
echo "/tmp/logoscore-cli/bin" >> $GITHUB_PATH
- uses: actions/setup-python@v5
with:
python-version: "3.14"
cache: pip
cache-dependency-path: tests/e2e/requirements.txt
- name: Install e2e test dependencies
run: |
cd tests/e2e
pip install -r requirements.txt
- name: Run e2e tests
run: |
mkdir -p ${{ runner.temp }}/e2e-logs
cd tests/e2e
pytest -v
env:
E2E_LOG_DIR: ${{ runner.temp }}/e2e-logs
LOGOSCORE_PY_FORWARD_OUTPUT: "1"
- name: Collect docker container logs on failure
if: failure()
run: |
mkdir -p ${{ runner.temp }}/e2e-logs
for c in $(docker ps -a --filter "name=logoscore-a" --filter "name=logoscore-b" --filter "name=logoscore-solo" -q); do
name=$(docker inspect --format '{{.Name}}' "$c" | tr -d '/')
docker logs "$c" > "${{ runner.temp }}/e2e-logs/${name}.log" 2>&1 || true
done
- name: Upload daemon logs on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: e2e-test-logs
path: ${{ runner.temp }}/e2e-logs/*.log
retention-days: 7