name: CI on: push: branches: [main, master] tags: ["v*"] pull_request: branches: [main, master] workflow_dispatch: jobs: # ───────────────────────────────────────────── # Lint, typecheck & unit tests # Draait op de host (self-hosted) waar Node 26 + # pnpm 11 geïnstalleerd zijn en internet beschikbaar is. # De job-container (docker mode) heeft GEEN outbound # internet, dus we draaien alles direct op de host. # ───────────────────────────────────────────── check: runs-on: self-hosted steps: - name: Checkout uses: actions/checkout@v4 with: repository: ${{ gitea.repository }} token: ${{ gitea.token }} - name: Toolchain check run: node scripts/check-node-toolchain.mjs - name: Install dependencies run: pnpm install --frozen-lockfile - name: Dependency security audit run: pnpm deps:audit - name: Lint run: pnpm biome:lint - name: CMS translation contracts run: pnpm i18n:check - name: Typecheck run: pnpm typecheck - name: Test env: SKIP_ENV_VALIDATION: 1 NODE_ENV: test DATABASE_URL: "mysql://test:test@localhost:3306/test?charset=utf8mb4" REDIS_URL: "redis://127.0.0.1:6379?connect_timeout=2" AUTH_SECRET: "ci-test-secret-key-that-is-long-enough" BCRYPT_ROUNDS: 4 run: | if [ -x /usr/bin/time ]; then /usr/bin/time -f 'Tests: %e seconds; peak process RSS: %M KiB' pnpm test:coverage --maxWorkers=4 else time pnpm test:coverage --maxWorkers=4 fi # ───────────────────────────────────────────── # Docker build & deploy # Draait op de host (self-hosted) zodat Docker # toegang heeft tot de daemon en volumes. # ───────────────────────────────────────────── deploy: needs: check if: gitea.event_name == 'push' && (gitea.ref_name == 'main' || gitea.ref_name == 'master') runs-on: self-hosted steps: - name: Checkout uses: actions/checkout@v4 with: repository: ${{ gitea.repository }} token: ${{ gitea.token }} - name: Build, deploy and smoke test shell: bash env: DEPLOY_BRANCH: ${{ gitea.ref_name }} run: bash scripts/ci-deploy.sh - name: Upload JavaScript size report if: always() uses: https://gitea.com/actions/gitea-upload-artifact@62ac910c5d3dfa85c7cb2df15afe2e342b2407c2 with: name: javascript-size-report path: build-reports/ if-no-files-found: warn retention-days: 14 # Publish only after checks and the production deployment have succeeded. # Serial execution also avoids two builds competing on the self-hosted runner. publish-container: needs: deploy if: gitea.event_name == 'push' && (gitea.ref_name == 'main' || gitea.ref_name == 'master') runs-on: self-hosted steps: - name: Checkout uses: actions/checkout@v4 with: repository: ${{ gitea.repository }} token: ${{ gitea.token }} - name: Build, verify portability and publish shell: bash env: REGISTRY_SERVER: ${{ gitea.server_url }} REGISTRY_REPOSITORY: ${{ gitea.repository }} REGISTRY_NAMESPACE: ${{ vars.CONTAINER_REGISTRY_NAMESPACE }} REGISTRY_USER: ${{ secrets.CONTAINER_REGISTRY_USER }} REGISTRY_TOKEN: ${{ secrets.CONTAINER_REGISTRY_TOKEN }} run: bash scripts/publish-container.sh