perf(ci): reduce CI quality check execution time by parallelizing and caching #10845
@@ -77,10 +77,18 @@ jobs:
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.cache/uv
|
||||
key: uv-${{ hashFiles('pyproject.toml') }}
|
||||
key: uv-${{ hashFiles('uv.lock', 'pyproject.toml') }}
|
||||
restore-keys: |
|
||||
uv-
|
||||
|
||||
- name: Cache nox virtualenvs
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: .nox
|
||||
key: nox-lint-${{ env.PYTHON_VERSION }}-${{ hashFiles('uv.lock', 'pyproject.toml') }}
|
||||
restore-keys: |
|
||||
nox-lint-${{ env.PYTHON_VERSION }}-
|
||||
|
||||
- name: Run lint and format checks via nox
|
||||
run: |
|
||||
mkdir -p build
|
||||
@@ -124,10 +132,18 @@ jobs:
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.cache/uv
|
||||
|
|
||||
key: uv-${{ hashFiles('pyproject.toml') }}
|
||||
key: uv-${{ hashFiles('uv.lock', 'pyproject.toml') }}
|
||||
restore-keys: |
|
||||
uv-
|
||||
|
||||
- name: Cache nox virtualenvs
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: .nox
|
||||
key: nox-typecheck-${{ env.PYTHON_VERSION }}-${{ hashFiles('uv.lock', 'pyproject.toml') }}
|
||||
restore-keys: |
|
||||
nox-typecheck-${{ env.PYTHON_VERSION }}-
|
||||
|
||||
- name: Run typecheck via nox
|
||||
run: |
|
||||
mkdir -p build
|
||||
@@ -170,10 +186,18 @@ jobs:
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.cache/uv
|
||||
key: uv-${{ hashFiles('pyproject.toml') }}
|
||||
key: uv-${{ hashFiles('uv.lock', 'pyproject.toml') }}
|
||||
restore-keys: |
|
||||
uv-
|
||||
|
||||
- name: Cache nox virtualenvs
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: .nox
|
||||
key: nox-security-${{ env.PYTHON_VERSION }}-${{ hashFiles('uv.lock', 'pyproject.toml') }}
|
||||
restore-keys: |
|
||||
nox-security-${{ env.PYTHON_VERSION }}-
|
||||
|
||||
- name: Run security scan and dead-code detection via nox
|
||||
run: |
|
||||
mkdir -p build
|
||||
@@ -217,10 +241,18 @@ jobs:
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.cache/uv
|
||||
key: uv-${{ hashFiles('pyproject.toml') }}
|
||||
key: uv-${{ hashFiles('uv.lock', 'pyproject.toml') }}
|
||||
restore-keys: |
|
||||
uv-
|
||||
|
||||
- name: Cache nox virtualenvs
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: .nox
|
||||
key: nox-quality-${{ env.PYTHON_VERSION }}-${{ hashFiles('uv.lock', 'pyproject.toml') }}
|
||||
restore-keys: |
|
||||
nox-quality-${{ env.PYTHON_VERSION }}-
|
||||
|
||||
- name: Run complexity check via nox
|
||||
run: |
|
||||
mkdir -p build
|
||||
@@ -288,10 +320,18 @@ jobs:
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.cache/uv
|
||||
key: uv-${{ hashFiles('pyproject.toml') }}
|
||||
key: uv-${{ hashFiles('uv.lock', 'pyproject.toml') }}
|
||||
restore-keys: |
|
||||
uv-
|
||||
|
||||
- name: Cache nox virtualenvs
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: .nox
|
||||
key: nox-unit-tests-${{ env.PYTHON_VERSION }}-${{ hashFiles('uv.lock', 'pyproject.toml') }}
|
||||
restore-keys: |
|
||||
nox-unit-tests-${{ env.PYTHON_VERSION }}-
|
||||
|
||||
- name: Run unit tests via nox
|
||||
run: |
|
||||
mkdir -p build
|
||||
@@ -364,10 +404,18 @@ jobs:
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.cache/uv
|
||||
key: uv-${{ hashFiles('pyproject.toml') }}
|
||||
key: uv-${{ hashFiles('uv.lock', 'pyproject.toml') }}
|
||||
restore-keys: |
|
||||
uv-
|
||||
|
||||
- name: Cache nox virtualenvs
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: .nox
|
||||
key: nox-integration-tests-${{ env.PYTHON_VERSION }}-${{ hashFiles('uv.lock', 'pyproject.toml') }}
|
||||
restore-keys: |
|
||||
nox-integration-tests-${{ env.PYTHON_VERSION }}-
|
||||
|
||||
- name: Run integration tests via nox
|
||||
run: |
|
||||
mkdir -p build
|
||||
@@ -517,10 +565,18 @@ jobs:
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.cache/uv
|
||||
key: uv-${{ hashFiles('pyproject.toml') }}
|
||||
key: uv-${{ hashFiles('uv.lock', 'pyproject.toml') }}
|
||||
restore-keys: |
|
||||
uv-
|
||||
|
||||
- name: Cache nox virtualenvs
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: .nox
|
||||
key: nox-build-${{ env.PYTHON_VERSION }}-${{ hashFiles('uv.lock', 'pyproject.toml') }}
|
||||
restore-keys: |
|
||||
nox-build-${{ env.PYTHON_VERSION }}-
|
||||
|
||||
- name: Build wheel via nox
|
||||
run: |
|
||||
mkdir -p build
|
||||
@@ -544,10 +600,13 @@ jobs:
|
||||
retention-days: 30
|
||||
|
||||
docker:
|
||||
# Only gate on unit_tests -- the most critical functional check.
|
||||
# lint/typecheck/security/quality run in parallel and are not
|
||||
# prerequisites for a successful Docker image build.
|
||||
# continue-on-error: true allows the status-check gate to pass even
|
||||
# when the docker:dind runner is unavailable (infrastructure issue).
|
||||
# The docker job still runs; only infrastructure failures are tolerated.
|
||||
needs: [load-versions, lint, typecheck, security, quality, unit_tests]
|
||||
needs: [unit_tests]
|
||||
continue-on-error: true
|
||||
runs-on: docker
|
||||
container:
|
||||
|
||||
@@ -54,11 +54,10 @@ Feature: CI workflow validation
|
||||
When I parse the CI workflow YAML
|
||||
Then the workflow env should set "PYTHON_VERSION" to "3.13"
|
||||
|
||||
Scenario: CI workflow coverage job depends on lint and typecheck
|
||||
Scenario: CI workflow coverage job depends on unit_tests
|
||||
Given the CI workflow file at ".forgejo/workflows/ci.yml"
|
||||
When I parse the CI workflow YAML
|
||||
Then the job "coverage" should depend on "lint"
|
||||
And the job "coverage" should depend on "typecheck"
|
||||
Then the job "coverage" should depend on "unit_tests"
|
||||
|
||||
Scenario: All required nox sessions are referenced
|
||||
Given the CI workflow file at ".forgejo/workflows/ci.yml"
|
||||
|
||||
@@ -44,10 +44,10 @@ Feature: Coverage threshold enforcement
|
||||
When I parse the coverage job from the CI workflow
|
||||
Then the coverage job should run nox -s coverage_report
|
||||
|
||||
Scenario: CI workflow coverage job depends on lint and typecheck
|
||||
Scenario: CI workflow coverage job depends on unit_tests
|
||||
Given the CI workflow file exists
|
||||
When I parse the coverage job from the CI workflow
|
||||
Then the coverage job should depend on lint and typecheck
|
||||
Then the coverage job should depend on unit_tests
|
||||
|
||||
Scenario: Coverage report session emits CI-parseable summary on success
|
||||
Given the noxfile.py exists
|
||||
|
||||
@@ -214,17 +214,13 @@ def step_check_ci_coverage_nox(context: Any) -> None:
|
||||
)
|
||||
|
||||
|
||||
@then("the coverage job should depend on lint and typecheck")
|
||||
@then("the coverage job should depend on unit_tests")
|
||||
def step_check_ci_coverage_deps(context: Any) -> None:
|
||||
job = context.ci_coverage_job
|
||||
needs = job.get("needs", [])
|
||||
if "lint" not in needs:
|
||||
if "unit_tests" not in needs:
|
||||
raise AssertionError(
|
||||
f"CI coverage job does not depend on 'lint': needs={needs}"
|
||||
)
|
||||
if "typecheck" not in needs:
|
||||
raise AssertionError(
|
||||
f"CI coverage job does not depend on 'typecheck': needs={needs}"
|
||||
f"CI coverage job does not depend on 'unit_tests': needs={needs}"
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user
BLOCKER: The
unit_testsdependency was deliberately included in the originalcoveragejobneedsto prevent misleading coverage results when unit tests are failing. The original comment stated:unit_tests is included so coverage only runs after tests pass, preventing misleading results when tests are still in-flight or failing.Removing
lint,typecheck,security, andqualityfrom coverage'sneedsis sound (those are independent static-analysis jobs). However, removingunit_testsis a correctness regression — coverage can now run and report passing metrics on code that has known failing tests.Recommended fix: Add
needs: [unit_tests]back to the coverage job:This preserves all parallelisation benefits against static-analysis jobs while retaining the safety gate against failing tests.