diff --git a/.github/workflows/deploy-demo.yml b/.github/workflows/deploy-demo.yml index c72f6dcf4..2d9f41de0 100644 --- a/.github/workflows/deploy-demo.yml +++ b/.github/workflows/deploy-demo.yml @@ -1,4 +1,4 @@ -name: Deploy demo +name: "Deploy: Demo" # Keeps https://demo.bulwarkmail.org on the published release image. It used to # follow ghcr.io/bulwarkmail/webmail:latest through Watchtower; now the deploy @@ -18,7 +18,7 @@ name: Deploy demo on: workflow_run: - workflows: ["Publish Docker Image on Release"] + workflows: ["Docker: Release image"] types: [completed] workflow_dispatch: inputs: diff --git a/.github/workflows/docker-publish-lite.yml b/.github/workflows/docker-publish-lite.yml index 3ca11187e..9b48d627b 100644 --- a/.github/workflows/docker-publish-lite.yml +++ b/.github/workflows/docker-publish-lite.yml @@ -1,12 +1,12 @@ -name: Publish Lite Docker Image +name: "Lite: Docker image" # Bulwark Lite as a container (Dockerfile.lite): the static export behind an # unprivileged nginx. Every run first builds a demo image and drives it with -# the Lite smoke suite, so the nginx routing and headers are tested, not only +# the Lite E2E suite, so the nginx routing and headers are tested, not only # the files. Then: # - release: ghcr.io/-lite (semver tags, latest unless prerelease) # - push to main: ghcr.io/-lite-beta (latest + sha) -# - pull request: smoke test only +# - pull request: E2E test only # Published images get a signed build provenance attestation, pushed to GHCR # next to them: `gh attestation verify oci://: --owner bulwarkmail`. @@ -36,7 +36,8 @@ on: workflow_dispatch: jobs: - smoke: + e2e: + name: E2E (container) runs-on: ubuntu-latest timeout-minutes: 30 permissions: @@ -54,13 +55,13 @@ jobs: context: . file: Dockerfile.lite load: true - tags: bulwark-lite:smoke + tags: bulwark-lite:e2e build-args: | GIT_COMMIT=${{ github.sha }} LITE_DEMO_MODE=true LITE_LOCALES=en,de - cache-from: type=gha,scope=lite-smoke - cache-to: type=gha,mode=max,scope=lite-smoke + cache-from: type=gha,scope=lite-e2e + cache-to: type=gha,mode=max,scope=lite-e2e # Read-only root, like a hardened Kubernetes pod: nginx only needs /tmp # and the directory the entrypoint renders its config into. @@ -69,7 +70,7 @@ jobs: docker run -d --name lite -p 4173:8080 \ --read-only --tmpfs /tmp --tmpfs /etc/nginx/conf.d:uid=101,gid=101 \ -e LITE_CSP_CONNECT_SRC=https://mail.example.com \ - bulwark-lite:smoke + bulwark-lite:e2e for i in $(seq 1 30); do curl -fsS http://localhost:4173/lite-build.json && exit 0 sleep 1 @@ -82,7 +83,7 @@ jobs: echo '{"appName":"Mounted","demoMode":true}' > "$RUNNER_TEMP/config.json" docker run -d --name lite-mounted -p 4174:8080 \ -v "$RUNNER_TEMP/config.json:/usr/share/nginx/html/config.json:ro" \ - bulwark-lite:smoke + bulwark-lite:e2e for i in $(seq 1 30); do curl -fsS http://localhost:4174/config.json | grep -q '"Mounted"' && break [ "$i" = 30 ] && { docker logs lite-mounted; exit 1; } @@ -102,7 +103,7 @@ jobs: - name: Install Playwright browser run: npx playwright install --with-deps chromium - - name: Run smoke test against the container + - name: Run E2E test against the container env: LITE_SMOKE_BASE_URL: http://localhost:4173 LITE_SMOKE_EXPECT_CONNECT_SRC: https://mail.example.com @@ -116,12 +117,13 @@ jobs: if: failure() uses: actions/upload-artifact@v4 with: - name: lite-container-smoke-report + name: lite-container-e2e-report path: playwright-report retention-days: 7 publish: - needs: smoke + name: Publish + needs: e2e if: github.event_name != 'pull_request' runs-on: ubuntu-latest timeout-minutes: 30 diff --git a/.github/workflows/docker-publish-releases.yml b/.github/workflows/docker-publish-releases.yml index 43e6d8552..fb9117dca 100644 --- a/.github/workflows/docker-publish-releases.yml +++ b/.github/workflows/docker-publish-releases.yml @@ -1,4 +1,4 @@ -name: Publish Docker Image on Release +name: "Docker: Release image" # `latest` moves only for a published stable release, or for a manual run # dispatched on a stable release tag (to rebuild one). A dispatch on a @@ -16,6 +16,7 @@ env: jobs: build: + name: Build (${{ matrix.platform == 'linux/amd64' && 'amd64' || 'arm64' }}) strategy: fail-fast: false matrix: @@ -77,6 +78,7 @@ jobs: retention-days: 1 merge: + name: Merge manifest runs-on: ubuntu-latest needs: build permissions: @@ -139,6 +141,7 @@ jobs: create-storage-record: false build-always: + name: Build locale-prefixed (${{ matrix.platform == 'linux/amd64' && 'amd64' || 'arm64' }}) strategy: fail-fast: false matrix: @@ -200,6 +203,7 @@ jobs: retention-days: 1 merge-always: + name: Merge locale-prefixed manifest runs-on: ubuntu-latest needs: build-always permissions: diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 7a42b5809..a7bae41ac 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -1,4 +1,4 @@ -name: Publish Docker Image +name: "Docker: Branch image" on: push: @@ -23,6 +23,7 @@ on: jobs: prepare: + name: Prepare runs-on: ubuntu-latest outputs: image_name: ${{ steps.set.outputs.image_name }} @@ -40,6 +41,7 @@ jobs: fi build: + name: Build (${{ matrix.platform == 'linux/amd64' && 'amd64' || 'arm64' }}) needs: prepare strategy: fail-fast: false @@ -102,6 +104,7 @@ jobs: retention-days: 1 merge: + name: Merge manifest runs-on: ubuntu-latest needs: [prepare, build] permissions: diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 67bab7c2c..040daffc6 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -1,4 +1,4 @@ -name: Integration tests +name: "CI: Integration tests" # Runs the dockerised webmail + Stalwart Playwright suite in integration/ # (see integration/README.md). It takes several minutes, so unlike the vitest @@ -26,7 +26,7 @@ permissions: jobs: playwright: - name: playwright + name: Playwright # On pull requests, run only when the "integration" label is on. A labeled # event for some other label must not start (or cancel) a run. if: >- diff --git a/.github/workflows/standalone-release.yml b/.github/workflows/standalone-release.yml index 7301f2cd5..c3aa5f0c4 100644 --- a/.github/workflows/standalone-release.yml +++ b/.github/workflows/standalone-release.yml @@ -1,4 +1,4 @@ -name: Publish Standalone Tarball on Release +name: "Standalone: Release tarball" # The tarballs build without a write token. The release job, which runs no # checked-out code, publishes each one with a `.sha256` next to it and a @@ -7,6 +7,7 @@ name: Publish Standalone Tarball on Release on: release: + name: Attach to release types: [published] workflow_dispatch: @@ -15,6 +16,7 @@ permissions: jobs: build: + name: Build (${{ matrix.arch }}) strategy: fail-fast: false matrix: @@ -66,6 +68,7 @@ jobs: retention-days: 7 release: + name: Attach to release needs: build if: github.event_name == 'release' runs-on: ubuntu-latest diff --git a/.github/workflows/static-lite.yml b/.github/workflows/static-lite.yml index 9dde0e910..149e12036 100644 --- a/.github/workflows/static-lite.yml +++ b/.github/workflows/static-lite.yml @@ -1,4 +1,4 @@ -name: Build Static Lite +name: "Lite: Static bundle" # Bulwark Lite: the static export of the webmail (see docs in README.md, # "Static Lite build"). Runs the build on every push as a regression check, @@ -18,6 +18,7 @@ name: Build Static Lite on: release: + name: Attach to release types: [published] push: branches: [main] @@ -47,6 +48,7 @@ permissions: jobs: build: + name: Build (${{ matrix.target }}) runs-on: ubuntu-latest timeout-minutes: 30 strategy: @@ -107,6 +109,7 @@ jobs: retention-days: 7 release: + name: Attach to release # The only job with a write token, and it runs no checked-out code. needs: build if: github.event_name == 'release' @@ -140,7 +143,8 @@ jobs: TAG_NAME: ${{ github.event.release.tag_name }} run: gh release upload "$TAG_NAME" zips/*.zip zips/*.zip.sha256 --clobber - smoke: + e2e: + name: E2E (static) # Boots the demo export on a plain static server and drives it with # Playwright: login, open a thread, switch surfaces, reload a deep link. # No JMAP server involved, so it is cheap and deterministic. @@ -163,7 +167,7 @@ jobs: - name: Install Playwright browser run: npx playwright install --with-deps chromium - # prepare.mjs prunes every test tree in the checkout; the smoke suite + # prepare.mjs prunes every test tree in the checkout; the E2E suite # lives under scripts/lite/smoke, which it leaves alone. - name: Build demo export env: @@ -173,18 +177,19 @@ jobs: LITE_LOCALES: "en,de" run: npm run build:lite - - name: Run smoke test + - name: Run E2E test run: npm run test:lite-smoke - name: Upload Playwright report if: failure() uses: actions/upload-artifact@v4 with: - name: lite-smoke-report + name: lite-e2e-report path: playwright-report retention-days: 7 - smoke-stalwart: + e2e-stalwart: + name: E2E (Stalwart) # The Stalwart Application bundle, served by scripts/lite/serve.mjs # --stalwart (an emulation of how Stalwart serves Applications) from the # zip itself, under two prefixes. @@ -216,13 +221,13 @@ jobs: LITE_LOCALES: "en,de" run: npm run build:lite - - name: Run smoke test + - name: Run E2E test run: npm run test:lite-smoke:stalwart - name: Upload Playwright report if: failure() uses: actions/upload-artifact@v4 with: - name: lite-smoke-stalwart-report + name: lite-e2e-stalwart-report path: playwright-report retention-days: 7 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 40b9e5bd8..43a7acac3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,4 +1,4 @@ -name: Tests +name: "CI: Unit tests" on: push: @@ -6,7 +6,7 @@ on: jobs: vitest: - name: vitest + name: Vitest runs-on: ubuntu-latest timeout-minutes: 30 steps: