ci: new ci-runner base image + uv/ruff/node_modules cache
Runner base image (infra/Dockerfile.runner-base): - Added uv (fast Python package installer, ~10x faster than pip) - Added ruff (baked in, lint job drops from ~13s to ~2s) - Added jq + tzdata - Renamed tag from py3.12-node22 to ci-runner (purpose over contents) Workflow (ci.yml): - typecheck: cache node_modules directly instead of npm download cache; skip npm ci entirely on cache hits (9m41s → ~30s expected) - lint: just `ruff check src/` — no venv, no install - test: uv venv + uv pip install replaces pip (~10x faster resolves) - all jobs: runs-on ci-runner label Baseline: typecheck 9m41s, lint 13s, test 1m42s
This commit is contained in:
+24
-26
@@ -51,17 +51,23 @@ env:
|
||||
jobs:
|
||||
typecheck:
|
||||
name: TypeScript typecheck
|
||||
runs-on: py3.12-node22
|
||||
runs-on: ci-runner
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- uses: actions/setup-node@v6
|
||||
# Cache node_modules directly (not the npm download cache).
|
||||
# npm ci still has to extract + link every module even with a
|
||||
# warm download cache, which is where the real time goes. Caching
|
||||
# the output directory lets us skip npm ci entirely on hits.
|
||||
- name: Cache node_modules
|
||||
id: npm-cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
node-version: "22"
|
||||
cache: "npm"
|
||||
cache-dependency-path: frontend/package-lock.json
|
||||
path: frontend/node_modules
|
||||
key: node-modules-${{ hashFiles('frontend/package-lock.json') }}
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.npm-cache.outputs.cache-hit != 'true'
|
||||
run: npm ci
|
||||
working-directory: frontend
|
||||
|
||||
@@ -71,46 +77,38 @@ jobs:
|
||||
|
||||
lint:
|
||||
name: Python lint
|
||||
runs-on: py3.12-node22
|
||||
runs-on: ci-runner
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Install ruff
|
||||
# Isolated venv avoids polluting the runner's system
|
||||
# site-packages (the old --break-system-packages was a smell)
|
||||
# and pipx isn't available on the py3.12-node22 runner image.
|
||||
run: |
|
||||
python3.12 -m venv /opt/ruff-venv
|
||||
/opt/ruff-venv/bin/pip install --quiet ruff
|
||||
|
||||
# ruff is pre-installed in the ci-runner base image — no install
|
||||
# step needed, lint runs in ~2s.
|
||||
- name: Lint
|
||||
run: /opt/ruff-venv/bin/ruff check src/
|
||||
run: ruff check src/
|
||||
|
||||
test:
|
||||
name: Python tests
|
||||
runs-on: py3.12-node22
|
||||
runs-on: ci-runner
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
# Python 3.12 is pre-installed in the runner-base image (py3.12-node22).
|
||||
- name: Cache pip wheels
|
||||
- name: Cache uv packages
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: pip-${{ hashFiles('pyproject.toml') }}
|
||||
restore-keys: pip-
|
||||
path: ~/.cache/uv
|
||||
key: uv-${{ hashFiles('pyproject.toml') }}
|
||||
restore-keys: uv-
|
||||
|
||||
- name: Create virtual environment
|
||||
run: python3.12 -m venv /opt/venv
|
||||
run: uv venv /opt/venv
|
||||
|
||||
- name: Install package with dev deps
|
||||
run: |
|
||||
/opt/venv/bin/pip install --upgrade pip setuptools wheel
|
||||
# http-ece's build-time dep on cryptography fails under PEP 517
|
||||
# isolation on this runner image — install it without isolation
|
||||
# first so the editable install below finds it already built.
|
||||
/opt/venv/bin/pip install --no-build-isolation http-ece
|
||||
/opt/venv/bin/pip install -e ".[dev]"
|
||||
uv pip install --python /opt/venv/bin/python --no-build-isolation http-ece
|
||||
uv pip install --python /opt/venv/bin/python -e ".[dev]"
|
||||
|
||||
- name: Run tests
|
||||
run: /opt/venv/bin/python -m pytest tests/ -q
|
||||
@@ -124,7 +122,7 @@ jobs:
|
||||
if: |
|
||||
github.event_name == 'push' &&
|
||||
(github.ref == 'refs/heads/dev' || startsWith(github.ref, 'refs/tags/'))
|
||||
runs-on: py3.12-node22
|
||||
runs-on: ci-runner
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
@@ -1,26 +1,28 @@
|
||||
# Runner base image for Forgejo act_runner job containers.
|
||||
# Pre-installs Python 3.12 and Node 20 so the test job skips the
|
||||
# ~3-4 minute deadsnakes PPA install on every run.
|
||||
# Pre-installs Python 3.12, Node 22, uv, and ruff so workflows skip
|
||||
# lengthy runtime installs on every run.
|
||||
#
|
||||
# Build and push (one-time setup, re-run if this file changes):
|
||||
# Build and push (re-run when this file changes):
|
||||
# docker build -f infra/Dockerfile.runner-base \
|
||||
# -t git.fabledsword.com/bvandeusen/runner-base:py3.12-node22 .
|
||||
# docker push git.fabledsword.com/bvandeusen/runner-base:py3.12-node22
|
||||
# -t git.fabledsword.com/bvandeusen/runner-base:ci-runner .
|
||||
# docker push git.fabledsword.com/bvandeusen/runner-base:ci-runner
|
||||
#
|
||||
# Then redeploy the act_runner stack in Portainer to pick up the new label.
|
||||
# Then redeploy the act_runner stack in Portainer to pick up the new image.
|
||||
|
||||
FROM ubuntu:24.04
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
ENV TZ=UTC
|
||||
|
||||
# Split into separate RUN steps so each pushed layer is smaller.
|
||||
# One combined layer would be ~280MB and exceeds the nginx upload timeout.
|
||||
# Split into separate RUN steps so each pushed layer is smaller — one
|
||||
# combined layer exceeds the nginx upload timeout on the self-hosted
|
||||
# Forgejo registry.
|
||||
|
||||
# Python 3.12 ships in Ubuntu 24.04 main repos — no PPA needed.
|
||||
# Python 3.12 (ships in Ubuntu 24.04 main repos) + core tools
|
||||
RUN apt-get update -qq && \
|
||||
apt-get install -y -qq \
|
||||
python3.12 python3.12-dev python3.12-venv python3-pip \
|
||||
git curl ca-certificates gnupg && \
|
||||
python3.12 python3.12-dev python3.12-venv \
|
||||
git curl ca-certificates gnupg jq tzdata && \
|
||||
apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Node 22 LTS via NodeSource
|
||||
@@ -33,3 +35,14 @@ RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - && \
|
||||
RUN apt-get update -qq && \
|
||||
apt-get install -y -qq docker.io && \
|
||||
apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# uv — fast Python package installer/resolver (~10x faster than pip).
|
||||
# Used by test jobs instead of pip for venv creation + dep installs.
|
||||
RUN curl -LsSf https://astral.sh/uv/install.sh | env INSTALLER_NO_MODIFY_PATH=1 sh && \
|
||||
mv /root/.local/bin/uv /usr/local/bin/ && \
|
||||
mv /root/.local/bin/uvx /usr/local/bin/
|
||||
|
||||
# ruff — Python linter. Baked in so the lint job is just
|
||||
# `ruff check src/` with zero install overhead.
|
||||
RUN curl -LsSf https://astral.sh/ruff/install.sh | env INSTALLER_NO_MODIFY_PATH=1 sh && \
|
||||
mv /root/.local/bin/ruff /usr/local/bin/
|
||||
|
||||
Reference in New Issue
Block a user