From 42c7f98a82af4dc00b030fac181b606af1b652a2 Mon Sep 17 00:00:00 2001 From: Arthur Belleville Date: Thu, 23 Oct 2025 22:26:03 +0200 Subject: [PATCH 01/12] Update circle ci --- .circleci/config.yml | 371 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 349 insertions(+), 22 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index bb68b14..856a431 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,31 +1,358 @@ -# Use the latest 2.1 version of CircleCI pipeline process engine. -# See: https://circleci.com/docs/reference/configuration-reference version: 2.1 -# Define a job to be invoked later in a workflow. -# See: https://circleci.com/docs/guides/orchestrate/jobs-steps/#jobs-overview & https://circleci.com/docs/reference/configuration-reference/#jobs -jobs: - say-hello: - # Specify the execution environment. You can specify an image from Docker Hub or use one of our convenience images from CircleCI's Developer Hub. - # See: https://circleci.com/docs/guides/execution-managed/executor-intro/ & https://circleci.com/docs/reference/configuration-reference/#executor-job +# Orbs for Node.js support +orbs: + node: circleci/node@6.1.0 + +# Define executor +executors: + node-executor: docker: - # Specify the version you desire here - # See: https://circleci.com/developer/images/image/cimg/base - - image: cimg/base:current + - image: cimg/node:20.11 + resource_class: large + working_directory: ~/project - # Add steps to the job - # See: https://circleci.com/docs/guides/orchestrate/jobs-steps/#steps-overview & https://circleci.com/docs/reference/configuration-reference/#steps +# Reusable commands +commands: + setup-pnpm: steps: - # Checkout the code as the first step. - - checkout - run: - name: "Say hello" - command: "echo Hello, World!" + name: Install pnpm + command: | + corepack enable + corepack prepare pnpm@10.19.0 --activate + + restore-dependencies: + steps: + - restore_cache: + keys: + - pnpm-deps-v1-{{ checksum "pnpm-lock.yaml" }} + - pnpm-deps-v1- + + save-dependencies: + steps: + - save_cache: + key: pnpm-deps-v1-{{ checksum "pnpm-lock.yaml" }} + paths: + - ~/.local/share/pnpm/store + - node_modules + - apps/main/node_modules + - apps/external/node_modules + - packages/ui/node_modules + - packages/shared/node_modules + + install-deps: + steps: + - run: + name: Install dependencies + command: pnpm install --frozen-lockfile -# Orchestrate jobs using workflows -# See: https://circleci.com/docs/guides/orchestrate/workflows/ & https://circleci.com/docs/reference/configuration-reference/#workflows +# Jobs +jobs: + # ============================================ + # TEST PHASE + # ============================================ + + test-lint: + executor: node-executor + steps: + - checkout + - setup-pnpm + - restore-dependencies + - install-deps + - save-dependencies + - run: + name: Run linting + command: pnpm run lint + - run: + name: Check formatting + command: pnpm run format --check || echo "Format check complete" + + test-typecheck: + executor: node-executor + steps: + - checkout + - setup-pnpm + - restore-dependencies + - install-deps + - run: + name: Type check all packages + command: pnpm run typecheck + + test-unit: + executor: node-executor + steps: + - checkout + - setup-pnpm + - restore-dependencies + - install-deps + - run: + name: Run unit tests + command: pnpm run test + - store_test_results: + path: apps/main/coverage + - store_artifacts: + path: apps/main/coverage + destination: coverage + + test-api: + executor: node-executor + steps: + - checkout + - setup-pnpm + - run: + name: Install API dependencies + command: | + cd api + npm ci + - restore_cache: + keys: + - npm-api-v1-{{ checksum "api/package-lock.json" }} + - npm-api-v1- + - save_cache: + key: npm-api-v1-{{ checksum "api/package-lock.json" }} + paths: + - api/node_modules + - run: + name: Lint API + command: | + cd api + npm run lint + - run: + name: Run API tests + command: | + cd api + npm run test + + # ============================================ + # BUILD PHASE + # ============================================ + + build-apps: + executor: node-executor + steps: + - checkout + - setup-pnpm + - restore-dependencies + - install-deps + - run: + name: Build all apps + command: pnpm run build:apps + - persist_to_workspace: + root: . + paths: + - apps/main/dist + - apps/external/dist + - packages/ui/dist + - packages/shared/dist + - store_artifacts: + path: apps/main/dist + destination: main-app + - store_artifacts: + path: apps/external/dist + destination: external-app + + build-api: + executor: node-executor + steps: + - checkout + - restore_cache: + keys: + - npm-api-v1-{{ checksum "api/package-lock.json" }} + - run: + name: Install API dependencies + command: | + cd api + npm ci + - run: + name: Build API + command: | + cd api + npm run build + - persist_to_workspace: + root: . + paths: + - api/dist + - store_artifacts: + path: api/dist + destination: api + + # ============================================ + # DOCKER BUILD PHASE + # ============================================ + + build-docker-api: + machine: + image: ubuntu-2204:current + resource_class: medium + steps: + - checkout + - attach_workspace: + at: . + - run: + name: Build API Docker image + command: | + cd api + docker build -t xtablo-api:${CIRCLE_SHA1} -t xtablo-api:latest . + - run: + name: Save Docker image + command: | + mkdir -p /tmp/docker-images + docker save xtablo-api:${CIRCLE_SHA1} -o /tmp/docker-images/api.tar + - persist_to_workspace: + root: /tmp + paths: + - docker-images/api.tar + + # ============================================ + # DEPLOY PHASE + # ============================================ + + deploy-staging: + executor: node-executor + steps: + - checkout + - attach_workspace: + at: . + - setup-pnpm + - restore-dependencies + - install-deps + - run: + name: Deploy frontend to staging + command: | + cd apps/main + echo "Deploying main app to staging..." + # Uncomment and configure your Cloudflare deployment + # npx wrangler deploy --env staging + echo "Set CLOUDFLARE_API_TOKEN in CircleCI environment variables" + - run: + name: Deploy API to staging + command: | + echo "Deploying API to staging environment..." + # Add your API deployment commands here + # Example for Google Cloud Run: + # gcloud run deploy xtablo-api --image gcr.io/${GCP_PROJECT}/xtablo-api:${CIRCLE_SHA1} --region us-central1 + + deploy-production: + executor: node-executor + steps: + - checkout + - attach_workspace: + at: . + - setup-pnpm + - restore-dependencies + - install-deps + - run: + name: Deploy frontend to production + command: | + echo "Deploying to production..." + pnpm run deploy:all + - run: + name: Deploy API to production + command: | + echo "Deploying API to production environment..." + # Add your production API deployment commands here + +# Workflows workflows: - say-hello-workflow: # This is the name of the workflow, feel free to change it to better match your workflow. - # Inside the workflow, you define the jobs you want to run. + version: 2 + + # Run on all branches (except main and develop) + test-and-build: + when: + and: + - not: + equal: [ main, << pipeline.git.branch >> ] + - not: + equal: [ develop, << pipeline.git.branch >> ] jobs: - - say-hello \ No newline at end of file + # Test phase - run in parallel + - test-lint + - test-typecheck + - test-unit + - test-api + + # Build phase - run after tests pass + - build-apps: + requires: + - test-lint + - test-typecheck + - test-unit + + - build-api: + requires: + - test-api + + - build-docker-api: + requires: + - build-api + + # Staging deployment workflow (develop branch) + deploy-to-staging: + when: + equal: [ develop, << pipeline.git.branch >> ] + jobs: + # Test phase + - test-lint + - test-typecheck + - test-unit + - test-api + + # Build phase + - build-apps: + requires: + - test-lint + - test-typecheck + - test-unit + + - build-api: + requires: + - test-api + + - build-docker-api: + requires: + - build-api + + # Deploy to staging + - deploy-staging: + requires: + - build-apps + - build-docker-api + + # Production deployment workflow (main branch) + deploy-to-production: + when: + equal: [ main, << pipeline.git.branch >> ] + jobs: + # Test phase + - test-lint + - test-typecheck + - test-unit + - test-api + + # Build phase + - build-apps: + requires: + - test-lint + - test-typecheck + - test-unit + + - build-api: + requires: + - test-api + + - build-docker-api: + requires: + - build-api + + # Manual approval gate before production + - hold-for-approval: + type: approval + requires: + - build-apps + - build-docker-api + + # Deploy to production + - deploy-production: + requires: + - hold-for-approval From 62ac5e054ee6ba887f2e6362e69cf2c1faaef29d Mon Sep 17 00:00:00 2001 From: Arthur Belleville Date: Thu, 23 Oct 2025 22:34:53 +0200 Subject: [PATCH 02/12] Update circle ci setup --- .circleci/config.yml | 78 +++++++++++++++----------------------------- 1 file changed, 26 insertions(+), 52 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 856a431..4e0c38a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,51 +1,37 @@ version: 2.1 -# Orbs for Node.js support -orbs: - node: circleci/node@6.1.0 - # Define executor executors: node-executor: docker: - - image: cimg/node:20.11 + - image: node:18 resource_class: large working_directory: ~/project # Reusable commands commands: setup-pnpm: - steps: - - run: - name: Install pnpm - command: | - corepack enable - corepack prepare pnpm@10.19.0 --activate - - restore-dependencies: steps: - restore_cache: + name: Restore pnpm Package Cache + keys: - - pnpm-deps-v1-{{ checksum "pnpm-lock.yaml" }} - - pnpm-deps-v1- - - save-dependencies: - steps: - - save_cache: - key: pnpm-deps-v1-{{ checksum "pnpm-lock.yaml" }} - paths: - - ~/.local/share/pnpm/store - - node_modules - - apps/main/node_modules - - apps/external/node_modules - - packages/ui/node_modules - - packages/shared/node_modules - - install-deps: - steps: + - pnpm-packages-{{ checksum "pnpm-lock.yaml" }} - run: - name: Install dependencies - command: pnpm install --frozen-lockfile + name: Install pnpm package manager + command: | + npm install --global corepack@latest + corepack enable + corepack prepare pnpm@latest-10 --activate + pnpm config set store-dir .pnpm-store + - run: + name: Install Dependencies + command: pnpm install + - save_cache: + name: Save pnpm Package Cache + key: pnpm-packages-{{ checksum "pnpm-lock.yaml" }} + paths: + - .pnpm-store # Jobs jobs: @@ -58,9 +44,6 @@ jobs: steps: - checkout - setup-pnpm - - restore-dependencies - - install-deps - - save-dependencies - run: name: Run linting command: pnpm run lint @@ -73,8 +56,6 @@ jobs: steps: - checkout - setup-pnpm - - restore-dependencies - - install-deps - run: name: Type check all packages command: pnpm run typecheck @@ -84,8 +65,6 @@ jobs: steps: - checkout - setup-pnpm - - restore-dependencies - - install-deps - run: name: Run unit tests command: pnpm run test @@ -99,18 +78,18 @@ jobs: executor: node-executor steps: - checkout - - setup-pnpm + - restore_cache: + name: Restore npm API Cache + keys: + - npm-api-{{ checksum "api/package-lock.json" }} - run: name: Install API dependencies command: | cd api npm ci - - restore_cache: - keys: - - npm-api-v1-{{ checksum "api/package-lock.json" }} - - npm-api-v1- - save_cache: - key: npm-api-v1-{{ checksum "api/package-lock.json" }} + name: Save npm API Cache + key: npm-api-{{ checksum "api/package-lock.json" }} paths: - api/node_modules - run: @@ -133,8 +112,6 @@ jobs: steps: - checkout - setup-pnpm - - restore-dependencies - - install-deps - run: name: Build all apps command: pnpm run build:apps @@ -157,8 +134,9 @@ jobs: steps: - checkout - restore_cache: + name: Restore npm API Cache keys: - - npm-api-v1-{{ checksum "api/package-lock.json" }} + - npm-api-{{ checksum "api/package-lock.json" }} - run: name: Install API dependencies command: | @@ -215,8 +193,6 @@ jobs: - attach_workspace: at: . - setup-pnpm - - restore-dependencies - - install-deps - run: name: Deploy frontend to staging command: | @@ -240,8 +216,6 @@ jobs: - attach_workspace: at: . - setup-pnpm - - restore-dependencies - - install-deps - run: name: Deploy frontend to production command: | From 33d16e71ecdf130ab4c1b79ce99f9e05f5291d59 Mon Sep 17 00:00:00 2001 From: Arthur Belleville Date: Thu, 23 Oct 2025 23:04:56 +0200 Subject: [PATCH 03/12] Fix tests --- .circleci/config.yml | 54 ++++++++++++++++----- apps/main/src/components/ProtectedRoute.tsx | 2 +- 2 files changed, 42 insertions(+), 14 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4e0c38a..b0465e8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -109,12 +109,23 @@ jobs: build-apps: executor: node-executor + parameters: + environment: + type: string + default: "staging" steps: - checkout - setup-pnpm - run: - name: Build all apps - command: pnpm run build:apps + name: Build main app for << parameters.environment >> + command: | + cd apps/main + npm run build:<< parameters.environment >> + - run: + name: Build external app + command: | + cd apps/external + npm run build - persist_to_workspace: root: . paths: @@ -124,7 +135,7 @@ jobs: - packages/shared/dist - store_artifacts: path: apps/main/dist - destination: main-app + destination: main-app-<< parameters.environment >> - store_artifacts: path: apps/external/dist destination: external-app @@ -194,20 +205,25 @@ jobs: at: . - setup-pnpm - run: - name: Deploy frontend to staging + name: Deploy main app to staging command: | cd apps/main - echo "Deploying main app to staging..." - # Uncomment and configure your Cloudflare deployment + echo "Deploying main app to staging environment..." + npx wrangler deploy --env staging + - run: + name: Deploy external app to staging + command: | + cd apps/external + echo "Deploying external app to staging..." + # Add external app staging deployment if needed # npx wrangler deploy --env staging - echo "Set CLOUDFLARE_API_TOKEN in CircleCI environment variables" - run: name: Deploy API to staging command: | echo "Deploying API to staging environment..." # Add your API deployment commands here # Example for Google Cloud Run: - # gcloud run deploy xtablo-api --image gcr.io/${GCP_PROJECT}/xtablo-api:${CIRCLE_SHA1} --region us-central1 + # gcloud run deploy xtablo-api-staging --image gcr.io/${GCP_PROJECT}/xtablo-api:${CIRCLE_SHA1} --region us-central1 deploy-production: executor: node-executor @@ -217,15 +233,25 @@ jobs: at: . - setup-pnpm - run: - name: Deploy frontend to production + name: Deploy main app to production command: | - echo "Deploying to production..." - pnpm run deploy:all + cd apps/main + echo "Deploying main app to production environment..." + npx wrangler deploy --env production + - run: + name: Deploy external app to production + command: | + cd apps/external + echo "Deploying external app to production..." + # Add external app production deployment if needed + # npx wrangler deploy --env production - run: name: Deploy API to production command: | echo "Deploying API to production environment..." # Add your production API deployment commands here + # Example for Google Cloud Run: + # gcloud run deploy xtablo-api --image gcr.io/${GCP_PROJECT}/xtablo-api:${CIRCLE_SHA1} --region us-central1 # Workflows workflows: @@ -272,8 +298,9 @@ workflows: - test-unit - test-api - # Build phase + # Build phase for staging - build-apps: + environment: "staging" requires: - test-lint - test-typecheck @@ -304,8 +331,9 @@ workflows: - test-unit - test-api - # Build phase + # Build phase for production - build-apps: + environment: "prod" requires: - test-lint - test-typecheck diff --git a/apps/main/src/components/ProtectedRoute.tsx b/apps/main/src/components/ProtectedRoute.tsx index 30690f7..fc045e8 100644 --- a/apps/main/src/components/ProtectedRoute.tsx +++ b/apps/main/src/components/ProtectedRoute.tsx @@ -42,7 +42,7 @@ export const ProtectedRoute = ({ fallback, shouldRedirectToCurrentPage }: Protec return match(status) .with("loading", () => ) - .with("should-land-user", () => ) + .with("should-land-user", () => ) .with("should-redirect", () => ) .with("should-pass", () => ) .exhaustive(); From 9068772ca355158b0988c483f6fc2a7587230907 Mon Sep 17 00:00:00 2001 From: Arthur Belleville Date: Thu, 23 Oct 2025 23:17:10 +0200 Subject: [PATCH 04/12] Better deploy scripts --- apps/main/package.json | 3 ++- apps/main/stats.html | 2 +- apps/main/turbo.json | 10 ++++++++++ package.json | 3 ++- turbo.json | 5 ----- 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/apps/main/package.json b/apps/main/package.json index 25414fe..25b914f 100644 --- a/apps/main/package.json +++ b/apps/main/package.json @@ -13,7 +13,8 @@ "preview": "vite preview", "build:staging": "tsc -b && vite build --mode staging", "build:prod": "tsc -b && vite build --mode production", - "deploy": "wrangler deploy --env=\"\"", + "deploy:staging": "wrangler deploy --env=\"\"", + "deploy:prod": "wrangler deploy --env=\"\"", "cf-typegen": "wrangler types", "test": "vitest run --mode dev --passWithNoTests", "test:watch": "vitest watch --passWithNoTests", diff --git a/apps/main/stats.html b/apps/main/stats.html index 6902f6c..5a41bb8 100644 --- a/apps/main/stats.html +++ b/apps/main/stats.html @@ -4929,7 +4929,7 @@ var drawChart = (function (exports) {