Skip to content

brand: roll the new CloudBank logo into the app, favicon and README #269

brand: roll the new CloudBank logo into the app, favicon and README

brand: roll the new CloudBank logo into the app, favicon and README #269

Workflow file for this run

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