test: lock calendar, audit, and time HTTP tenancy #692
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] | |
| concurrency: | |
| group: ci-${{ github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| packages: write | |
| jobs: | |
| test-and-build: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: "24" | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Lint | |
| run: npm run lint | |
| - name: Typecheck | |
| run: npm run typecheck | |
| - name: Unit tests | |
| run: npm run test:unit | |
| - name: Build | |
| env: | |
| AUTH_SECRET: ci-build-secret-not-for-production | |
| NEXT_PUBLIC_OFFICER_HUB_PUBLIC: "true" | |
| NEXT_PUBLIC_DEMO_SITE: "true" | |
| # Optional — readable Sentry stack traces when the org secret is set. | |
| SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} | |
| SENTRY_ORG: union-ops | |
| SENTRY_PROJECT: javascript-nextjs | |
| run: npm run build | |
| - name: Install Playwright browsers | |
| run: | | |
| # ubuntu-latest ships Microsoft apt feeds that can break `apt update` (NOSPLIT / unsigned). | |
| sudo rm -f /etc/apt/sources.list.d/microsoft*.list \ | |
| /etc/apt/sources.list.d/microsoft*.sources \ | |
| /etc/apt/sources.list.d/azure-cli* 2>/dev/null || true | |
| npx playwright install chromium --with-deps | |
| - name: E2E smoke | |
| env: | |
| CI: "true" | |
| AUTH_SECRET: ci-build-secret-not-for-production | |
| # Production `next start` disables the demo roster unless opted in | |
| # (isDemoAuthEnabled). Without this, hub/portal @smoke spins on | |
| # CredentialsSignin until the job is cancelled. | |
| AUTH_ALLOW_DEMO_USERS: "true" | |
| NEXT_PUBLIC_DEMO_SITE: "true" | |
| NEXT_PUBLIC_OFFICER_HUB_PUBLIC: "true" | |
| run: npm run test:smoke | |
| - name: Dependency audit | |
| run: npm audit --audit-level=high | |
| continue-on-error: true | |
| # Docker build + GHCR publish run independently of E2E so CapRover can pull a | |
| # pre-built image instead of rebuilding on a small droplet (BuildKit export failures). | |
| docker-image: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Docker build smoke | |
| env: | |
| SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} | |
| NEXT_PUBLIC_SENTRY_DSN: ${{ secrets.NEXT_PUBLIC_SENTRY_DSN }} | |
| run: | | |
| EXTRA_ARGS="" | |
| if [ -n "$SENTRY_AUTH_TOKEN" ]; then | |
| EXTRA_ARGS="$EXTRA_ARGS --build-arg SENTRY_AUTH_TOKEN=$SENTRY_AUTH_TOKEN --build-arg SENTRY_ORG=union-ops --build-arg SENTRY_PROJECT=javascript-nextjs" | |
| fi | |
| if [ -n "$NEXT_PUBLIC_SENTRY_DSN" ]; then | |
| EXTRA_ARGS="$EXTRA_ARGS --build-arg NEXT_PUBLIC_SENTRY_DSN=$NEXT_PUBLIC_SENTRY_DSN" | |
| fi | |
| # shellcheck disable=SC2086 | |
| docker build -f docker/Dockerfile -t union-communications:ci \ | |
| --build-arg AUTH_SECRET=build-time-placeholder-not-used-at-runtime \ | |
| --build-arg CAPROVER_GIT_COMMIT_SHA=${{ github.sha }} \ | |
| --build-arg NEXT_PUBLIC_OFFICER_HUB_PUBLIC=true \ | |
| --build-arg NEXT_PUBLIC_DEMO_SITE=true \ | |
| $EXTRA_ARGS \ | |
| . | |
| - name: Docker migrate smoke | |
| run: bash scripts/docker-migrate-smoke.sh union-communications:ci | |
| - name: Log in to GHCR | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Push demo / workshop image | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| run: | | |
| IMAGE="ghcr.io/${{ github.repository }}" | |
| docker tag union-communications:ci "${IMAGE}:main" | |
| docker tag union-communications:ci "${IMAGE}:sha-${GITHUB_SHA::7}" | |
| docker push "${IMAGE}:main" | |
| docker push "${IMAGE}:sha-${GITHUB_SHA::7}" | |
| - name: Build and push production hardened image | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| file: docker/Dockerfile | |
| push: true | |
| tags: ghcr.io/${{ github.repository }}:production | |
| build-args: | | |
| AUTH_SECRET=build-time-placeholder-not-used-at-runtime | |
| CAPROVER_GIT_COMMIT_SHA=${{ github.sha }} | |
| NEXT_PUBLIC_OFFICER_HUB_PUBLIC=true | |
| NEXT_PUBLIC_DEMO_SITE=false | |
| SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} | |
| SENTRY_ORG=union-ops | |
| SENTRY_PROJECT=javascript-nextjs | |
| NEXT_PUBLIC_SENTRY_DSN=${{ secrets.NEXT_PUBLIC_SENTRY_DSN }} | |
| deploy: | |
| needs: docker-image | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Deploy pre-built GHCR image to CapRover | |
| env: | |
| CAPROVER_SERVER: ${{ secrets.CAPROVER_SERVER }} | |
| CAPROVER_PASSWORD: ${{ secrets.CAPROVER_PASSWORD }} | |
| CAPROVER_APP: ${{ secrets.CAPROVER_APP }} | |
| CAPROVER_WEBHOOK_URL: ${{ secrets.CAPROVER_WEBHOOK_URL }} | |
| IMAGE: ghcr.io/${{ github.repository }}:main | |
| run: | | |
| if [ -n "$CAPROVER_SERVER" ] && [ -n "$CAPROVER_PASSWORD" ] && [ -n "$CAPROVER_APP" ]; then | |
| echo "Deploying ${IMAGE} to CapRover app ${CAPROVER_APP} (pull only — no on-host build)." | |
| docker run --rm caprover/caprover-cli:2.2.3 caprover deploy \ | |
| --caproverUrl "$CAPROVER_SERVER" \ | |
| --caproverPassword "$CAPROVER_PASSWORD" \ | |
| --caproverApp "$CAPROVER_APP" \ | |
| --imageName "$IMAGE" | |
| echo "CapRover image deploy triggered." | |
| exit 0 | |
| fi | |
| if [ -n "$CAPROVER_WEBHOOK_URL" ]; then | |
| echo "::warning::CAPROVER_SERVER/PASSWORD/APP not set — falling back to git webhook (rebuilds on CapRover; may fail on small hosts)." | |
| curl -fsS -X POST "$CAPROVER_WEBHOOK_URL" | |
| echo "CapRover git build webhook triggered." | |
| exit 0 | |
| fi | |
| echo "::warning::No CapRover deploy secrets — skipping deploy. Set CAPROVER_SERVER, CAPROVER_PASSWORD, CAPROVER_APP for image deploy." |