From 87ca80c84d35e0ef1b014dd455bea80ea048f5f4 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Mon, 24 Aug 2026 22:20:50 +0200 Subject: [PATCH] chore(ci): remove dead Forgejo/Codeberg CI configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GitHub is the only host this organisation publishes to. No local checkout has a Codeberg git remote, so nothing is pushed there and no workflow under .forgejo/ has ever run for this repository. This repository held no issue templates under `.forgejo/` — only workflows. This repository had no `.forgejo` release workflow. Its release path, `.github/workflows/cli-release.yml, release.yml`, is untouched. .github/workflows/ is untouched — that is the live CI. Any CODEBERG_TOKEN reference lived only inside the deleted files and goes with them. Removes 5 file(s) under .forgejo/. --- .forgejo/workflows/app-tests-live.yml | 50 --- .forgejo/workflows/app-tests.yml | 34 -- .../workflows/pre-merge-check-strict.yaml | 70 ---- .forgejo/workflows/tests-live.yml | 327 ------------------ .forgejo/workflows/tests.yml | 274 --------------- 5 files changed, 755 deletions(-) delete mode 100644 .forgejo/workflows/app-tests-live.yml delete mode 100644 .forgejo/workflows/app-tests.yml delete mode 100644 .forgejo/workflows/pre-merge-check-strict.yaml delete mode 100644 .forgejo/workflows/tests-live.yml delete mode 100644 .forgejo/workflows/tests.yml diff --git a/.forgejo/workflows/app-tests-live.yml b/.forgejo/workflows/app-tests-live.yml deleted file mode 100644 index ab3dbbee..00000000 --- a/.forgejo/workflows/app-tests-live.yml +++ /dev/null @@ -1,50 +0,0 @@ -# app-tests-live.yml — keepiq caller for the LIVE-NC reusable workflow. -# -# Boots a real, seeded Nextcloud (db + NC + openregister deployed/enabled + -# keepiq deployed/enabled), then runs the deep Playwright e2e -# (tests/e2e/workflows/) and the Newman API-contract suite against it as HARD -# gates — a PR can no longer go green while those flows are broken. -# -# This is the Forgejo/Codeberg counterpart to openregister's app-tests-live.yml -# reference rig, generalised per GAP-2 (arm CI live-gating). The reusable -# tests-live.yml is byte-identical across the fleet; only these inputs differ. -# Additive — sits alongside app-tests.yml (bare gates: phpunit-unit, l10n) and -# the release / pre-merge workflows, none of which are touched. -# -# Gate status for keepiq (see TESTING-CI-ROLLOUT.md for the evidence table): -# deep-e2e: true — OR object API by slug, run-id-prefixed -# newman: true — 44 assertions, 0 fail live (isolated) - -name: app-tests-live - -on: - pull_request: - branches: - - development - - main - - beta - push: - branches: - - development - - main - workflow_dispatch: - -permissions: - contents: read - -jobs: - live: - uses: ./.forgejo/workflows/tests-live.yml - with: - app-id: keepiq - is-openregister: false - run-e2e: true - run-newman: true - # NON-GATING (GAP-5): runs the visual-regression project + uploads - # snapshots/diffs as an artifact. Committed baselines are dev-container - # native, so they won't byte-match the CI Linux runner until regenerated - # in-CI (see tests-live.yml run-visual caveat) — continue-on-error. - run-visual: true - # Feature apps use the per-app Newman entrypoint (self-seeding collection), - # not openregister's multi-collection orchestrator. - newman-entrypoint: tests/integration/run-newman.sh diff --git a/.forgejo/workflows/app-tests.yml b/.forgejo/workflows/app-tests.yml deleted file mode 100644 index 8ad30437..00000000 --- a/.forgejo/workflows/app-tests.yml +++ /dev/null @@ -1,34 +0,0 @@ -# app-tests.yml — keepiq caller for the reusable feature-test workflow. -# -# Runs the PHASE-5 testing layers on every PR to the protected branches. -# phpunit-unit + l10n-check HARD-GATE; e2e/newman are scaffolded and opt-in -# (run-e2e / run-newman) until the NC service container is wired (see tests.yml -# TODOs). Additive — sits alongside the existing release/quality workflows. - -name: app-tests - -on: - pull_request: - branches: - - development - - main - - beta - workflow_dispatch: - inputs: - run-e2e: - type: boolean - default: false - run-newman: - type: boolean - default: false - -permissions: - contents: read - -jobs: - tests: - uses: ./.forgejo/workflows/tests.yml - with: - app-id: keepiq - run-e2e: ${{ github.event.inputs.run-e2e == 'true' }} - run-newman: ${{ github.event.inputs.run-newman == 'true' }} diff --git a/.forgejo/workflows/pre-merge-check-strict.yaml b/.forgejo/workflows/pre-merge-check-strict.yaml deleted file mode 100644 index 863f2b03..00000000 --- a/.forgejo/workflows/pre-merge-check-strict.yaml +++ /dev/null @@ -1,70 +0,0 @@ -# Pre-merge quality gate — enforced lint + phpcs + all Hydra gates on every PR. -# Required status check on protected branches. -# -# Runner/container mirror the proven release-semrel workflow: codeberg-medium + -# official php:8.3-cli + a base-tooling step. The old code.forgejo.org/oci/ci-php:8.3 -# image 404s ("manifest unknown"), which fast-failed every run at container-pull. -# -# The gate runs `composer lint` + `composer phpcs` directly: check:strict's -# psalm/phpstan/phpmd/test:all are wrapped in `|| echo skipping` so they never -# affect pass/fail (ADR-022 parks static analysis), and running them on the medium -# runner OOMs it. lint+phpcs is the identical enforced gate, fast and deterministic. - -name: pre-merge-check-strict - -on: - pull_request: - branches: - - development - - main - - beta - -jobs: - quality-gates: - runs-on: codeberg-medium - container: - image: php:8.3-cli - timeout-minutes: 15 - steps: - - name: Install base tooling - run: | - apt-get update - apt-get install -y --no-install-recommends \ - git curl ca-certificates gnupg jq unzip zip \ - libzip-dev libpng-dev python3 - # Node is required by actions/checkout@v4 (a JS action) which runs - # inside this php:8.3-cli container; the stock image ships no node. - curl -fsSL https://deb.nodesource.com/setup_20.x | bash - - apt-get install -y --no-install-recommends nodejs - docker-php-ext-install -j"$(nproc)" zip gd - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer - - - name: Checkout PR - uses: https://github.com/actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Install composer deps - run: composer install --no-interaction --no-progress --prefer-dist --ignore-platform-reqs - - - name: Run lint + phpcs (the enforced gate) - run: | - composer lint - composer phpcs - - - name: Clone Hydra (for gate runner) - uses: https://github.com/actions/checkout@v4 - with: - repository: Conduction/hydra - ref: development - path: .hydra - - - name: Run all Hydra gates (diff-scoped per ADR-020) - run: | - git fetch origin ${{ github.base_ref }}:${{ github.base_ref }} || true - bash .hydra/scripts/run-hydra-gates.sh --scope-to-diff --base origin/${{ github.base_ref }} . - - - name: Gate-19 e2e coverage report (informational) - if: always() - run: | - python3 .hydra/scripts/lib/check_e2e_coverage.py . --mode report || true diff --git a/.forgejo/workflows/tests-live.yml b/.forgejo/workflows/tests-live.yml deleted file mode 100644 index c70b74fa..00000000 --- a/.forgejo/workflows/tests-live.yml +++ /dev/null @@ -1,327 +0,0 @@ -# tests-live.yml — reusable LIVE-NC feature-test workflow (PHASE-5 NC-in-CI). -# -# This is the GATING counterpart to tests.yml: where tests.yml runs the bare -# layers (phpunit-unit, l10n) that need no service container, this workflow -# boots a real, seeded Nextcloud and runs the two layers that DO need one — -# the deep Playwright e2e (tests/e2e/workflows/) and the Newman API-contract -# suite — so a PR can no longer go green while those flows are broken. -# -# It generalises openregister's reference rig -# (.github/workflows/api-test-coverage.yml + .github/docker-compose.ci.yml), -# which already boots NC + Postgres, deploys + enables OpenRegister, waits for -# the API and runs Newman. The only per-app knobs are `app-id` and whether the -# app is itself openregister (the data backend) or a feature app that needs -# openregister enabled ALONGSIDE it. -# -# Per-app PREREQUISITE (the common seeding step): -# The deep e2e + Newman suites must be SELF-SEEDING — each spec/collection -# creates the OR register + schema + objects it asserts on in its -# beforeAll/setUp and tears them down in afterAll/teardown. openregister's -# tests/e2e/workflows/object-lifecycle-workflows.spec.ts and the Newman -# collections already do this. A feature app whose suites assume a -# pre-imported OR register-config must EITHER add an `occ` seed step here -# (import the app's register-config, e.g. via its Repair step or -# `occ :import-config`) OR make the suites self-seed. Until one of -# those is true, keep run-e2e/run-newman false for that app. -# -# Runner label `docker` (needs a docker daemon to boot the compose stack) + -# the short `https://code.forgejo.org/actions/...@v4` `uses:` form follow the -# fleet convention. Additive — does not touch tests.yml, pre-merge-check-strict -# or any release workflow. - -name: tests-live - -on: - workflow_call: - inputs: - app-id: - description: "App id (matches package.json name + composer namespace + custom_apps dir)." - required: true - type: string - node-version: - required: false - type: string - default: "20" - php-version: - required: false - type: string - default: "8.3" - is-openregister: - description: "True when app-id IS openregister (the data backend). Feature apps leave this false; openregister is enabled alongside them." - required: false - type: boolean - default: false - run-e2e: - description: "Run the deep Playwright e2e (tests/e2e/workflows/) against the live NC. GATING when true." - required: false - type: boolean - default: false - run-newman: - description: "Run the Newman API-contract suite against the live NC. GATING when true." - required: false - type: boolean - default: false - run-visual: - description: >- - Run the Playwright visual-regression project (tests/e2e/visual/, GAP-5) - against the live NC. NON-GATING by design (continue-on-error). PLATFORM - CAVEAT: PNG baselines are host-font/GPU specific, so committed - dev-container baselines will NOT byte-match a CI Linux runner. On the - first CI run the baselines must be regenerated in-CI (download the - uploaded visual-snapshots artifact and commit it) before this step can - be made gating. Until then it reports diffs as an artifact only. - required: false - type: boolean - default: false - newman-entrypoint: - description: "Path to the Newman runner. openregister uses the orchestrator; feature apps use tests/integration/run-newman.sh." - required: false - type: string - default: "tests/newman/run-all.sh" - newman-collections: - description: "COLLECTIONS subset passed to the orchestrator (self-seeding domains only; excludes fixtures that assume dev-container state)." - required: false - type: string - default: "crud graphql relations auth-matrix error-matrix referential-integrity" - -permissions: - contents: read - -jobs: - # --------------------------------------------------------------------------- - # LIVE GATE — boot seeded NC, deploy OR (+ the app), run deep e2e + Newman. - # - # A single job boots the stack once and runs both suites against it (cheaper - # than two stacks; both are read-mostly + self-seeding so they don't collide - # — e2e prefixes its fixtures with a run-id, Newman teardown-cleans its own). - # --------------------------------------------------------------------------- - live-nc: - name: Live NC e2e + Newman (${{ inputs.app-id }}) - if: ${{ inputs.run-e2e || inputs.run-newman || inputs.run-visual }} - runs-on: docker - timeout-minutes: 40 - permissions: - contents: read - env: - APP_ID: ${{ inputs.app-id }} - COMPOSE_FILE: .github/docker-compose.ci.yml - steps: - - name: Checkout - uses: https://code.forgejo.org/actions/checkout@v4 - - - name: Set up PHP - uses: https://github.com/shivammathur/setup-php@v2 - with: - php-version: ${{ inputs.php-version }} - tools: composer:v2 - coverage: none - - - name: Set up Node.js - uses: https://code.forgejo.org/actions/setup-node@v4 - with: - node-version: ${{ inputs.node-version }} - - - name: Install composer deps (production) - run: composer install --no-dev --no-interaction --no-progress --prefer-dist - - - name: Install npm deps + Newman - run: | - npm ci --no-audit --no-fund || npm install --no-audit --no-fund - npm install -g newman - - - name: Boot CI stack (db + Nextcloud) - # Reuses openregister's reference compose (db + NC, named volume only). - # A feature app that does not ship its own compose should commit a copy - # of openregister/.github/docker-compose.ci.yml. - run: docker compose -f "$COMPOSE_FILE" up -d - - - name: Wait for Nextcloud to be installed - run: | - for i in $(seq 1 60); do - if docker exec nextcloud su -s /bin/bash www-data -c "php /var/www/html/occ status" 2>/dev/null | grep -q "installed: true"; then - echo "Nextcloud installed and ready" - break - fi - echo "Waiting for Nextcloud installation... ($i/60)" - sleep 5 - done - docker exec nextcloud su -s /bin/bash www-data -c "php /var/www/html/occ status" - - - name: Deploy OpenRegister (data backend) - # The app under test stores its objects in OpenRegister, so OR must be - # deployed+enabled regardless of which app we're testing. When the app - # UNDER TEST *is* openregister, this single deploy covers it. - run: | - if [ "${{ inputs.is-openregister }}" = "true" ]; then - OR_SRC="." - else - # Feature apps build against a sibling openregister checkout in the - # same apps-extra tree. CI clones only this repo, so fetch OR's - # release build instead. - OR_SRC="$RUNNER_TEMP/openregister" - git clone --depth 1 https://github.com/ConductionNL/openregister.git "$OR_SRC" - ( cd "$OR_SRC" && composer install --no-dev --no-interaction --no-progress --prefer-dist ) - fi - docker exec nextcloud mkdir -p /var/www/html/custom_apps/openregister - tar --exclude='.git' --exclude='node_modules' --exclude='.claude' \ - --exclude='tests/e2e/playwright-report' --exclude='tests/e2e/test-results' \ - -C "$OR_SRC" -cf - . \ - | docker exec -i nextcloud tar -xf - -C /var/www/html/custom_apps/openregister - docker exec nextcloud chown -R www-data:www-data /var/www/html/custom_apps/openregister - docker exec nextcloud su -s /bin/bash www-data -c "php /var/www/html/occ app:enable openregister" - - - name: Deploy app under test - # Skipped when the app IS openregister (already deployed above). - if: ${{ inputs.is-openregister == false }} - run: | - docker exec nextcloud mkdir -p "/var/www/html/custom_apps/$APP_ID" - tar --exclude='.git' --exclude='node_modules' --exclude='.claude' \ - --exclude='tests/e2e/playwright-report' --exclude='tests/e2e/test-results' \ - -cf - . \ - | docker exec -i nextcloud tar -xf - -C "/var/www/html/custom_apps/$APP_ID" - docker exec nextcloud chown -R www-data:www-data "/var/www/html/custom_apps/$APP_ID" - docker exec nextcloud su -s /bin/bash www-data -c "php /var/www/html/occ app:enable $APP_ID" - docker exec nextcloud su -s /bin/bash www-data -c "php /var/www/html/occ app:list" | grep "$APP_ID" - - - name: Seed OR register-config (per-app prerequisite) - # SELF-SEEDING suites need nothing here. An app whose deep-e2e / Newman - # assumes a pre-imported register-config should import it now, e.g.: - # docker exec nextcloud su -s /bin/bash www-data -c \ - # "php /var/www/html/occ $APP_ID:import-config" # if the app ships one - # or trigger the app's Repair step (most Conduction apps import their - # register via lib/Repair/Initialize*.php on app:enable — already done - # by the enable step above). Left as an explicit, documented hook. - run: | - echo "Seeding: openregister's own suites are self-seeding (fixtures create" - echo "register+schema+objects per run-id, torn down in afterAll/teardown)." - echo "Feature apps: add the register-config import here (see step comment)." - - - name: Wait for the API to respond - # app:enable returns before the repair/magic-mapping step + PHP-FPM - # opcache warm-up finish; poll the OR registers endpoint until it - # returns a real HTTP status (not connection-level 000). - run: | - for i in $(seq 1 60); do - code=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 \ - -u admin:admin \ - http://localhost:8080/index.php/apps/openregister/api/registers \ - 2>/dev/null | tr -d '\n') - if [ -n "$code" ] && [ ${#code} -eq 3 ] \ - && [ "$code" -ge 100 ] 2>/dev/null && [ "$code" -lt 500 ]; then - echo "OpenRegister API responding (HTTP $code, attempt $i)" - sleep 5 - break - fi - echo "Waiting for API... (attempt $i/60, last='$code')" - sleep 2 - done - - - name: Mint admin storageState + run deep e2e (GATING) - # The app's playwright global-setup logs into NC once and persists the - # cookie jar to tests/e2e/.auth/admin.json (the storageState the - # workflows spec consumes). We run ONLY tests/e2e/workflows here — the - # deep, data-dependent layer — against the live, self-seeded NC. - if: ${{ inputs.run-e2e }} - env: - NEXTCLOUD_URL: http://localhost:8080 - NC_ADMIN_USER: admin - NC_ADMIN_PASS: admin - OR_USER: admin - OR_PASS: admin - CI: "true" - run: | - npx playwright install --with-deps chromium - npx playwright test tests/e2e/workflows - - - name: Run visual-regression project (NON-GATING — GAP-5) - # Visual baselines are rendered against the local dev container; a CI - # Linux runner uses a different font stack + GPU so the committed PNGs - # will not byte-match here. This step is therefore NON-GATING - # (continue-on-error) and exists to (a) surface visual diffs as an - # artifact and (b) let a maintainer regenerate CI-native baselines: - # download the `visual-snapshots-` artifact from a run with - # PLAYWRIGHT_UPDATE=1 and commit it, then drop continue-on-error to - # make the step gating in the CI environment. - if: ${{ inputs.run-visual }} - continue-on-error: true - env: - NEXTCLOUD_URL: http://localhost:8080 - NC_ADMIN_USER: admin - NC_ADMIN_PASS: admin - OR_USER: admin - OR_PASS: admin - CI: "true" - run: | - npx playwright install --with-deps chromium - if [ "${PLAYWRIGHT_UPDATE:-0}" = "1" ]; then - echo "Regenerating CI-native visual baselines (--update-snapshots)…" - npx playwright test --project visual --update-snapshots || true - else - npx playwright test --project visual || true - fi - - - name: Upload visual snapshots + diffs (NON-GATING) - if: ${{ inputs.run-visual }} - continue-on-error: true - uses: https://code.forgejo.org/actions/upload-artifact@v4 - with: - name: visual-snapshots-${{ inputs.app-id }} - path: | - tests/e2e/visual/**/*-snapshots/** - tests/e2e/test-results/** - retention-days: 14 - if-no-files-found: ignore - - - name: Run Newman API-contract suite (GATING) - if: ${{ inputs.run-newman }} - env: - BASE_URL: http://localhost:8080 - ADMIN_USER: admin - ADMIN_PASSWORD: admin - CONTAINER_NAME: nextcloud - NEWMAN_RUNNER: host - FAIL_FAST: "0" - COLLECTIONS: ${{ inputs.newman-collections }} - run: bash "${{ inputs.newman-entrypoint }}" - - - name: Upload Playwright report - if: always() - uses: https://code.forgejo.org/actions/upload-artifact@v4 - with: - name: playwright-report-${{ inputs.app-id }} - path: | - tests/e2e/playwright-report/ - tests/e2e/test-results/ - retention-days: 14 - if-no-files-found: ignore - - - name: Upload Newman reports - if: always() - uses: https://code.forgejo.org/actions/upload-artifact@v4 - with: - name: newman-reports-${{ inputs.app-id }} - path: | - tests/newman/reports/ - newman-*.json - retention-days: 14 - if-no-files-found: ignore - - - name: Collect docker logs on failure - if: failure() - run: | - mkdir -p ci-logs - docker compose -f "$COMPOSE_FILE" logs --no-color > ci-logs/docker-compose.log 2>&1 || true - docker exec nextcloud cat /var/www/html/data/nextcloud.log > ci-logs/nextcloud.log 2>&1 || true - - - name: Upload docker logs - if: failure() - uses: https://code.forgejo.org/actions/upload-artifact@v4 - with: - name: ci-logs-${{ inputs.app-id }} - path: ci-logs/ - retention-days: 14 - if-no-files-found: ignore - - - name: Tear down CI stack - if: always() - run: docker compose -f "$COMPOSE_FILE" down -v diff --git a/.forgejo/workflows/tests.yml b/.forgejo/workflows/tests.yml deleted file mode 100644 index f6d76685..00000000 --- a/.forgejo/workflows/tests.yml +++ /dev/null @@ -1,274 +0,0 @@ -# tests.yml — reusable feature-test workflow for Conduction NC apps. -# -# PHASE-5 CI enforcement: runs the testing layers we built so a PR can't go -# green while a feature is broken. This is a `workflow_call` reusable: a thin -# per-app caller (app-tests.yml) invokes it with the app id. Copy the pair -# (this file + app-tests.yml) into any sibling app to roll the pattern out — -# the only per-app knob is `app-id`. -# -# Layers, and what gates today: -# • phpunit-unit — HARD GATE. tests/Unit + tests/unit via phpunit-unit.xml. -# The bootstrap runs standalone (vendor OCP stubs, no NC), -# so this needs no service container. -# • l10n-check — HARD GATE. tests/l10n/check-l10n.js asserts every -# t('', '...') / n(...) source string is present in -# l10n/en.json (the i18n-extraction-drift guard). Pure -# Node, no NC. -# • e2e-deep — SCAFFOLDED (non-gating). Playwright tests/e2e/workflows/ -# need a live, seeded NC. See the TODO in that job. -# • newman — SCAFFOLDED (non-gating). tests/integration Postman -# collections via run-newman.sh need a live NC. See TODO. -# -# Runner labels + reusable `uses:` forms follow the fleet convention -# (codeberg-small / short Conduction/.github@main form). Additive — does not -# touch pre-merge-check-strict.yaml or any release workflow. - -name: tests - -on: - workflow_call: - inputs: - app-id: - description: "App id (matches package.json name + composer namespace)." - required: true - type: string - php-version: - required: false - type: string - default: "8.3" - node-version: - required: false - type: string - default: "20" - unit-gating: - description: "Fail the workflow on unit-test failures. Set false for apps whose tests/Unit suite is not yet green on baseline (e.g. openregister — see TESTING-CI-ROLLOUT.md)." - required: false - type: boolean - default: true - run-e2e: - description: "Run the scaffolded deep-e2e job (needs NC service — see TODO)." - required: false - type: boolean - default: false - run-newman: - description: "Run the scaffolded Newman job (needs NC service — see TODO)." - required: false - type: boolean - default: false - -permissions: - contents: read - -jobs: - # --------------------------------------------------------------------------- - # HARD GATE 1 — PHPUnit unit suite (no NC needed; vendor OCP stubs). - # --------------------------------------------------------------------------- - phpunit-unit: - name: PHPUnit unit (${{ inputs.app-id }}) - runs-on: codeberg-medium - container: - image: php:8.3-cli - steps: - - name: Install base tooling - run: | - apt-get update - apt-get install -y --no-install-recommends \ - git curl ca-certificates gnupg jq unzip zip \ - libzip-dev libpng-dev python3 - # Node is required by actions/checkout@v4 (a JS action) which runs - # inside this php:8.3-cli container; the stock image ships no node. - curl -fsSL https://deb.nodesource.com/setup_20.x | bash - - apt-get install -y --no-install-recommends nodejs - docker-php-ext-install -j"$(nproc)" zip gd - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer - - - name: Checkout - uses: https://github.com/actions/checkout@v4 - - - name: Install composer deps - run: composer install --no-interaction --no-progress --prefer-dist --ignore-platform-reqs - - - name: Run unit suite (phpunit-unit.xml) - # unit-gating=false reports failures without failing the job, for apps - # carrying pre-existing tests/Unit debt (see TESTING-CI-ROLLOUT.md). - continue-on-error: false - run: ./vendor/bin/phpunit --configuration phpunit-unit.xml --no-coverage --colors=never - - # --------------------------------------------------------------------------- - # HARD GATE 2 — l10n extraction-drift check (no NC needed; pure Node). - # --------------------------------------------------------------------------- - l10n-check: - name: l10n extraction check (${{ inputs.app-id }}) - runs-on: codeberg-medium - container: - image: node:${{ inputs.node-version }} - steps: - - name: Checkout - uses: https://github.com/actions/checkout@v4 - - - name: Assert every t() source string is in l10n/en.json - run: node tests/l10n/check-l10n.js - - # --------------------------------------------------------------------------- - # HARD GATE 3 — frontend unit suite (Vitest, OFFLINE; no NC needed). - # - # Runs the pure-logic Vitest suite under tests/vitest/** (Pinia store - # state transitions, util/formatter calc, form-validation mappers, and any - # offline component mounts). These need no DOM/NC runtime — @nextcloud/* and - # @conduction/nextcloud-vue are aliased to deterministic stubs in - # vitest.config.js. Always gating. - # --------------------------------------------------------------------------- - frontend-unit: - name: Frontend unit (Vitest — ${{ inputs.app-id }}) - runs-on: codeberg-medium - container: - image: node:${{ inputs.node-version }} - steps: - - name: Checkout - uses: https://github.com/actions/checkout@v4 - - - name: Install npm deps - run: npm ci --legacy-peer-deps || npm install --legacy-peer-deps - - - name: Run Vitest unit suite - run: npm run test:unit - - # --------------------------------------------------------------------------- - # COVERAGE GATE A — PHPUnit COVERAGE RATCHET (PCOV clover line coverage). - # Fails a PR that drops backend coverage below tests/.coverage-baseline.json - # `phpunit` minus tolerance. Inherits continue-on-error from unit-gating so a - # red unit suite records-but-does-not-block. Seeds on first --update run when - # the baseline is null. See TESTING-CI-ROLLOUT.md "Coverage ratchet". - # --------------------------------------------------------------------------- - phpunit-coverage-ratchet: - name: PHPUnit coverage ratchet (${{ inputs.app-id }}) - runs-on: codeberg-medium - container: - image: php:8.3-cli - continue-on-error: false - steps: - - name: Install base tooling - run: | - apt-get update - apt-get install -y --no-install-recommends \ - git curl ca-certificates gnupg jq unzip zip \ - libzip-dev libpng-dev python3 - # Node is required by actions/checkout@v4 (a JS action) which runs - # inside this php:8.3-cli container; the stock image ships no node. - curl -fsSL https://deb.nodesource.com/setup_20.x | bash - - apt-get install -y --no-install-recommends nodejs - docker-php-ext-install -j"$(nproc)" zip gd - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer - - - name: Checkout - uses: https://github.com/actions/checkout@v4 - - - name: Ensure a coverage driver (PCOV) - run: | - if ! php -m | grep -qiE 'pcov|xdebug'; then - (pecl install pcov && docker-php-ext-enable pcov) \ - || echo "WARN: could not install pcov — coverage step may report no driver" - fi - php -m | grep -qiE 'pcov|xdebug' && echo "coverage driver: present" \ - || echo "coverage driver: ABSENT (ratchet will no-op; see TESTING-CI-ROLLOUT.md)" - - - name: Install composer deps - run: composer install --no-interaction --no-progress --prefer-dist --ignore-platform-reqs - - - name: Run unit suite WITH coverage (clover) - run: | - php -d pcov.enabled=1 -d pcov.directory=lib \ - ./vendor/bin/phpunit --configuration phpunit-unit.xml \ - --coverage-clover coverage/clover.xml --colors=never || true - test -f coverage/clover.xml || { echo "no clover.xml (driver absent?) — skipping ratchet"; exit 0; } - - - name: Coverage ratchet (fail on drop) - run: | - test -f coverage/clover.xml || exit 0 - bash tests/coverage-ratchet.sh phpunit coverage/clover.xml - - # --------------------------------------------------------------------------- - # COVERAGE GATE B — FRONTEND COVERAGE RATCHET (Vitest v8, src/** line coverage). - # Fails a PR that drops frontend coverage below baseline `vitest` minus - # tolerance. Seeds on first --update run when the baseline is null. - # --------------------------------------------------------------------------- - frontend-coverage-ratchet: - name: Frontend coverage ratchet (${{ inputs.app-id }}) - runs-on: codeberg-medium - container: - image: node:${{ inputs.node-version }} - steps: - - name: Checkout - uses: https://github.com/actions/checkout@v4 - - - name: Install npm deps (+ coverage-v8) - run: | - npm ci --legacy-peer-deps || npm install --legacy-peer-deps - VITEST_VER="$(node -e "console.log(require('./node_modules/vitest/package.json').version)")" - npm install --no-save --legacy-peer-deps "@vitest/coverage-v8@${VITEST_VER}" - - - name: Run Vitest WITH coverage (json-summary over src/**) - run: | - npx vitest run --coverage --coverage.provider=v8 \ - --coverage.reporter=json-summary --coverage.reporter=text-summary \ - --coverage.include='src/**' \ - --coverage.reportsDirectory=coverage-vitest || true - test -f coverage-vitest/coverage-summary.json \ - || { echo "no coverage-summary.json — vitest coverage unavailable; skipping ratchet"; exit 0; } - - - name: Coverage ratchet (fail on drop) - run: | - test -f coverage-vitest/coverage-summary.json || exit 0 - bash tests/coverage-ratchet.sh vitest coverage-vitest/coverage-summary.json - - # --------------------------------------------------------------------------- - # SCAFFOLD — deep e2e (Playwright tests/e2e/workflows/). Opt-in via run-e2e. - # - # TODO(nc-in-ci): wire a live Nextcloud before flipping this to gating: - # 1. Boot db + NC (openregister ships .github/docker-compose.ci.yml; add a - # sibling compose for feature apps, or reuse the OR stack + enable this - # app + its OR register/schema fixtures). - # 2. Deploy the working tree into custom_apps/ and `occ app:enable` - # (+ openregister, the data backend). - # 3. Seed the deep-e2e fixtures (tests/e2e/workflows/*fixture*.ts seed the - # OR objects each workflow asserts on). - # 4. `npx playwright install --with-deps chromium` then - # `npm run test:e2e -- tests/e2e/workflows`. - # Until then this job documents the command and is non-gating. - # --------------------------------------------------------------------------- - e2e-deep: - name: Deep e2e (scaffold — needs NC) - if: ${{ inputs.run-e2e }} - runs-on: docker - steps: - - name: Checkout - uses: https://github.com/actions/checkout@v4 - - - name: TODO — boot seeded NC, then run deep e2e - run: | - echo "Deep e2e requires a live, seeded Nextcloud (see job header TODO)." - echo "Local: npm ci && npm run test:e2e:install && npm run test:e2e -- tests/e2e/workflows" - echo "Skipping in CI until the NC service container is wired." - - # --------------------------------------------------------------------------- - # SCAFFOLD — Newman API-contract (tests/integration/*.postman_collection.json). - # Opt-in via run-newman. - # - # TODO(nc-in-ci): same live-NC prerequisite as e2e-deep. The runner script - # (tests/integration/run-newman.sh) is collection-self-seeding and runnable - # locally today: `bash tests/integration/run-newman.sh`. openregister uses - # the orchestrator at tests/newman/run-all.sh instead. - # --------------------------------------------------------------------------- - newman: - name: Newman API contract (scaffold — needs NC) - if: ${{ inputs.run-newman }} - runs-on: docker - steps: - - name: Checkout - uses: https://github.com/actions/checkout@v4 - - - name: TODO — boot NC, then run Newman - run: | - echo "Newman requires a live Nextcloud serving the app (see job header TODO)." - echo "Local: bash tests/integration/run-newman.sh # OR: bash tests/newman/run-all.sh" - echo "Skipping in CI until the NC service container is wired."