name: CI — NoteLett on: push: branches: [main] pull_request: branches: [main] concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: release-guards: name: Release guards — secrets + token/color drift runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Checkout common-plat guard scripts uses: actions/checkout@v4 with: repository: saravanakumardb1/learning_ai_common_plat path: learning_ai_common_plat token: ${{ secrets.GH_PAT }} - name: Link common-platform workspace path run: | ln -sfn "$GITHUB_WORKSPACE/learning_ai_common_plat" ../learning_ai_common_plat - name: Install audit tools run: sudo apt-get update && sudo apt-get install -y ripgrep - name: Run release guard audit run: COMMON_PLAT="$GITHUB_WORKSPACE/learning_ai_common_plat" bash scripts/release-guard-audit.sh - name: Run UI drift ratchet (one-way gate vs scripts/ui-drift-baseline.json) run: bash scripts/ui-drift-ratchet.sh - name: Run UI drift audit (report mode, informational) run: bash scripts/ui-drift-audit.sh || true backend: name: Backend — typecheck + test + build runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Checkout common-plat (for @bytelyst/* packages) uses: actions/checkout@v4 with: repository: saravanakumardb1/learning_ai_common_plat path: learning_ai_common_plat token: ${{ secrets.GH_PAT }} - name: Link common-platform workspace path run: | ln -sfn "$GITHUB_WORKSPACE/learning_ai_common_plat" ../learning_ai_common_plat - uses: actions/setup-node@v4 with: node-version: 22 cache: pnpm cache-dependency-path: pnpm-lock.yaml - name: Enable pnpm run: corepack enable - name: Build @bytelyst/* packages working-directory: learning_ai_common_plat run: | pnpm install --frozen-lockfile pnpm build - name: Install workspace dependencies run: pnpm install --frozen-lockfile - name: Backend lint run: pnpm --filter @notelett/backend run lint - name: Backend typecheck run: pnpm --filter @notelett/backend run typecheck - name: Backend tests run: pnpm --filter @notelett/backend run test env: DB_PROVIDER: memory JWT_SECRET: ci-test-secret-at-least-32-characters-long - name: Backend build run: pnpm --filter @notelett/backend run build backend-cosmos: # Cosmos-emulator smoke — exercises partition-key paths that the # in-memory provider cannot detect. Runs only the *.cosmos.test.ts # suite via vitest.cosmos.config.ts. See backend/src/cosmos.smoke.cosmos.test.ts # for the contract. name: Backend — Cosmos emulator smoke (partition keys) runs-on: ubuntu-latest needs: backend services: cosmos: image: mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:latest ports: - 8081:8081 - 10251:10251 - 10252:10252 - 10253:10253 - 10254:10254 env: AZURE_COSMOS_EMULATOR_PARTITION_COUNT: 4 AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE: false options: >- --memory 3g steps: - uses: actions/checkout@v4 - name: Checkout common-plat (for @bytelyst/* packages) uses: actions/checkout@v4 with: repository: saravanakumardb1/learning_ai_common_plat path: learning_ai_common_plat token: ${{ secrets.GH_PAT }} - name: Link common-platform workspace path run: | ln -sfn "$GITHUB_WORKSPACE/learning_ai_common_plat" ../learning_ai_common_plat - uses: actions/setup-node@v4 with: node-version: 22 cache: pnpm cache-dependency-path: pnpm-lock.yaml - name: Enable pnpm run: corepack enable - name: Build @bytelyst/* packages working-directory: learning_ai_common_plat run: | pnpm install --frozen-lockfile pnpm build - name: Install workspace dependencies run: pnpm install --frozen-lockfile - name: Wait for Cosmos emulator to be ready run: | for i in {1..60}; do if curl -ks --max-time 5 https://localhost:8081/_explorer/emulator.pem >/dev/null 2>&1; then echo "Cosmos emulator is ready (after ${i}s)" exit 0 fi echo "Waiting for Cosmos emulator... ($i/60)" sleep 5 done echo "Cosmos emulator failed to become ready in 5 minutes" >&2 exit 1 - name: Run Cosmos smoke suite run: pnpm --filter @notelett/backend run test:cosmos env: DB_PROVIDER: cosmos COSMOS_ENDPOINT: https://localhost:8081 # Well-known emulator dev key. NOT a secret. # https://learn.microsoft.com/en-us/azure/cosmos-db/local-emulator COSMOS_KEY: C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw== COSMOS_DATABASE: notelett_test NODE_TLS_REJECT_UNAUTHORIZED: 0 JWT_SECRET: ci-test-secret-at-least-32-characters-long web: name: Web — typecheck + test + build runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Checkout common-plat (for @bytelyst/* packages) uses: actions/checkout@v4 with: repository: saravanakumardb1/learning_ai_common_plat path: learning_ai_common_plat token: ${{ secrets.GH_PAT }} - name: Link common-platform workspace path run: | ln -sfn "$GITHUB_WORKSPACE/learning_ai_common_plat" ../learning_ai_common_plat - uses: actions/setup-node@v4 with: node-version: 22 cache: pnpm cache-dependency-path: pnpm-lock.yaml - name: Enable pnpm run: corepack enable - name: Build @bytelyst/* packages working-directory: learning_ai_common_plat run: | pnpm install --frozen-lockfile pnpm build - name: Install workspace dependencies run: pnpm install --frozen-lockfile - name: Web lint run: pnpm --filter @notelett/web run lint - name: Web typecheck run: pnpm --filter @notelett/web run typecheck - name: Web tests run: pnpm --filter @notelett/web run test - name: Web build run: pnpm --filter @notelett/web run build web-e2e: name: Web E2E — Playwright runs-on: ubuntu-latest needs: web steps: - uses: actions/checkout@v4 - name: Checkout common-plat (for @bytelyst/* packages) uses: actions/checkout@v4 with: repository: saravanakumardb1/learning_ai_common_plat path: learning_ai_common_plat token: ${{ secrets.GH_PAT }} - name: Link common-platform workspace path run: | ln -sfn "$GITHUB_WORKSPACE/learning_ai_common_plat" ../learning_ai_common_plat - uses: actions/setup-node@v4 with: node-version: 22 cache: pnpm cache-dependency-path: pnpm-lock.yaml - name: Enable pnpm run: corepack enable - name: Build @bytelyst/* packages working-directory: learning_ai_common_plat run: | pnpm install --frozen-lockfile pnpm build - name: Install workspace dependencies run: pnpm install --frozen-lockfile - name: Cache Playwright browsers uses: actions/cache@v4 with: path: ~/.cache/ms-playwright key: ${{ runner.os }}-playwright-${{ hashFiles('pnpm-lock.yaml') }} restore-keys: | ${{ runner.os }}-playwright- - name: Install Playwright Chromium run: pnpm --filter @notelett/web exec playwright install --with-deps chromium - name: Web Playwright E2E run: pnpm --filter @notelett/web run test:e2e -- --reporter=list - name: Upload Playwright report if: always() uses: actions/upload-artifact@v4 with: name: web-playwright-report path: | web/playwright-report web/test-results if-no-files-found: ignore docker-build: name: Docker — backend + web images runs-on: ubuntu-latest needs: [backend, web] steps: - uses: actions/checkout@v4 - name: Checkout common-plat (for @bytelyst/* packages) uses: actions/checkout@v4 with: repository: saravanakumardb1/learning_ai_common_plat path: learning_ai_common_plat token: ${{ secrets.GH_PAT }} - name: Link common-platform workspace path run: | ln -sfn "$GITHUB_WORKSPACE/learning_ai_common_plat" ../learning_ai_common_plat - uses: actions/setup-node@v4 with: node-version: 22 cache: pnpm cache-dependency-path: pnpm-lock.yaml - name: Enable pnpm run: corepack enable - name: Install common-platform dependencies working-directory: learning_ai_common_plat run: pnpm install --frozen-lockfile - name: Prepare Docker tarball dependencies run: COMMON_PLAT="$GITHUB_WORKSPACE/learning_ai_common_plat" bash scripts/docker-prep.sh - name: Build backend image env: GITEA_NPM_TOKEN: ${{ secrets.GITEA_NPM_TOKEN }} run: | printf '%s' "${GITEA_NPM_TOKEN:-}" > /tmp/gitea_npm_token DOCKER_BUILDKIT=1 docker build \ --secret id=gitea_npm_token,src=/tmp/gitea_npm_token \ -f backend/Dockerfile \ -t notelett-backend:ci \ . - name: Build web image env: GITEA_NPM_TOKEN: ${{ secrets.GITEA_NPM_TOKEN }} run: | printf '%s' "${GITEA_NPM_TOKEN:-}" > /tmp/gitea_npm_token DOCKER_BUILDKIT=1 docker build \ --secret id=gitea_npm_token,src=/tmp/gitea_npm_token \ --build-arg NEXT_PUBLIC_NOTES_API_URL=http://localhost:4016/api \ --build-arg NEXT_PUBLIC_PLATFORM_SERVICE_URL=http://localhost:4003/api \ -f web/Dockerfile \ -t notelett-web:ci \ . - name: Restore Docker prep changes if: always() run: bash scripts/docker-prep.sh --restore mobile: name: Mobile — lint + typecheck + test runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Checkout common-plat (for @bytelyst/* packages) uses: actions/checkout@v4 with: repository: saravanakumardb1/learning_ai_common_plat path: learning_ai_common_plat token: ${{ secrets.GH_PAT }} - name: Link common-platform workspace path run: | ln -sfn "$GITHUB_WORKSPACE/learning_ai_common_plat" ../learning_ai_common_plat - uses: actions/setup-node@v4 with: node-version: 22 cache: pnpm cache-dependency-path: pnpm-lock.yaml - name: Enable pnpm run: corepack enable - name: Build @bytelyst/* packages working-directory: learning_ai_common_plat run: | pnpm install --frozen-lockfile pnpm build - name: Install workspace dependencies run: pnpm install --frozen-lockfile - name: Mobile lint run: pnpm --filter @notelett/mobile run lint - name: Mobile typecheck run: pnpm --filter @notelett/mobile run typecheck - name: Mobile tests run: pnpm --filter @notelett/mobile run test