release: promote v2.3.0 general availability #29
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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" |