brand: roll the new CloudBank logo into the app, favicon and README #269
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| pull_request: | |
| push: | |
| branches: [main] | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ci-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| server: | |
| name: Server (Go) | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| working-directory: server | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-go@v5 | |
| id: setup-go | |
| with: | |
| go-version-file: server/go.mod | |
| cache-dependency-path: server/go.sum | |
| - name: Verify formatting | |
| run: | | |
| unformatted=$(gofmt -l .) | |
| if [ -n "$unformatted" ]; then | |
| echo "These files need gofmt:"; echo "$unformatted"; exit 1 | |
| fi | |
| - name: Embedded OpenAPI spec is in sync | |
| run: diff -u ../api/openapi.yaml internal/httpapi/openapi.yaml | |
| - name: Vet | |
| run: go vet ./... | |
| - name: Cache golangci-lint binary | |
| uses: actions/cache@v4 | |
| with: | |
| # Cache the from-source build below. The key pins both the linter | |
| # version and the Go toolchain it was built with, so bumping either | |
| # rebuilds it. | |
| path: ~/go/bin/golangci-lint | |
| key: golangci-lint-${{ runner.os }}-v2.1.6-go${{ steps.setup-go.outputs.go-version }} | |
| - name: golangci-lint | |
| # Build golangci-lint from source with the project's Go toolchain so its | |
| # build-time Go version always matches the module's target (prebuilt | |
| # binaries lag behind new Go releases and refuse newer module targets). | |
| # The binary is cached above, so this only rebuilds when the key changes. | |
| run: | | |
| bin="$(go env GOPATH)/bin/golangci-lint" | |
| if [ ! -x "$bin" ]; then | |
| go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.1.6 | |
| fi | |
| "$bin" run ./... | |
| - name: Test | |
| run: go test ./... -race -count=1 | |
| - name: Build | |
| run: CGO_ENABLED=0 go build ./... | |
| web: | |
| name: Web (React) | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| working-directory: web | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| cache: npm | |
| cache-dependency-path: web/package-lock.json | |
| - run: npm ci | |
| - name: Generate API types | |
| run: npm run gen:api | |
| - name: Check generated API types are up to date | |
| run: git diff --exit-code src/api/schema.d.ts | |
| - name: Lint (eslint + prettier) | |
| run: npm run lint | |
| - name: i18n key parity | |
| run: npm run check:i18n | |
| - name: Typecheck + build | |
| run: npm run build | |
| - name: Test | |
| run: npm run test | |
| docker: | |
| name: Docker (smoke build) | |
| runs-on: ubuntu-latest | |
| # Only on PRs: verify the image builds (single arch, no push). | |
| if: github.event_name == 'pull_request' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: docker/setup-buildx-action@v3 | |
| - name: Build image (no push) | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| push: false | |
| load: true | |
| tags: cloudbank:ci | |
| build-args: | | |
| VERSION=ci | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| - name: Smoke test the container | |
| run: | | |
| docker run -d --name cb -p 8080:8080 -e CB_SECURE_COOKIES=false cloudbank:ci | |
| for i in $(seq 1 30); do | |
| if curl -fsS http://localhost:8080/healthz; then ok=1; break; fi | |
| sleep 1 | |
| done | |
| docker logs cb | |
| docker rm -f cb | |
| test -n "$ok" | |
| e2e: | |
| name: E2E (Playwright) | |
| runs-on: ubuntu-latest | |
| # Build the real image, run it via compose, and drive it with Playwright. | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| cache: npm | |
| cache-dependency-path: e2e/package-lock.json | |
| - name: Build and start the app via compose | |
| run: docker compose -f e2e/docker-compose.ci.yml up -d --build | |
| - name: Wait for the app to be healthy | |
| run: | | |
| for i in $(seq 1 60); do | |
| if curl -fsS http://localhost:8080/healthz; then ok=1; break; fi | |
| sleep 2 | |
| done | |
| test -n "$ok" | |
| - name: Install e2e dependencies | |
| working-directory: e2e | |
| run: npm ci | |
| - name: Cache Playwright browsers | |
| id: playwright-cache | |
| uses: actions/cache@v4 | |
| with: | |
| # Keyed on the e2e lockfile so a @playwright/test bump re-downloads the | |
| # matching browser; unchanged deps reuse the cached Chromium. | |
| path: ~/.cache/ms-playwright | |
| key: playwright-${{ runner.os }}-${{ hashFiles('e2e/package-lock.json') }} | |
| - name: Install Playwright browser | |
| working-directory: e2e | |
| # On a cache hit only the OS libraries need (re)installing (they are | |
| # system packages, not part of the cached browser); otherwise download | |
| # the browser too. | |
| run: | | |
| if [ "${{ steps.playwright-cache.outputs.cache-hit }}" = "true" ]; then | |
| npx playwright install-deps chromium | |
| else | |
| npx playwright install --with-deps chromium | |
| fi | |
| - name: Run the e2e suite | |
| working-directory: e2e | |
| run: npm test | |
| env: | |
| E2E_BASE_URL: http://localhost:8080 | |
| - name: Container logs on failure | |
| if: failure() | |
| run: docker compose -f e2e/docker-compose.ci.yml logs | |
| - name: Upload Playwright traces and screenshots | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: playwright-artifacts | |
| path: | | |
| e2e/test-results/ | |
| e2e/playwright-report/ | |
| retention-days: 7 |