From d6d5f40359cb5816496d42c876e7fb1f76c6b790 Mon Sep 17 00:00:00 2001 From: Millian Lamiaux Date: Mon, 13 Jul 2026 15:44:52 +0200 Subject: [PATCH] ci: gate admin-web docker build on unit tests and remove admin-web job from ci.yml - admin-web-docker.yml: add 'test' job (Node 22, npm ci, tsc --noEmit, vitest run) gated by the anti-[skip ci] guard, wire needs: [test] on build-validation and semantic-release, and needs: [semantic-release, test] on build-and-push. Tests now run as a gate before Docker build validation on PRs and before semantic-release on main. - ci.yml: drop the redundant admin-web-test job (now covered by the test job in admin-web-docker.yml on PRs), remove the admin-web path filter and output from the changes job, simplify deploy-functions.needs. - scripts/verify-admin-web-docker.sh: update check_workflow_jobs to expect 4 jobs (test + build-validation + semantic-release + build-and-push) and check_workflow_needs to expect build-and-push needs [semantic-release, test] so the verify script stays green with the new job topology. --- .github/workflows/admin-web-docker.yml | 30 ++++++++++++++++++- .github/workflows/ci.yml | 40 +------------------------- scripts/verify-admin-web-docker.sh | 12 ++++---- 3 files changed, 36 insertions(+), 46 deletions(-) diff --git a/.github/workflows/admin-web-docker.yml b/.github/workflows/admin-web-docker.yml index c10a200..382159f 100644 --- a/.github/workflows/admin-web-docker.yml +++ b/.github/workflows/admin-web-docker.yml @@ -17,8 +17,35 @@ env: NODE_VERSION: "22" jobs: + test: + name: Admin Web Tests + runs-on: ubuntu-latest + timeout-minutes: 10 + if: | + !contains(github.event.head_commit.message, '[skip ci]') && + !contains(github.event.head_commit.message, '[ci skip]') + defaults: + run: + working-directory: admin-web + steps: + - name: Checkout + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - name: Setup Node.js + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: npm + cache-dependency-path: admin-web/package-lock.json + - name: Install dependencies + run: npm ci + - name: Type check + run: npx tsc --noEmit + - name: Run unit tests + run: npx vitest run + build-validation: name: Docker Build Validation + needs: [test] if: github.event_name == 'pull_request' runs-on: ubuntu-latest timeout-minutes: 15 @@ -47,6 +74,7 @@ jobs: semantic-release: name: Semantic Release + needs: [test] runs-on: ubuntu-latest timeout-minutes: 10 if: | @@ -100,7 +128,7 @@ jobs: build-and-push: name: Build & Push Docker Image - needs: semantic-release + needs: [semantic-release, test] runs-on: ubuntu-latest timeout-minutes: 15 if: | diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1948f33..620e979 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,6 @@ jobs: name: Detect Changes runs-on: ubuntu-latest outputs: - admin-web: ${{ steps.filter.outputs.admin-web }} youtube-worker: ${{ steps.filter.outputs.youtube-worker }} supabase-functions: ${{ steps.filter.outputs.supabase-functions }} steps: @@ -22,9 +21,6 @@ jobs: id: filter with: filters: | - admin-web: - - 'admin-web/**' - - '.github/workflows/ci.yml' youtube-worker: - 'youtube-worker/**' - '.github/workflows/ci.yml' @@ -33,40 +29,6 @@ jobs: - 'youtube-worker/**' - '.github/workflows/ci.yml' - # ── Admin Web: Next.js ── - admin-web-test: - name: Admin Web CI - needs: changes - if: needs.changes.outputs.admin-web == 'true' - runs-on: ubuntu-latest - defaults: - run: - working-directory: admin-web - steps: - - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'npm' - cache-dependency-path: admin-web/package-lock.json - - - name: Install dependencies - run: npm ci - - - name: Type check - run: npx tsc --noEmit - - - name: Run unit tests - run: npx vitest run - - - name: Install Playwright browsers - run: npx playwright install --with-deps chromium - - - name: Run E2E tests - run: npx playwright test - # ── YouTube Worker: Node.js microservice ── youtube-worker-check: name: YouTube Worker @@ -95,7 +57,7 @@ jobs: # ── Deploy: Supabase edge functions + YouTube worker ── deploy-functions: name: Deploy - needs: [changes, admin-web-test, youtube-worker-check] + needs: [changes, youtube-worker-check] if: | always() && github.ref == 'refs/heads/main' && diff --git a/scripts/verify-admin-web-docker.sh b/scripts/verify-admin-web-docker.sh index cd410ad..210606c 100755 --- a/scripts/verify-admin-web-docker.sh +++ b/scripts/verify-admin-web-docker.sh @@ -263,9 +263,9 @@ check_workflow_valid() { yaml_valid ".github/workflows/admin-web-docker.yml" "admin-web-docker.yml is valid YAML" } -# --- workflow: exactly 3 jobs --------------------------------------- # +# --- workflow: exactly 4 jobs --------------------------------------- # check_workflow_jobs() { - local label="workflow has exactly 3 jobs: build-validation + semantic-release + build-and-push" + local label="workflow has exactly 4 jobs: test + build-validation + semantic-release + build-and-push" local f=".github/workflows/admin-web-docker.yml" if [[ ! -f "$f" ]]; then fail "$label" "file missing" @@ -281,16 +281,16 @@ print(','.join(sorted(jobs))) fail "$label" "could not parse jobs" return fi - if [[ "$out" == "build-and-push,build-validation,semantic-release" ]]; then + if [[ "$out" == "build-and-push,build-validation,semantic-release,test" ]]; then pass "$label" else fail "$label" "jobs=[$out]" fi } -# --- workflow: build-and-push needs semantic-release --------------- # +# --- workflow: build-and-push needs semantic-release + test ---------- # check_workflow_needs() { - local label="build-and-push needs: semantic-release" + local label="build-and-push needs: [semantic-release, test]" local f=".github/workflows/admin-web-docker.yml" if [[ ! -f "$f" ]]; then fail "$label" "file missing" @@ -305,7 +305,7 @@ n=bp.get('needs') if isinstance(n,list): print(','.join(n)) else: print(str(n)) " "$f" 2>/dev/null || true) - if [[ "$out" == "semantic-release" ]]; then + if [[ "$out" == "semantic-release,test" ]]; then pass "$label" else fail "$label" "needs='$out'"