Skip to content

release: promote v2.3.0 general availability #29

release: promote v2.3.0 general availability

release: promote v2.3.0 general availability #29

Workflow file for this run

name: CI
# Runs the project's existing self-contained test suites — no live server,
# no API keys, no network calls to an LLM. Compatible with both GitHub
# Actions and Gitea Actions (same workflow syntax).
on:
push:
branches: [main]
pull_request:
jobs:
backend:
runs-on: ubuntu-latest
env:
BT_COVERAGE_FAIL_UNDER: "60"
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
# actions/setup-python only ships prebuilt interpreters for GitHub's
# hosted Ubuntu images; in a minimal Gitea job container it fails with
# "version '3.11' ... was not found for this operating system". Use the
# platform's own Python instead: already present on GitHub runners,
# apt-installed in the container otherwise. Both paths give Python 3.11.
- name: Set up Python
run: |
if ! command -v python3 >/dev/null 2>&1; then
apt-get update && apt-get install -y --no-install-recommends python3 python3-pip
fi
# node:*-bookworm ships python3 but no pip module — ensure pip too.
if ! python3 -m pip --version >/dev/null 2>&1; then
if command -v apt-get >/dev/null 2>&1; then
apt-get update && apt-get install -y --no-install-recommends python3-pip
else
python3 -m ensurepip --upgrade
fi
fi
python3 --version && python3 -m pip --version
- name: Install dependencies
# Debian's system Python is PEP 668 "externally managed"; the flag is
# safe in this ephemeral CI env and is supported by modern pip on both.
run: >-
python3 -m pip install --break-system-packages --require-hashes --only-binary=:all: -r requirements/requirements.txt
- name: Audit Python deps
# Audit tooling is itself installed from a reviewed hash lock. The
# runtime lock already lists every transitive dependency, so audit it
# without invoking a resolver or creating another environment.
run: |
set -e
python3 -m pip install --break-system-packages --require-hashes --only-binary=:all: -r requirements/requirements-audit.txt
python3 -m pip_audit -r requirements/requirements.txt --strict --disable-pip --no-deps
- run: git ls-files -z -- '*.py' | xargs -0 -r python3 -m py_compile
- run: bash -n btctl install_unraid.sh scripts/*.sh
- run: python3 -m tests.python.test_translation
- run: python3 -m tests.python.test_hardening
- run: python3 -m coverage erase
- run: python3 -m coverage run --branch --source=. --omit='.venv/*,tests/*,tools/*' -m unittest discover -v tests/python
- run: python3 -m coverage report --precision=1 --show-missing --fail-under="$BT_COVERAGE_FAIL_UNDER"
frontend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version-file: ".node-version"
- run: node -c static/translator.js
- run: node -c static/loader.js
- run: npm ci
- run: npm audit --audit-level=high
- run: npm test
- run: npx playwright install --with-deps --only-shell chromium
- run: npm run test:e2e
# Smoke test: build the image, run it, hit /ping, expect 200.
# Catches Dockerfile regressions (syntax, missing deps, broken entrypoint,
# USER appuser) that pure Python tests can't. Docker is a required artifact
# gate: runners without a working daemon fail instead of reporting a green
# workflow whose build and runtime checks never executed.
# Provider-specific Docker runner:
# GitHub-hosted ubuntu-latest includes an isolated Docker daemon. Keep public
# pull requests off homelab runners; Gitea binds this same gate separately.
docker-smoke:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
fetch-depth: 0
- name: Derive repository-scoped Docker names
# GITHUB_RUN_ID is only unique within one repository. Include a stable
# repository hash before using a shared/self-hosted Docker daemon.
run: sh scripts/ci-docker-names.sh
- name: Verify Docker daemon
run: docker version
- name: Build image
run: docker build -t "$SMOKE_IMAGE" .
- name: Exercise independent hardened roles
run: ./scripts/container-smoke.sh "$SMOKE_IMAGE" "$SMOKE_PREFIX"
- name: Exercise the managed lifecycle and migration
run: ./scripts/btctl-lifecycle-smoke.sh "$SMOKE_IMAGE" "$SMOKE_PREFIX"
- name: Exercise the stock-Unraid bootstrap without host Python
run: ./scripts/btctl-bootstrap-smoke.sh "$SMOKE_PREFIX"
- name: Exercise the Community Applications combined profile
run: ./scripts/ca-container-smoke.sh "$SMOKE_IMAGE" "$SMOKE_PREFIX-ca"
- name: Exercise the universal one-container hub
run: ./scripts/hub-container-smoke.sh "$SMOKE_IMAGE" "$SMOKE_PREFIX-hub"
- name: Exercise the managed hub fresh and retained lifecycle
run: ./scripts/hub-btctl-lifecycle-smoke.sh "$SMOKE_IMAGE" "$SMOKE_PREFIX-hl"