From 48a9aa1a4adf25668518db6eec0119fd91aebb7c Mon Sep 17 00:00:00 2001 From: Tahmid Ahmed Date: Thu, 15 Jan 2026 20:07:35 -0500 Subject: [PATCH 01/10] 641: wip --- .../test/backend-pre-test/action.yml | 20 ++- .github/scripts/package.json | 16 ++ .github/scripts/pnpm-lock.yaml | 155 ++++++++++++++++++ .github/scripts/run-backend-compile-tests.sh | 13 -- .github/scripts/run-backend-compile-tests.ts | 21 +++ .github/scripts/tsconfig.json | 23 +++ 6 files changed, 234 insertions(+), 14 deletions(-) create mode 100644 .github/scripts/package.json create mode 100644 .github/scripts/pnpm-lock.yaml delete mode 100644 .github/scripts/run-backend-compile-tests.sh create mode 100644 .github/scripts/run-backend-compile-tests.ts create mode 100644 .github/scripts/tsconfig.json diff --git a/.github/composite/test/backend-pre-test/action.yml b/.github/composite/test/backend-pre-test/action.yml index e58004745..899af3cbb 100644 --- a/.github/composite/test/backend-pre-test/action.yml +++ b/.github/composite/test/backend-pre-test/action.yml @@ -20,6 +20,24 @@ runs: javac -version echo "JAVA_HOME=$JAVA_HOME" + - uses: pnpm/action-setup@v3 + with: + version: 10 + + - uses: actions/setup-node@v4 + with: + node-version: 20 + cache: "pnpm" + cache-dependency-path: ".github/scripts/pnpm-lock.yaml" + + - uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Install deps + shell: bash + run: pnpm --dir .github/scripts install --frozen-lockfile + - name: Run script shell: bash - run: bash .github/scripts/run-backend-compile-tests.sh + run: bun .github/scripts/run-backend-compile-tests.ts diff --git a/.github/scripts/package.json b/.github/scripts/package.json new file mode 100644 index 000000000..ac73670cd --- /dev/null +++ b/.github/scripts/package.json @@ -0,0 +1,16 @@ +{ + "name": "scripts", + "version": "1.0.0", + "description": "CodeBloom CI Scripts", + "scripts": {}, + "keywords": [], + "author": "Tahmid Ahmed", + "license": "MIT", + "packageManager": "pnpm@10.24.0", + "dependencies": { + "bun": "^1.3.6" + }, + "devDependencies": { + "@types/bun": "^1.3.6" + } +} diff --git a/.github/scripts/pnpm-lock.yaml b/.github/scripts/pnpm-lock.yaml new file mode 100644 index 000000000..046bcf34a --- /dev/null +++ b/.github/scripts/pnpm-lock.yaml @@ -0,0 +1,155 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + bun: + specifier: ^1.3.6 + version: 1.3.6 + devDependencies: + '@types/bun': + specifier: ^1.3.6 + version: 1.3.6 + +packages: + + '@oven/bun-darwin-aarch64@1.3.6': + resolution: {integrity: sha512-27rypIapNkYboOSylkf1tD9UW9Ado2I+P1NBL46Qz29KmOjTL6WuJ7mHDC5O66CYxlOkF5r93NPDAC3lFHYBXw==} + cpu: [arm64] + os: [darwin] + + '@oven/bun-darwin-x64-baseline@1.3.6': + resolution: {integrity: sha512-nqtr+pTsHqusYpG2OZc6s+AmpWDB/FmBvstrK0y5zkti4OqnCuu7Ev2xNjS7uyb47NrAFF40pWqkpaio5XEd7w==} + cpu: [x64] + os: [darwin] + + '@oven/bun-darwin-x64@1.3.6': + resolution: {integrity: sha512-I82xGzPkBxzBKgbl8DsA0RfMQCWTWjNmLjIEkW1ECiv3qK02kHGQ5FGUr/29L/SuvnGsULW4tBTRNZiMzL37nA==} + cpu: [x64] + os: [darwin] + + '@oven/bun-linux-aarch64-musl@1.3.6': + resolution: {integrity: sha512-FR+iJt17rfFgYgpxL3M67AUwujOgjw52ZJzB9vElI5jQXNjTyOKf8eH4meSk4vjlYF3h/AjKYd6pmN0OIUlVKQ==} + cpu: [arm64] + os: [linux] + + '@oven/bun-linux-aarch64@1.3.6': + resolution: {integrity: sha512-YaQEAYjBanoOOtpqk/c5GGcfZIyxIIkQ2m1TbHjedRmJNwxzWBhGinSARFkrRIc3F8pRIGAopXKvJ/2rjN1LzQ==} + cpu: [arm64] + os: [linux] + + '@oven/bun-linux-x64-baseline@1.3.6': + resolution: {integrity: sha512-jRmnX18ak8WzqLrex3siw0PoVKyIeI5AiCv4wJLgSs7VKfOqrPycfHIWfIX2jdn7ngqbHFPzI09VBKANZ4Pckg==} + cpu: [x64] + os: [linux] + + '@oven/bun-linux-x64-musl-baseline@1.3.6': + resolution: {integrity: sha512-7FjVnxnRTp/AgWqSQRT/Vt9TYmvnZ+4M+d9QOKh/Lf++wIFXFGSeAgD6bV1X/yr2UPVmZDk+xdhr2XkU7l2v3w==} + cpu: [x64] + os: [linux] + + '@oven/bun-linux-x64-musl@1.3.6': + resolution: {integrity: sha512-YeXcJ9K6vJAt1zSkeA21J6pTe7PgDMLTHKGI3nQBiMYnYf7Ob3K+b/ChSCznrJG7No5PCPiQPg4zTgA+BOTmSA==} + cpu: [x64] + os: [linux] + + '@oven/bun-linux-x64@1.3.6': + resolution: {integrity: sha512-egfngj0dfJ868cf30E7B+ye9KUWSebYxOG4l9YP5eWeMXCtenpenx0zdKtAn9qxJgEJym5AN6trtlk+J6x8Lig==} + cpu: [x64] + os: [linux] + + '@oven/bun-windows-x64-baseline@1.3.6': + resolution: {integrity: sha512-PFUa7JL4lGoyyppeS4zqfuoXXih+gSE0XxhDMrCPVEUev0yhGNd/tbWBvcdpYnUth80owENoGjc8s5Knopv9wA==} + cpu: [x64] + os: [win32] + + '@oven/bun-windows-x64@1.3.6': + resolution: {integrity: sha512-Sr1KwUcbB0SEpnSPO22tNJppku2khjFluEst+mTGhxHzAGQTQncNeJxDnt3F15n+p9Q+mlcorxehd68n1siikQ==} + cpu: [x64] + os: [win32] + + '@types/bun@1.3.6': + resolution: {integrity: sha512-uWCv6FO/8LcpREhenN1d1b6fcspAB+cefwD7uti8C8VffIv0Um08TKMn98FynpTiU38+y2dUO55T11NgDt8VAA==} + + '@types/node@25.0.9': + resolution: {integrity: sha512-/rpCXHlCWeqClNBwUhDcusJxXYDjZTyE8v5oTO7WbL8eij2nKhUeU89/6xgjU7N4/Vh3He0BtyhJdQbDyhiXAw==} + + bun-types@1.3.6: + resolution: {integrity: sha512-OlFwHcnNV99r//9v5IIOgQ9Uk37gZqrNMCcqEaExdkVq3Avwqok1bJFmvGMCkCE0FqzdY8VMOZpfpR3lwI+CsQ==} + + bun@1.3.6: + resolution: {integrity: sha512-Tn98GlZVN2WM7+lg/uGn5DzUao37Yc0PUz7yzYHdeF5hd+SmHQGbCUIKE4Sspdgtxn49LunK3mDNBC2Qn6GJjw==} + cpu: [arm64, x64] + os: [darwin, linux, win32] + hasBin: true + + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + +snapshots: + + '@oven/bun-darwin-aarch64@1.3.6': + optional: true + + '@oven/bun-darwin-x64-baseline@1.3.6': + optional: true + + '@oven/bun-darwin-x64@1.3.6': + optional: true + + '@oven/bun-linux-aarch64-musl@1.3.6': + optional: true + + '@oven/bun-linux-aarch64@1.3.6': + optional: true + + '@oven/bun-linux-x64-baseline@1.3.6': + optional: true + + '@oven/bun-linux-x64-musl-baseline@1.3.6': + optional: true + + '@oven/bun-linux-x64-musl@1.3.6': + optional: true + + '@oven/bun-linux-x64@1.3.6': + optional: true + + '@oven/bun-windows-x64-baseline@1.3.6': + optional: true + + '@oven/bun-windows-x64@1.3.6': + optional: true + + '@types/bun@1.3.6': + dependencies: + bun-types: 1.3.6 + + '@types/node@25.0.9': + dependencies: + undici-types: 7.16.0 + + bun-types@1.3.6: + dependencies: + '@types/node': 25.0.9 + + bun@1.3.6: + optionalDependencies: + '@oven/bun-darwin-aarch64': 1.3.6 + '@oven/bun-darwin-x64': 1.3.6 + '@oven/bun-darwin-x64-baseline': 1.3.6 + '@oven/bun-linux-aarch64': 1.3.6 + '@oven/bun-linux-aarch64-musl': 1.3.6 + '@oven/bun-linux-x64': 1.3.6 + '@oven/bun-linux-x64-baseline': 1.3.6 + '@oven/bun-linux-x64-musl': 1.3.6 + '@oven/bun-linux-x64-musl-baseline': 1.3.6 + '@oven/bun-windows-x64': 1.3.6 + '@oven/bun-windows-x64-baseline': 1.3.6 + + undici-types@7.16.0: {} diff --git a/.github/scripts/run-backend-compile-tests.sh b/.github/scripts/run-backend-compile-tests.sh deleted file mode 100644 index 1f9e29aa7..000000000 --- a/.github/scripts/run-backend-compile-tests.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -RED='\033[0;31m' - -# fmt -./mvnw spotless:check - -# lint -./mvnw checkstyle:check - -# compile -./mvnw -B verify -Dmaven.test.skip=true --no-transfer-progress diff --git a/.github/scripts/run-backend-compile-tests.ts b/.github/scripts/run-backend-compile-tests.ts new file mode 100644 index 000000000..1c4ca57c6 --- /dev/null +++ b/.github/scripts/run-backend-compile-tests.ts @@ -0,0 +1,21 @@ +import { $ } from "bun"; + +async function main() { + // fmt + await $`./mvnw spotless:check`; + + // lint + await $`./mvnw checkstyle:check`; + + // compile + await $`./mvnw -B verify -Dmaven.test.skip=true --no-transfer-progress`; +} + +main() + .then(() => { + process.exit(0); + }) + .catch((e) => { + console.error(e); + process.exit(1); + }); diff --git a/.github/scripts/tsconfig.json b/.github/scripts/tsconfig.json new file mode 100644 index 000000000..de49a4cea --- /dev/null +++ b/.github/scripts/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "baseUrl": "./", + "allowJs": true, + "checkJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "resolveJsonModule": true, + "experimentalDecorators": true, + "paths": { + "@/*": ["src/*"] + } + }, + "include": [ + "**/*.ts", + "**/*.tsx", + "src/lib/types/*.d.ts", + "vitest.config.mts" + ], + "exclude": ["node_modules"] +} From ae86667fb98d694b8151f7742dd9ca575a4ad1eb Mon Sep 17 00:00:00 2001 From: Tahmid Ahmed Date: Thu, 15 Jan 2026 21:11:05 -0500 Subject: [PATCH 02/10] 641: wip pt2 --- .../test/backend-pre-test/action.yml | 21 ++- .github/scripts/bun.lock | 48 ++++++ .github/scripts/fn/colors.ts | 11 ++ .github/scripts/fn/run-backend-instance.ts | 70 ++++++++ .github/scripts/fn/run-local-db.ts | 75 +++++++++ .github/scripts/local-db.sh | 52 ------ .github/scripts/package.json | 1 - .github/scripts/pnpm-lock.yaml | 155 ------------------ .github/scripts/run-backend-compile-tests.ts | 2 +- .github/scripts/run-backend-instance.sh | 38 ----- .github/scripts/run-backend-tests.sh | 26 --- .github/scripts/run-backend-tests.ts | 29 ++++ .github/scripts/tsconfig.json | 42 +++-- .github/workflows/ci-cd.yml | 25 ++- 14 files changed, 287 insertions(+), 308 deletions(-) create mode 100644 .github/scripts/bun.lock create mode 100644 .github/scripts/fn/colors.ts create mode 100644 .github/scripts/fn/run-backend-instance.ts create mode 100644 .github/scripts/fn/run-local-db.ts delete mode 100644 .github/scripts/local-db.sh delete mode 100644 .github/scripts/pnpm-lock.yaml delete mode 100644 .github/scripts/run-backend-instance.sh delete mode 100644 .github/scripts/run-backend-tests.sh create mode 100644 .github/scripts/run-backend-tests.ts diff --git a/.github/composite/test/backend-pre-test/action.yml b/.github/composite/test/backend-pre-test/action.yml index 899af3cbb..61d2494bf 100644 --- a/.github/composite/test/backend-pre-test/action.yml +++ b/.github/composite/test/backend-pre-test/action.yml @@ -20,23 +20,22 @@ runs: javac -version echo "JAVA_HOME=$JAVA_HOME" - - uses: pnpm/action-setup@v3 - with: - version: 10 - - - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: "pnpm" - cache-dependency-path: ".github/scripts/pnpm-lock.yaml" - - uses: oven-sh/setup-bun@v2 with: bun-version: latest + - name: Cache Bun dependencies + uses: actions/cache@v4 + with: + path: ~/.bun/install/cache + # Hash your lockfile to invalidate the cache when dependencies change + key: ${{ runner.os }}-bun-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-bun- + - name: Install deps shell: bash - run: pnpm --dir .github/scripts install --frozen-lockfile + run: bun install --cwd .github/scripts --frozen-lockfile - name: Run script shell: bash diff --git a/.github/scripts/bun.lock b/.github/scripts/bun.lock new file mode 100644 index 000000000..6b3eea5d0 --- /dev/null +++ b/.github/scripts/bun.lock @@ -0,0 +1,48 @@ +{ + "lockfileVersion": 1, + "configVersion": 1, + "workspaces": { + "": { + "name": "scripts", + "dependencies": { + "bun": "^1.3.6", + }, + "devDependencies": { + "@types/bun": "^1.3.6", + }, + }, + }, + "packages": { + "@oven/bun-darwin-aarch64": ["@oven/bun-darwin-aarch64@1.3.6", "", { "os": "darwin", "cpu": "arm64" }, "sha512-27rypIapNkYboOSylkf1tD9UW9Ado2I+P1NBL46Qz29KmOjTL6WuJ7mHDC5O66CYxlOkF5r93NPDAC3lFHYBXw=="], + + "@oven/bun-darwin-x64": ["@oven/bun-darwin-x64@1.3.6", "", { "os": "darwin", "cpu": "x64" }, "sha512-I82xGzPkBxzBKgbl8DsA0RfMQCWTWjNmLjIEkW1ECiv3qK02kHGQ5FGUr/29L/SuvnGsULW4tBTRNZiMzL37nA=="], + + "@oven/bun-darwin-x64-baseline": ["@oven/bun-darwin-x64-baseline@1.3.6", "", { "os": "darwin", "cpu": "x64" }, "sha512-nqtr+pTsHqusYpG2OZc6s+AmpWDB/FmBvstrK0y5zkti4OqnCuu7Ev2xNjS7uyb47NrAFF40pWqkpaio5XEd7w=="], + + "@oven/bun-linux-aarch64": ["@oven/bun-linux-aarch64@1.3.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-YaQEAYjBanoOOtpqk/c5GGcfZIyxIIkQ2m1TbHjedRmJNwxzWBhGinSARFkrRIc3F8pRIGAopXKvJ/2rjN1LzQ=="], + + "@oven/bun-linux-aarch64-musl": ["@oven/bun-linux-aarch64-musl@1.3.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-FR+iJt17rfFgYgpxL3M67AUwujOgjw52ZJzB9vElI5jQXNjTyOKf8eH4meSk4vjlYF3h/AjKYd6pmN0OIUlVKQ=="], + + "@oven/bun-linux-x64": ["@oven/bun-linux-x64@1.3.6", "", { "os": "linux", "cpu": "x64" }, "sha512-egfngj0dfJ868cf30E7B+ye9KUWSebYxOG4l9YP5eWeMXCtenpenx0zdKtAn9qxJgEJym5AN6trtlk+J6x8Lig=="], + + "@oven/bun-linux-x64-baseline": ["@oven/bun-linux-x64-baseline@1.3.6", "", { "os": "linux", "cpu": "x64" }, "sha512-jRmnX18ak8WzqLrex3siw0PoVKyIeI5AiCv4wJLgSs7VKfOqrPycfHIWfIX2jdn7ngqbHFPzI09VBKANZ4Pckg=="], + + "@oven/bun-linux-x64-musl": ["@oven/bun-linux-x64-musl@1.3.6", "", { "os": "linux", "cpu": "x64" }, "sha512-YeXcJ9K6vJAt1zSkeA21J6pTe7PgDMLTHKGI3nQBiMYnYf7Ob3K+b/ChSCznrJG7No5PCPiQPg4zTgA+BOTmSA=="], + + "@oven/bun-linux-x64-musl-baseline": ["@oven/bun-linux-x64-musl-baseline@1.3.6", "", { "os": "linux", "cpu": "x64" }, "sha512-7FjVnxnRTp/AgWqSQRT/Vt9TYmvnZ+4M+d9QOKh/Lf++wIFXFGSeAgD6bV1X/yr2UPVmZDk+xdhr2XkU7l2v3w=="], + + "@oven/bun-windows-x64": ["@oven/bun-windows-x64@1.3.6", "", { "os": "win32", "cpu": "x64" }, "sha512-Sr1KwUcbB0SEpnSPO22tNJppku2khjFluEst+mTGhxHzAGQTQncNeJxDnt3F15n+p9Q+mlcorxehd68n1siikQ=="], + + "@oven/bun-windows-x64-baseline": ["@oven/bun-windows-x64-baseline@1.3.6", "", { "os": "win32", "cpu": "x64" }, "sha512-PFUa7JL4lGoyyppeS4zqfuoXXih+gSE0XxhDMrCPVEUev0yhGNd/tbWBvcdpYnUth80owENoGjc8s5Knopv9wA=="], + + "@types/bun": ["@types/bun@1.3.6", "", { "dependencies": { "bun-types": "1.3.6" } }, "sha512-uWCv6FO/8LcpREhenN1d1b6fcspAB+cefwD7uti8C8VffIv0Um08TKMn98FynpTiU38+y2dUO55T11NgDt8VAA=="], + + "@types/node": ["@types/node@25.0.9", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-/rpCXHlCWeqClNBwUhDcusJxXYDjZTyE8v5oTO7WbL8eij2nKhUeU89/6xgjU7N4/Vh3He0BtyhJdQbDyhiXAw=="], + + "bun": ["bun@1.3.6", "", { "optionalDependencies": { "@oven/bun-darwin-aarch64": "1.3.6", "@oven/bun-darwin-x64": "1.3.6", "@oven/bun-darwin-x64-baseline": "1.3.6", "@oven/bun-linux-aarch64": "1.3.6", "@oven/bun-linux-aarch64-musl": "1.3.6", "@oven/bun-linux-x64": "1.3.6", "@oven/bun-linux-x64-baseline": "1.3.6", "@oven/bun-linux-x64-musl": "1.3.6", "@oven/bun-linux-x64-musl-baseline": "1.3.6", "@oven/bun-windows-x64": "1.3.6", "@oven/bun-windows-x64-baseline": "1.3.6" }, "os": [ "linux", "win32", "darwin", ], "cpu": [ "x64", "arm64", ], "bin": { "bun": "bin/bun.exe", "bunx": "bin/bunx.exe" } }, "sha512-Tn98GlZVN2WM7+lg/uGn5DzUao37Yc0PUz7yzYHdeF5hd+SmHQGbCUIKE4Sspdgtxn49LunK3mDNBC2Qn6GJjw=="], + + "bun-types": ["bun-types@1.3.6", "", { "dependencies": { "@types/node": "*" } }, "sha512-OlFwHcnNV99r//9v5IIOgQ9Uk37gZqrNMCcqEaExdkVq3Avwqok1bJFmvGMCkCE0FqzdY8VMOZpfpR3lwI+CsQ=="], + + "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], + } +} diff --git a/.github/scripts/fn/colors.ts b/.github/scripts/fn/colors.ts new file mode 100644 index 000000000..c9aaa68d4 --- /dev/null +++ b/.github/scripts/fn/colors.ts @@ -0,0 +1,11 @@ +const CYAN = "\x1b[36m"; +const RESET = "\x1b[0m"; +const DIM = "\x1b[2m"; + +export function cyan(s: string) { + return `${CYAN}${s}${RESET}`; +} + +export function dim(s: string) { + return `${DIM}${s}${RESET}`; +} diff --git a/.github/scripts/fn/run-backend-instance.ts b/.github/scripts/fn/run-backend-instance.ts new file mode 100644 index 000000000..782a9623a --- /dev/null +++ b/.github/scripts/fn/run-backend-instance.ts @@ -0,0 +1,70 @@ +import { $ } from "bun"; +import { cyan } from "./colors"; + +let be: Bun.Subprocess<"ignore", Bun.BunFile, "inherit"> | undefined; + +async function start() { + try { + console.log("Starting backend instance..."); + + await $`java -version`; + await $`javac -version`; + console.log(`JAVA_HOME=${process.env.JAVA_HOME}`); + + const logFile = Bun.file("backend.log"); + be = Bun.spawn( + ["./mvnw", "-Dspring-boot.run.profiles=ci", "spring-boot:run"], + { + stdout: logFile, + }, + ); + + console.log("Waiting for backend to become ready."); + + let ready = false; + const attempts = 30; + + for (let i = 1; i <= attempts; i++) { + try { + const response = await fetch("http://localhost:8080/api"); + const data = (await response.json()) as { success: boolean }; + + if (data.success === true) { + console.log("Backend is up!"); + ready = true; + break; + } + } catch (_) {} + + console.log(`Waiting for backend... (${i}/${attempts})`); + await Bun.sleep(2000); + } + + if (!ready) { + console.error("Backend failed to start in time."); + end(); + } + + console.log("backend ready"); + } catch (e) { + console.error(e); + end(); + } +} + +async function end() { + if (be) { + if (!be.killed) { + be.kill(); + } + console.log(cyan("=== BACKEND LOGS ===")); + console.log(cyan(await Bun.file("backend.log").text())); + console.log(cyan("=== BACKEND LOGS ===")); + } + process.exit(1); +} + +export const backend = { + start, + end, +}; diff --git a/.github/scripts/fn/run-local-db.ts b/.github/scripts/fn/run-local-db.ts new file mode 100644 index 000000000..43b315d93 --- /dev/null +++ b/.github/scripts/fn/run-local-db.ts @@ -0,0 +1,75 @@ +import { $ } from "bun"; + +async function start() { + try { + console.log("Starting postgres container..."); + + await $`docker rm -f codebloom-db`; + + await $`docker run -d \ + --name codebloom-db \ + -e POSTGRES_USER=postgres \ + -e POSTGRES_PASSWORD=postgres \ + -e POSTGRES_DB=codebloom \ + -p 5440:5432 \ + postgres:16`; + + console.log("Waiting for postgres to become ready."); + + let ready = false; + const attempts = 30; + + for (let i = 1; i <= attempts; i++) { + const check = await $`docker exec codebloom-db pg_isready -U postgres` + .quiet() + .nothrow(); + + if (check.exitCode === 0) { + console.log("postgres is ready!"); + ready = true; + break; + } + + console.log(`Waiting for backend... (${i}/${attempts})`); + await Bun.sleep(2000); + } + + if (!ready) { + console.error("postgres failed to start in time."); + process.exit(1); + } + + process.env.DATABASE_HOST = "localhost"; + process.env.DATABASE_PORT = "5440"; + process.env.DATABASE_NAME = "codebloom"; + process.env.DATABASE_USER = "postgres"; + process.env.DATABASE_PASSWORD = "postgres"; + + console.log("postres started, running migrations..."); + + await $`./mvnw flyway:migrate -Dflyway.locations=filesystem:./db`; + + console.log("postgres ready"); + } catch (e) { + console.error(e); + end(); + } +} + +async function end() { + console.log("Stopping and removing postgres container..."); + await $`docker logs codebloom-db`.nothrow(); + await $`docker stop codebloom-db`.quiet().nothrow(); + await $`docker rm codebloom-db`.quiet().nothrow(); + + delete process.env.DATABASE_HOST; + delete process.env.DATABASE_PORT; + delete process.env.DATABASE_NAME; + delete process.env.DATABASE_USER; + delete process.env.DATABASE_PASSWORD; +} + +export const db = { + start, + end, +}; diff --git a/.github/scripts/local-db.sh b/.github/scripts/local-db.sh deleted file mode 100644 index 2decab01d..000000000 --- a/.github/scripts/local-db.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env bash - -db_cleanup() { - echo "Stopping and removing postgres container..." - docker stop codebloom-db >/dev/null 2>&1 || true - docker rm codebloom-db >/dev/null 2>&1 || true - - unset DATABASE_HOST - unset DATABASE_PORT - unset DATABASE_NAME - unset DATABASE_USER - unset DATABASE_PASSWORD -} - -db_startup() { - echo "Starting postgres container..." - docker rm -f codebloom-db >/dev/null 2>&1 || true - docker run -d \ - --name codebloom-db \ - -e POSTGRES_USER=postgres \ - -e POSTGRES_PASSWORD=postgres \ - -e POSTGRES_DB=codebloom \ - -p 5440:5432 \ - postgres:16 - - echo "Waiting for postgres to become ready." - for i in {1..30}; do - if docker exec codebloom-db pg_isready -U postgres >/dev/null 2>&1; then - echo "postgres is ready!" - break - fi - echo "Waiting for postgres, sleep 2... ($i/30)" - sleep 2 - done - - if ! docker exec codebloom-db pg_isready -U postgres >/dev/null 2>&1; then - echo "postgres failed to start in time." - docker logs codebloom-db || true - exit 1 - fi - - export DATABASE_HOST=localhost - export DATABASE_PORT=5440 - export DATABASE_NAME=codebloom - export DATABASE_USER=postgres - export DATABASE_PASSWORD=postgres - - echo "postgres ready. migrating now..." - ./mvnw flyway:migrate -Dflyway.locations=filesystem:./db - echo "postgres migration complete" - -} diff --git a/.github/scripts/package.json b/.github/scripts/package.json index ac73670cd..c5c7a8a5a 100644 --- a/.github/scripts/package.json +++ b/.github/scripts/package.json @@ -6,7 +6,6 @@ "keywords": [], "author": "Tahmid Ahmed", "license": "MIT", - "packageManager": "pnpm@10.24.0", "dependencies": { "bun": "^1.3.6" }, diff --git a/.github/scripts/pnpm-lock.yaml b/.github/scripts/pnpm-lock.yaml deleted file mode 100644 index 046bcf34a..000000000 --- a/.github/scripts/pnpm-lock.yaml +++ /dev/null @@ -1,155 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - bun: - specifier: ^1.3.6 - version: 1.3.6 - devDependencies: - '@types/bun': - specifier: ^1.3.6 - version: 1.3.6 - -packages: - - '@oven/bun-darwin-aarch64@1.3.6': - resolution: {integrity: sha512-27rypIapNkYboOSylkf1tD9UW9Ado2I+P1NBL46Qz29KmOjTL6WuJ7mHDC5O66CYxlOkF5r93NPDAC3lFHYBXw==} - cpu: [arm64] - os: [darwin] - - '@oven/bun-darwin-x64-baseline@1.3.6': - resolution: {integrity: sha512-nqtr+pTsHqusYpG2OZc6s+AmpWDB/FmBvstrK0y5zkti4OqnCuu7Ev2xNjS7uyb47NrAFF40pWqkpaio5XEd7w==} - cpu: [x64] - os: [darwin] - - '@oven/bun-darwin-x64@1.3.6': - resolution: {integrity: sha512-I82xGzPkBxzBKgbl8DsA0RfMQCWTWjNmLjIEkW1ECiv3qK02kHGQ5FGUr/29L/SuvnGsULW4tBTRNZiMzL37nA==} - cpu: [x64] - os: [darwin] - - '@oven/bun-linux-aarch64-musl@1.3.6': - resolution: {integrity: sha512-FR+iJt17rfFgYgpxL3M67AUwujOgjw52ZJzB9vElI5jQXNjTyOKf8eH4meSk4vjlYF3h/AjKYd6pmN0OIUlVKQ==} - cpu: [arm64] - os: [linux] - - '@oven/bun-linux-aarch64@1.3.6': - resolution: {integrity: sha512-YaQEAYjBanoOOtpqk/c5GGcfZIyxIIkQ2m1TbHjedRmJNwxzWBhGinSARFkrRIc3F8pRIGAopXKvJ/2rjN1LzQ==} - cpu: [arm64] - os: [linux] - - '@oven/bun-linux-x64-baseline@1.3.6': - resolution: {integrity: sha512-jRmnX18ak8WzqLrex3siw0PoVKyIeI5AiCv4wJLgSs7VKfOqrPycfHIWfIX2jdn7ngqbHFPzI09VBKANZ4Pckg==} - cpu: [x64] - os: [linux] - - '@oven/bun-linux-x64-musl-baseline@1.3.6': - resolution: {integrity: sha512-7FjVnxnRTp/AgWqSQRT/Vt9TYmvnZ+4M+d9QOKh/Lf++wIFXFGSeAgD6bV1X/yr2UPVmZDk+xdhr2XkU7l2v3w==} - cpu: [x64] - os: [linux] - - '@oven/bun-linux-x64-musl@1.3.6': - resolution: {integrity: sha512-YeXcJ9K6vJAt1zSkeA21J6pTe7PgDMLTHKGI3nQBiMYnYf7Ob3K+b/ChSCznrJG7No5PCPiQPg4zTgA+BOTmSA==} - cpu: [x64] - os: [linux] - - '@oven/bun-linux-x64@1.3.6': - resolution: {integrity: sha512-egfngj0dfJ868cf30E7B+ye9KUWSebYxOG4l9YP5eWeMXCtenpenx0zdKtAn9qxJgEJym5AN6trtlk+J6x8Lig==} - cpu: [x64] - os: [linux] - - '@oven/bun-windows-x64-baseline@1.3.6': - resolution: {integrity: sha512-PFUa7JL4lGoyyppeS4zqfuoXXih+gSE0XxhDMrCPVEUev0yhGNd/tbWBvcdpYnUth80owENoGjc8s5Knopv9wA==} - cpu: [x64] - os: [win32] - - '@oven/bun-windows-x64@1.3.6': - resolution: {integrity: sha512-Sr1KwUcbB0SEpnSPO22tNJppku2khjFluEst+mTGhxHzAGQTQncNeJxDnt3F15n+p9Q+mlcorxehd68n1siikQ==} - cpu: [x64] - os: [win32] - - '@types/bun@1.3.6': - resolution: {integrity: sha512-uWCv6FO/8LcpREhenN1d1b6fcspAB+cefwD7uti8C8VffIv0Um08TKMn98FynpTiU38+y2dUO55T11NgDt8VAA==} - - '@types/node@25.0.9': - resolution: {integrity: sha512-/rpCXHlCWeqClNBwUhDcusJxXYDjZTyE8v5oTO7WbL8eij2nKhUeU89/6xgjU7N4/Vh3He0BtyhJdQbDyhiXAw==} - - bun-types@1.3.6: - resolution: {integrity: sha512-OlFwHcnNV99r//9v5IIOgQ9Uk37gZqrNMCcqEaExdkVq3Avwqok1bJFmvGMCkCE0FqzdY8VMOZpfpR3lwI+CsQ==} - - bun@1.3.6: - resolution: {integrity: sha512-Tn98GlZVN2WM7+lg/uGn5DzUao37Yc0PUz7yzYHdeF5hd+SmHQGbCUIKE4Sspdgtxn49LunK3mDNBC2Qn6GJjw==} - cpu: [arm64, x64] - os: [darwin, linux, win32] - hasBin: true - - undici-types@7.16.0: - resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} - -snapshots: - - '@oven/bun-darwin-aarch64@1.3.6': - optional: true - - '@oven/bun-darwin-x64-baseline@1.3.6': - optional: true - - '@oven/bun-darwin-x64@1.3.6': - optional: true - - '@oven/bun-linux-aarch64-musl@1.3.6': - optional: true - - '@oven/bun-linux-aarch64@1.3.6': - optional: true - - '@oven/bun-linux-x64-baseline@1.3.6': - optional: true - - '@oven/bun-linux-x64-musl-baseline@1.3.6': - optional: true - - '@oven/bun-linux-x64-musl@1.3.6': - optional: true - - '@oven/bun-linux-x64@1.3.6': - optional: true - - '@oven/bun-windows-x64-baseline@1.3.6': - optional: true - - '@oven/bun-windows-x64@1.3.6': - optional: true - - '@types/bun@1.3.6': - dependencies: - bun-types: 1.3.6 - - '@types/node@25.0.9': - dependencies: - undici-types: 7.16.0 - - bun-types@1.3.6: - dependencies: - '@types/node': 25.0.9 - - bun@1.3.6: - optionalDependencies: - '@oven/bun-darwin-aarch64': 1.3.6 - '@oven/bun-darwin-x64': 1.3.6 - '@oven/bun-darwin-x64-baseline': 1.3.6 - '@oven/bun-linux-aarch64': 1.3.6 - '@oven/bun-linux-aarch64-musl': 1.3.6 - '@oven/bun-linux-x64': 1.3.6 - '@oven/bun-linux-x64-baseline': 1.3.6 - '@oven/bun-linux-x64-musl': 1.3.6 - '@oven/bun-linux-x64-musl-baseline': 1.3.6 - '@oven/bun-windows-x64': 1.3.6 - '@oven/bun-windows-x64-baseline': 1.3.6 - - undici-types@7.16.0: {} diff --git a/.github/scripts/run-backend-compile-tests.ts b/.github/scripts/run-backend-compile-tests.ts index 1c4ca57c6..a2aad8a60 100644 --- a/.github/scripts/run-backend-compile-tests.ts +++ b/.github/scripts/run-backend-compile-tests.ts @@ -13,7 +13,7 @@ async function main() { main() .then(() => { - process.exit(0); + process.exit(); }) .catch((e) => { console.error(e); diff --git a/.github/scripts/run-backend-instance.sh b/.github/scripts/run-backend-instance.sh deleted file mode 100644 index 5c9a5549a..000000000 --- a/.github/scripts/run-backend-instance.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env bash - -backend_cleanup() { - echo "[INFO] ===== BACKEND LOGS START =====" - cat backend.log || echo "[WARN] backend.log not found" - echo "[INFO] ===== BACKEND LOGS END =====" - if kill $(cat spring_pid.txt) >/dev/null 2>&1; then - echo "Backend process killed successfully." - else - echo "Backend was not running or already stopped." - fi -} - -backend_startup() { - java -version - javac -version - echo "JAVA_HOME=$JAVA_HOME" - - ./mvnw -Dspring-boot.run.profiles=ci spring-boot:run >backend.log 2>&1 & - echo $! >spring_pid.txt - - backend_started=false - for i in {1..30}; do - if curl -s http://localhost:8080/api | grep -q '"success":true'; then - echo "Backend is up!" - backend_started=true - break - fi - echo "Waiting for backend... ($i/30)" - sleep 5 - done - - if [ "$backend_started" = false ]; then - echo "Backend failed to start in time." - exit 1 - fi - -} diff --git a/.github/scripts/run-backend-tests.sh b/.github/scripts/run-backend-tests.sh deleted file mode 100644 index cd828e5c8..000000000 --- a/.github/scripts/run-backend-tests.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "$DIR/local-db.sh" - -trap db_cleanup EXIT - -java -version -javac -version -echo "JAVA_HOME=$JAVA_HOME" - -./mvnw -B install -D skipTests --no-transfer-progress - -./mvnw -B exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="install-deps" -./mvnw -B exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="install firefox" - -corepack enable pnpm -cd email -pnpm i --frozen-lockfile -./email.sh -cd .. - -db_startup - -./mvnw clean verify -Dspring.profiles.active=ci diff --git a/.github/scripts/run-backend-tests.ts b/.github/scripts/run-backend-tests.ts new file mode 100644 index 000000000..0c2389d98 --- /dev/null +++ b/.github/scripts/run-backend-tests.ts @@ -0,0 +1,29 @@ +import { $ } from "bun"; +import { db } from "./fn/run-local-db"; + +async function main() { + try { + await db.start(); + + await $`./mvnw -B install -D skipTests --no-transfer-progress`; + + await $`./mvnw -B exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="install-deps"`; + await $`./mvnw -B exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="install firefox"`; + + await $`corepack enable pnpm`; + await $`cd email && pnpm i --frozen-lockfile && ./email.sh && cd ..`; + + await $`./mvnw clean verify -Dspring.profiles.active=ci`; + } finally { + await db.end(); + } +} + +main() + .then(() => { + process.exit(0); + }) + .catch((e) => { + console.error(e); + process.exit(1); + }); diff --git a/.github/scripts/tsconfig.json b/.github/scripts/tsconfig.json index de49a4cea..c3c57e20d 100644 --- a/.github/scripts/tsconfig.json +++ b/.github/scripts/tsconfig.json @@ -1,23 +1,29 @@ { "compilerOptions": { - "baseUrl": "./", + // Environment setup & latest features + "lib": ["ESNext"], + "target": "ESNext", + "module": "Preserve", + "moduleDetection": "force", + "jsx": "react-jsx", "allowJs": true, - "checkJs": true, - "skipLibCheck": true, - "strict": true, + + // Bundler mode + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, "noEmit": true, - "esModuleInterop": true, - "resolveJsonModule": true, - "experimentalDecorators": true, - "paths": { - "@/*": ["src/*"] - } - }, - "include": [ - "**/*.ts", - "**/*.tsx", - "src/lib/types/*.d.ts", - "vitest.config.mts" - ], - "exclude": ["node_modules"] + + // Best practices + "strict": true, + "skipLibCheck": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedIndexedAccess": true, + "noImplicitOverride": true, + + // Some stricter flags (disabled by default) + "noUnusedLocals": false, + "noUnusedParameters": false, + "noPropertyAccessFromIndexSignature": false + } } diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 20c2280f8..2f86294b3 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -40,11 +40,6 @@ jobs: - name: Disable man-db uses: ./.github/composite/disable-mandb - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: 20 - - name: Set up OpenJDK 25 uses: actions/setup-java@v4 with: @@ -65,8 +60,26 @@ jobs: GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} UNLOAD_ENVIRONMENTS: ci,ci-app + - uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Cache Bun dependencies + uses: actions/cache@v4 + with: + path: ~/.bun/install/cache + # Hash your lockfile to invalidate the cache when dependencies change + key: ${{ runner.os }}-bun-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-bun- + + - name: Install deps + shell: bash + run: bun install --cwd .github/scripts --frozen-lockfile + - name: Run script - run: bash .github/scripts/run-backend-tests.sh + shell: bash + run: bun .github/scripts/run-backend-tests.ts - name: Upload JaCoCo HTML report uses: actions/upload-artifact@v4 From fde382176e849d1d1a5efac6a092740c3d3797dc Mon Sep 17 00:00:00 2001 From: Tahmid Ahmed Date: Thu, 15 Jan 2026 21:55:21 -0500 Subject: [PATCH 03/10] 641: wip pt3 641: wip fix coloring 641: wip fix coloring pt2 641: update ai review 641: add load-secrets 641: add load-secrets pt2 641: add load-secrets pt3 641: add load-secrets pt4 641: add load-secrets pt5 fix writing logic 641: add load-secrets pt5 fix writing logic wdekfjnewkgfn --- .github/composite/load-secrets/action.yml | 20 ++++- .github/scripts/fn/colors.ts | 98 +++++++++++++++++++++- .github/scripts/fn/run-backend-instance.ts | 12 ++- .github/scripts/fn/run-local-db.ts | 12 ++- .github/scripts/load-secrets.sh | 67 --------------- .github/scripts/load-secrets.ts | 96 +++++++++++++++++++++ .github/scripts/run-frontend-tests.sh | 15 ---- .github/scripts/run-frontend-tests.ts | 27 ++++++ .github/workflows/ai-review.yml | 20 ++++- .github/workflows/ci-cd.yml | 20 ++++- 10 files changed, 292 insertions(+), 95 deletions(-) delete mode 100644 .github/scripts/load-secrets.sh create mode 100644 .github/scripts/load-secrets.ts delete mode 100644 .github/scripts/run-frontend-tests.sh create mode 100644 .github/scripts/run-frontend-tests.ts diff --git a/.github/composite/load-secrets/action.yml b/.github/composite/load-secrets/action.yml index 64392f6da..25df02b5b 100644 --- a/.github/composite/load-secrets/action.yml +++ b/.github/composite/load-secrets/action.yml @@ -37,8 +37,24 @@ runs: shell: bash run: git-crypt --version - - name: Run load secrets script + - uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Cache Bun dependencies + uses: actions/cache@v4 + with: + path: ~/.bun/install/cache + key: ${{ runner.os }}-bun-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-bun- + + - name: Install deps + shell: bash + run: bun install --cwd .github/scripts --frozen-lockfile + + - name: Run script shell: bash - run: bash .github/scripts/load-secrets.sh + run: bun .github/scripts/load-secrets.ts env: UNLOAD_ENVIRONMENTS: ${{ inputs.UNLOAD_ENVIRONMENTS }} diff --git a/.github/scripts/fn/colors.ts b/.github/scripts/fn/colors.ts index c9aaa68d4..aebe42cbd 100644 --- a/.github/scripts/fn/colors.ts +++ b/.github/scripts/fn/colors.ts @@ -1,11 +1,103 @@ -const CYAN = "\x1b[36m"; -const RESET = "\x1b[0m"; -const DIM = "\x1b[2m"; +export function black(s: string) { + return `${BLACK}${s}${RESET}`; +} + +export function red(s: string) { + return `${RED}${s}${RESET}`; +} + +export function green(s: string) { + return `${GREEN}${s}${RESET}`; +} + +export function yellow(s: string) { + return `${YELLOW}${s}${RESET}`; +} + +export function blue(s: string) { + return `${BLUE}${s}${RESET}`; +} + +export function magenta(s: string) { + return `${MAGENTA}${s}${RESET}`; +} export function cyan(s: string) { return `${CYAN}${s}${RESET}`; } +export function white(s: string) { + return `${WHITE}${s}${RESET}`; +} + +export function gray(s: string) { + return `${GRAY}${s}${RESET}`; +} + +export function brightRed(s: string) { + return `${BRIGHT_RED}${s}${RESET}`; +} + +export function brightGreen(s: string) { + return `${BRIGHT_GREEN}${s}${RESET}`; +} + +export function brightYellow(s: string) { + return `${BRIGHT_YELLOW}${s}${RESET}`; +} + +export function brightBlue(s: string) { + return `${BRIGHT_BLUE}${s}${RESET}`; +} + +export function brightMagenta(s: string) { + return `${BRIGHT_MAGENTA}${s}${RESET}`; +} + +export function brightCyan(s: string) { + return `${BRIGHT_CYAN}${s}${RESET}`; +} + +export function brightWhite(s: string) { + return `${BRIGHT_WHITE}${s}${RESET}`; +} + +export function bold(s: string) { + return `${BOLD}${s}${RESET}`; +} + export function dim(s: string) { return `${DIM}${s}${RESET}`; } + +export function italic(s: string) { + return `${ITALIC}${s}${RESET}`; +} + +export function underline(s: string) { + return `${UNDERLINE}${s}${RESET}`; +} + +const BLACK = "\x1b[30m"; +const RED = "\x1b[31m"; +const GREEN = "\x1b[32m"; +const YELLOW = "\x1b[33m"; +const BLUE = "\x1b[34m"; +const MAGENTA = "\x1b[35m"; +const CYAN = "\x1b[36m"; +const WHITE = "\x1b[37m"; +const GRAY = "\x1b[90m"; + +const BRIGHT_RED = "\x1b[91m"; +const BRIGHT_GREEN = "\x1b[92m"; +const BRIGHT_YELLOW = "\x1b[93m"; +const BRIGHT_BLUE = "\x1b[94m"; +const BRIGHT_MAGENTA = "\x1b[95m"; +const BRIGHT_CYAN = "\x1b[96m"; +const BRIGHT_WHITE = "\x1b[97m"; + +const RESET = "\x1b[0m"; +const BOLD = "\x1b[1m"; +const DIM = "\x1b[2m"; +const ITALIC = "\x1b[3m"; +const UNDERLINE = "\x1b[4m"; diff --git a/.github/scripts/fn/run-backend-instance.ts b/.github/scripts/fn/run-backend-instance.ts index 782a9623a..c35ae98b4 100644 --- a/.github/scripts/fn/run-backend-instance.ts +++ b/.github/scripts/fn/run-backend-instance.ts @@ -42,7 +42,8 @@ async function start() { if (!ready) { console.error("Backend failed to start in time."); - end(); + await end(); + process.exit(1); } console.log("backend ready"); @@ -58,10 +59,13 @@ async function end() { be.kill(); } console.log(cyan("=== BACKEND LOGS ===")); - console.log(cyan(await Bun.file("backend.log").text())); - console.log(cyan("=== BACKEND LOGS ===")); + const logs = await Bun.file("backend.log").text(); + logs + .split("\n") + .filter((s) => s.length > 0) + .forEach((line) => console.log(cyan(line))); + console.log(cyan("=== BACKEND LOGS END ===")); } - process.exit(1); } export const backend = { diff --git a/.github/scripts/fn/run-local-db.ts b/.github/scripts/fn/run-local-db.ts index 43b315d93..97298a6ba 100644 --- a/.github/scripts/fn/run-local-db.ts +++ b/.github/scripts/fn/run-local-db.ts @@ -1,4 +1,5 @@ import { $ } from "bun"; +import { brightGreen, brightMagenta } from "./colors"; async function start() { try { @@ -36,6 +37,7 @@ async function start() { if (!ready) { console.error("postgres failed to start in time."); + await end(); process.exit(1); } @@ -58,7 +60,15 @@ async function start() { async function end() { console.log("Stopping and removing postgres container..."); - await $`docker logs codebloom-db`.nothrow(); + + console.log(brightMagenta("=== DB LOGS ===")); + const logs = await $`docker logs codebloom-db`.text(); + logs + .split("\n") + .filter((s) => s.length > 0) + .forEach((line) => console.log(brightMagenta(line))); + console.log(brightMagenta("=== DB LOGS END ===")); + await $`docker stop codebloom-db`.quiet().nothrow(); await $`docker rm codebloom-db`.quiet().nothrow(); diff --git a/.github/scripts/load-secrets.sh b/.github/scripts/load-secrets.sh deleted file mode 100644 index 860495abf..000000000 --- a/.github/scripts/load-secrets.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -git-crypt unlock - -# UNLOAD_ENVIRONMENTS="prod,staging,dev" -IFS=',' read -ra ENVS <<<"${UNLOAD_ENVIRONMENTS:-}" - -declare -A LOADED - -for v in "${ENVS[@]}"; do - ENV_FILE=".env.${v}" - if [[ -f "$ENV_FILE" ]]; then - echo "Loading $ENV_FILE" - declare -A BEFORE - for VAR in $(compgen -v); do - BEFORE["$VAR"]=1 - done - - source "$ENV_FILE" - - for VAR in $(compgen -v); do - if [[ -z "${BEFORE["$VAR"]:-}" ]]; then - LOADED["$VAR"]=1 - fi - done - else - echo "Warning: $ENV_FILE not found" - fi -done - -EXCLUDED_VARS=( - "PATH" - "HOME" - "PWD" - "SHELL" - "USER" - "DEBUG" - "LOG_LEVEL" - "CI" - "JAVA_HOME" -) - -for VAR in "${!LOADED[@]}"; do - VALUE="${!VAR-}" - - if [[ "$VAR" == "VAR" ]]; then # weird bug - continue - fi - - echo "$VAR=$VALUE" >>"$GITHUB_ENV" - - for EX in "${EXCLUDED_VARS[@]}"; do - if [[ "$VAR" == "$EX" ]]; then - echo "Not masking $VAR: Excluded" - continue 2 - fi - done - - if [[ "$VALUE" == "true" || "$VALUE" == "false" || -z "$VALUE" ]]; then - echo "Not masking $VAR: true/false/empty value" - continue - fi - - echo "Masking $VAR" - echo "::add-mask::$VALUE" -done diff --git a/.github/scripts/load-secrets.ts b/.github/scripts/load-secrets.ts new file mode 100644 index 000000000..3da1aba85 --- /dev/null +++ b/.github/scripts/load-secrets.ts @@ -0,0 +1,96 @@ +import { $ } from "bun"; + +// UNLOAD_ENVIRONMENTS="prod,staging,dev" +const unloadEnvironments = process.env.UNLOAD_ENVIRONMENTS || ""; + +const excludedVars = [ + "PATH", + "HOME", + "PWD", + "SHELL", + "USER", + "DEBUG", + "LOG_LEVEL", + "CI", + "JAVA_HOME", +]; + +async function main() { + await $`git-crypt unlock`; + + const envs = unloadEnvironments + .split(",") + .map((e) => e.trim()) + .filter(Boolean); + + const loaded = new Map(); + + for (const env of envs) { + const envFile = Bun.file(`.env.${env}`); + if (await envFile.exists()) { + console.log(`Loading ${envFile.name}`); + + const content = await envFile.text(); + const lines = content.split("\n").filter((s) => s.length > 0); + + for (const line of lines) { + const trimmed = line.trim(); + if (!trimmed || trimmed.startsWith("#")) continue; + + const match = trimmed.split("=").filter((s) => s.length > 0); + if (match.length === 2) { + const [key, value] = match; + const cleanKey = key.trim(); + let cleanValue = value.trim(); + if ( + (cleanValue.startsWith('"') && cleanValue.endsWith('"')) || + (cleanValue.startsWith("'") && cleanValue.endsWith("'")) + ) { + cleanValue = cleanValue.slice(1, -1); + } + + if (!loaded.has(cleanKey)) { + loaded.set(cleanKey, cleanValue); + } + } + } + } else { + console.log(`Warning: ${envFile} not found`); + } + } + + const githubEnv = process.env.GITHUB_ENV; + if (!githubEnv) { + console.log("Warning: GITHUB_ENV not set, skipping variable export"); + return; + } + + const githubEnvFileWriter = Bun.file(githubEnv).writer(); + + for (const [varName, value] of loaded.entries()) { + githubEnvFileWriter.write(`${varName}=${value}\n`); + if (excludedVars.includes(varName)) { + console.log(`Not masking ${varName}: Excluded`); + continue; + } + + if (value === "true" || value === "false" || value === "") { + console.log(`Not masking ${varName}: true/false/empty value`); + continue; + } + + console.log(`Masking ${varName}`); + console.log(`::add-mask::${value}`); + } + + githubEnvFileWriter.flush(); +} + +main() + .then(() => { + process.exit(0); + }) + .catch((e) => { + console.error(e); + process.exit(1); + }); diff --git a/.github/scripts/run-frontend-tests.sh b/.github/scripts/run-frontend-tests.sh deleted file mode 100644 index 84723f160..000000000 --- a/.github/scripts/run-frontend-tests.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "$DIR/local-db.sh" -source "$DIR/run-backend-instance.sh" -trap 'backend_cleanup; db_cleanup' EXIT - -db_startup -backend_startup - -corepack enable pnpm -pnpm --dir js i --frozen-lockfile -pnpm --dir js run generate -pnpm --dir js run test diff --git a/.github/scripts/run-frontend-tests.ts b/.github/scripts/run-frontend-tests.ts new file mode 100644 index 000000000..fee5175f4 --- /dev/null +++ b/.github/scripts/run-frontend-tests.ts @@ -0,0 +1,27 @@ +import { $ } from "bun"; +import { db } from "./fn/run-local-db"; +import { backend } from "./fn/run-backend-instance"; + +async function main() { + try { + await db.start(); + await backend.start(); + + await $`corepack enable pnpm`; + await $`pnpm --dir js i --frozen-lockfile`; + await $`pnpm --dir js run generate`; + await $`pnpm --dir js run test`; + } finally { + await backend.end(); + await db.end(); + } +} + +main() + .then(() => { + process.exit(0); + }) + .catch((e) => { + console.error(e); + process.exit(1); + }); diff --git a/.github/workflows/ai-review.yml b/.github/workflows/ai-review.yml index 800956041..06bf9e4b3 100644 --- a/.github/workflows/ai-review.yml +++ b/.github/workflows/ai-review.yml @@ -103,6 +103,9 @@ jobs: pr_reviewer.enable_review_labels_effort: "false" pr_reviewer.final_update_message: "false" pr_description.publish_description_as_comment: "true" + pr_description.extra_instructions: | + Below is some additional context for the PR from the connected Notion task: + ${{ steps.notion_check.outputs.context }} pr_description.publish_description_as_comment_persistent: "false" pr_description.publish_labels: "false" pr_description.add_original_user_description: "false" @@ -112,8 +115,23 @@ jobs: pr_code_suggestions.enable_help_text: "false" pr_code_suggestions.enable_chat_text: "false" pr_code_suggestions.persistent_comment: "false" - pr_code_suggestions.max_history_len: "4" + pr_code_suggestions.max_history_len: "10" pr_code_suggestions.publish_output_no_suggestions: "true" + pr_code_suggestions.extra_instructions: | + Scrutinize this PR in the context of the following Notion task: + ${{ steps.notion_check.outputs.context }} + + Additional review guidelines: + - Verify that the implementation matches the acceptance criteria from the Notion task + - Check for proper error handling and edge cases + - Ensure code follows existing patterns and architecture in the codebase + - Look for potential security vulnerabilities or data validation issues + - Verify that database migrations (if any) are reversible and safe + - Check for proper logging and monitoring considerations + - Ensure API endpoints follow RESTful conventions and existing API patterns + - Verify that environment variables and secrets are handled securely + - Check for potential performance bottlenecks or N+1 query issues + - Ensure proper test coverage for critical paths pr_code_suggestions.apply_suggestions_checkbox: "true" pr_code_suggestions.suggestions_score_threshold: "0" pr_code_suggestions.new_score_mechanism: "true" diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 2f86294b3..1b54eca91 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -68,7 +68,6 @@ jobs: uses: actions/cache@v4 with: path: ~/.bun/install/cache - # Hash your lockfile to invalidate the cache when dependencies change key: ${{ runner.os }}-bun-${{ hashFiles('**/pnpm-lock.yaml') }} restore-keys: | ${{ runner.os }}-bun- @@ -133,8 +132,25 @@ jobs: GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} UNLOAD_ENVIRONMENTS: ci-app + - uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Cache Bun dependencies + uses: actions/cache@v4 + with: + path: ~/.bun/install/cache + key: ${{ runner.os }}-bun-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-bun- + + - name: Install deps + shell: bash + run: bun install --cwd .github/scripts --frozen-lockfile + - name: Run script - run: bash .github/scripts/run-frontend-tests.sh + shell: bash + run: bun .github/scripts/run-frontend-tests.ts testBuildImage: name: Build Test Docker Image From b0bc9b9f26a52b9c982fe10ae7c4617961dae878 Mon Sep 17 00:00:00 2001 From: Tahmid Ahmed Date: Fri, 16 Jan 2026 01:16:38 -0500 Subject: [PATCH 04/10] 641: blee bloo bleeeeeeee --- .../test/backend-pre-test/action.yml | 3 +- .../composite/test/backend-test/action.yml | 53 ++++++++++ .../composite/test/frontend-test/action.yml | 58 +++++++++++ .github/workflows/ci-cd.yml | 98 +------------------ 4 files changed, 114 insertions(+), 98 deletions(-) create mode 100644 .github/composite/test/backend-test/action.yml create mode 100644 .github/composite/test/frontend-test/action.yml diff --git a/.github/composite/test/backend-pre-test/action.yml b/.github/composite/test/backend-pre-test/action.yml index 61d2494bf..2cfa4c0b6 100644 --- a/.github/composite/test/backend-pre-test/action.yml +++ b/.github/composite/test/backend-pre-test/action.yml @@ -28,8 +28,7 @@ runs: uses: actions/cache@v4 with: path: ~/.bun/install/cache - # Hash your lockfile to invalidate the cache when dependencies change - key: ${{ runner.os }}-bun-${{ hashFiles('**/pnpm-lock.yaml') }} + key: ${{ runner.os }}-bun-${{ hashFiles('.github/scripts/bun.lock') }} restore-keys: | ${{ runner.os }}-bun- diff --git a/.github/composite/test/backend-test/action.yml b/.github/composite/test/backend-test/action.yml new file mode 100644 index 000000000..0e0a3bfc9 --- /dev/null +++ b/.github/composite/test/backend-test/action.yml @@ -0,0 +1,53 @@ +name: "Backend test" +description: "Run backend tests" +runs: + using: "composite" + steps: + - name: Disable man-db + uses: ./.github/composite/disable-mandb + + - name: Set up OpenJDK 25 + uses: actions/setup-java@v4 + with: + distribution: "temurin" + java-version: "25" + cache: "maven" + + - name: Set up bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Cache Bun dependencies + uses: actions/cache@v4 + with: + path: ~/.bun/install/cache + key: ${{ runner.os }}-bun-${{ hashFiles('.github/scripts/bun.lock') }} + restore-keys: | + ${{ runner.os }}-bun- + + - name: Install deps + shell: bash + run: bun install --cwd .github/scripts --frozen-lockfile + + - name: Load secrets + uses: ./.github/composite/load-secrets + with: + GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} + GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} + UNLOAD_ENVIRONMENTS: ci-app + + - name: Run script + shell: bash + run: bun .github/scripts/run-backend-tests.ts + + - name: Upload JaCoCo HTML report + uses: actions/upload-artifact@v4 + with: + name: jacoco-report + path: target/site/jacoco/ + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v5 + with: + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/composite/test/frontend-test/action.yml b/.github/composite/test/frontend-test/action.yml new file mode 100644 index 000000000..18367b177 --- /dev/null +++ b/.github/composite/test/frontend-test/action.yml @@ -0,0 +1,58 @@ +name: "Frontend Test" +description: "Run frontend tests" + +inputs: + GPG_PRIVATE_KEY: + description: "GPG Private Key" + required: true + GPG_PASSPHRASE: + description: "GPG Passphrase" + required: true + +runs: + using: "composite" + steps: + - name: Disable man-db + uses: ./.github/composite/disable-mandb + + - name: Set up pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + cache: true + cache_dependency_path: js/pnpm-lock.yaml + + - name: Set up OpenJDK 25 + uses: actions/setup-java@v4 + with: + distribution: "temurin" + java-version: "25" + cache: "maven" + + - name: Set up bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Cache Bun dependencies + uses: actions/cache@v4 + with: + path: ~/.bun/install/cache + key: ${{ runner.os }}-bun-${{ hashFiles('.github/scripts/bun.lock') }} + restore-keys: | + ${{ runner.os }}-bun- + + - name: Install deps + shell: bash + run: bun install --cwd .github/scripts --frozen-lockfile + + - name: Load secrets + uses: ./.github/composite/load-secrets + with: + GPG_PRIVATE_KEY: ${{ inputs.GPG_PRIVATE_KEY }} + GPG_PASSPHRASE: ${{ inputs.GPG_PASSPHRASE }} + UNLOAD_ENVIRONMENTS: ci-app + + - name: Run script + shell: bash + run: bun .github/scripts/run-frontend-tests.ts diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 1b54eca91..13e897cc6 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -37,59 +37,11 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - - name: Disable man-db - uses: ./.github/composite/disable-mandb - - - name: Set up OpenJDK 25 - uses: actions/setup-java@v4 - with: - distribution: "temurin" - java-version: "25" - cache: "maven" - - - name: Verify Java version - run: | - java -version - javac -version - echo "JAVA_HOME=$JAVA_HOME" - - name: Load secrets - uses: ./.github/composite/load-secrets + uses: ./.github/composite/test/backend-test with: GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} - UNLOAD_ENVIRONMENTS: ci,ci-app - - - uses: oven-sh/setup-bun@v2 - with: - bun-version: latest - - - name: Cache Bun dependencies - uses: actions/cache@v4 - with: - path: ~/.bun/install/cache - key: ${{ runner.os }}-bun-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-bun- - - - name: Install deps - shell: bash - run: bun install --cwd .github/scripts --frozen-lockfile - - - name: Run script - shell: bash - run: bun .github/scripts/run-backend-tests.ts - - - name: Upload JaCoCo HTML report - uses: actions/upload-artifact@v4 - with: - name: jacoco-report - path: target/site/jacoco/ - - - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v5 - with: - token: ${{ secrets.CODECOV_TOKEN }} frontendTests: name: Frontend Tests @@ -100,57 +52,11 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - - name: Disable man-db - uses: ./.github/composite/disable-mandb - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: 20 - - - name: Set up OpenJDK 25 - uses: actions/setup-java@v4 - with: - distribution: "temurin" - java-version: "25" - cache: "maven" - - - name: Verify Java version - run: | - java -version - javac -version - echo "JAVA_HOME=$JAVA_HOME" - - - name: Fix a bug with corepack by installing corepack globally - run: npm i -g corepack@latest - working-directory: js - - name: Load secrets - uses: ./.github/composite/load-secrets + uses: ./.github/composite/test/frontend-test with: GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} - UNLOAD_ENVIRONMENTS: ci-app - - - uses: oven-sh/setup-bun@v2 - with: - bun-version: latest - - - name: Cache Bun dependencies - uses: actions/cache@v4 - with: - path: ~/.bun/install/cache - key: ${{ runner.os }}-bun-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-bun- - - - name: Install deps - shell: bash - run: bun install --cwd .github/scripts --frozen-lockfile - - - name: Run script - shell: bash - run: bun .github/scripts/run-frontend-tests.ts testBuildImage: name: Build Test Docker Image From 5cbc96cc8161837835f4916f136c215b48c0d712 Mon Sep 17 00:00:00 2001 From: Tahmid Ahmed Date: Fri, 16 Jan 2026 01:21:08 -0500 Subject: [PATCH 05/10] 641: blee bloo bleeeeeeee wefklfkenfwekjnfg --- .github/composite/test/frontend-test/action.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/composite/test/frontend-test/action.yml b/.github/composite/test/frontend-test/action.yml index 18367b177..5ba7a2574 100644 --- a/.github/composite/test/frontend-test/action.yml +++ b/.github/composite/test/frontend-test/action.yml @@ -16,11 +16,12 @@ runs: uses: ./.github/composite/disable-mandb - name: Set up pnpm - uses: pnpm/action-setup@v4 + uses: pnpm/action-setup@master with: version: 10 cache: true cache_dependency_path: js/pnpm-lock.yaml + package_json_file: js/package.json - name: Set up OpenJDK 25 uses: actions/setup-java@v4 From c2fe246ac06edfe0bd8b441b87c46f37731a047e Mon Sep 17 00:00:00 2001 From: Tahmid Ahmed Date: Fri, 16 Jan 2026 01:23:29 -0500 Subject: [PATCH 06/10] 641: blee --- .github/composite/test/frontend-test/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/composite/test/frontend-test/action.yml b/.github/composite/test/frontend-test/action.yml index 5ba7a2574..b2a1bb37d 100644 --- a/.github/composite/test/frontend-test/action.yml +++ b/.github/composite/test/frontend-test/action.yml @@ -18,7 +18,7 @@ runs: - name: Set up pnpm uses: pnpm/action-setup@master with: - version: 10 + version: 10.24.0 cache: true cache_dependency_path: js/pnpm-lock.yaml package_json_file: js/package.json From 8882bfb9f075e63e1525ac77ef48d7ddb56bf340 Mon Sep 17 00:00:00 2001 From: Tahmid Ahmed Date: Fri, 16 Jan 2026 01:35:10 -0500 Subject: [PATCH 07/10] 641: lsdfnsdgvlndefblnerb --- .github/composite/test/backend-test/action.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/composite/test/backend-test/action.yml b/.github/composite/test/backend-test/action.yml index 0e0a3bfc9..a507b5c25 100644 --- a/.github/composite/test/backend-test/action.yml +++ b/.github/composite/test/backend-test/action.yml @@ -1,5 +1,14 @@ name: "Backend test" description: "Run backend tests" + +inputs: + GPG_PRIVATE_KEY: + description: "GPG Private Key" + required: true + GPG_PASSPHRASE: + description: "GPG Passphrase" + required: true + runs: using: "composite" steps: From b8d4c40f7d68f6bb0cc710fd58febd54327fac33 Mon Sep 17 00:00:00 2001 From: Tahmid Ahmed Date: Fri, 16 Jan 2026 02:19:58 -0500 Subject: [PATCH 08/10] 641: neenurrr --- .github/composite/build-image/action.yml | 77 +++++++++++++++ .../composite/test/backend-test/action.yml | 6 ++ .github/scripts/build-image.ts | 95 +++++++++++++++++++ .github/workflows/ci-cd.yml | 61 ++---------- 4 files changed, 186 insertions(+), 53 deletions(-) create mode 100644 .github/composite/build-image/action.yml create mode 100644 .github/scripts/build-image.ts diff --git a/.github/composite/build-image/action.yml b/.github/composite/build-image/action.yml new file mode 100644 index 000000000..cf82223c3 --- /dev/null +++ b/.github/composite/build-image/action.yml @@ -0,0 +1,77 @@ +name: "Build & Upload Docker Image" +description: "Build & (optionally) upload Docker Image to Docker Registry" + +inputs: + GPG_PRIVATE_KEY: + description: "GPG Private Key" + required: true + GPG_PASSPHRASE: + description: "GPG Passphrase" + required: true + DOCKER_UPLOAD: + description: "Boolean indicating whether the image should be uploaded to Docker registry or not." + required: false + default: true + TAG_PREFIX: + description: "Docker tags prefix" + required: false + SERVER_PROFILES: + description: "Profile(s) to apply to Codebloom instance." + required: false + default: prod + +runs: + using: "composite" + steps: + - name: Disable man-db + uses: ./.github/composite/disable-mandb + + - name: Set up pnpm + uses: pnpm/action-setup@master + with: + version: 10.24.0 + cache: true + cache_dependency_path: js/pnpm-lock.yaml + package_json_file: js/package.json + + - name: Set up OpenJDK 25 + uses: actions/setup-java@v4 + with: + distribution: "temurin" + java-version: "25" + cache: "maven" + + - name: Set up bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Cache Bun dependencies + uses: actions/cache@v4 + with: + path: ~/.bun/install/cache + key: ${{ runner.os }}-bun-${{ hashFiles('.github/scripts/bun.lock') }} + restore-keys: | + ${{ runner.os }}-bun- + + - name: Install deps + shell: bash + run: bun install --cwd .github/scripts --frozen-lockfile + + - name: Load secrets + uses: ./.github/composite/load-secrets + with: + GPG_PRIVATE_KEY: ${{ inputs.GPG_PRIVATE_KEY }} + GPG_PASSPHRASE: ${{ inputs.GPG_PASSPHRASE }} + UNLOAD_ENVIRONMENTS: ci,ci-app + + - name: Expose GitHub Runtime + uses: crazy-max/ghaction-github-runtime@v3 + + - name: Run script + shell: bash + run: bun .github/scripts/build-image.ts + env: + DOCKER_UPLOAD: ${{ inputs.DOCKER_UPLOAD }} + TAG_PREFIX: ${{ inputs.TAG_PREFIX }} + SERVER_PROFILES: ${{ inputs.SERVER_PROFILES }} diff --git a/.github/composite/test/backend-test/action.yml b/.github/composite/test/backend-test/action.yml index a507b5c25..a240ac154 100644 --- a/.github/composite/test/backend-test/action.yml +++ b/.github/composite/test/backend-test/action.yml @@ -8,6 +8,10 @@ inputs: GPG_PASSPHRASE: description: "GPG Passphrase" required: true + UPLOAD_TEST_COV: + description: "Boolean indicating whether tests should be uploaded to Codecov or not." + required: false + default: true runs: using: "composite" @@ -52,11 +56,13 @@ runs: - name: Upload JaCoCo HTML report uses: actions/upload-artifact@v4 + if: ${{ inputs.UPLOAD_TEST_COV == true }} with: name: jacoco-report path: target/site/jacoco/ - name: Upload coverage reports to Codecov uses: codecov/codecov-action@v5 + if: ${{ inputs.UPLOAD_TEST_COV == true }} with: token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/scripts/build-image.ts b/.github/scripts/build-image.ts new file mode 100644 index 000000000..742f093bd --- /dev/null +++ b/.github/scripts/build-image.ts @@ -0,0 +1,95 @@ +import { $ } from "bun"; +import { db } from "./fn/run-local-db"; +import { backend } from "./fn/run-backend-instance"; + +process.env.TZ = "America/New_York"; + +const tagPrefix = process.env.TAG_PREFIX || ""; +const shouldDockerUpload = Boolean(process.env.DOCKER_UPLOAD) || false; +const serverProfiles = process.env.SERVER_PROFILES || "prod"; + +const dockerHubPat = process.env.DOCKER_HUB_PAT; +if (!dockerHubPat) { + throw new Error("DOCKER_HUB_PAT is required."); +} + +async function main() { + try { + await db.start(); + await backend.start(); + + await $`corepack enable pnpm`; + await $`pnpm --dir js i -D --frozen-lockfile`; + await $`pnpm --dir js run generate`; + + // copy old tz format from build-image.sh + const timestamp = new Date() + .toLocaleString("en-US", { + timeZone: process.env.TZ, + year: "numeric", + month: "2-digit", + day: "2-digit", + hour: "2-digit", + minute: "2-digit", + second: "2-digit", + hour12: false, + }) + .replace(/(\d+)\/(\d+)\/(\d+),\s(\d+):(\d+):(\d+)/, "$3.$1.$2-$4.$5.$6"); + + const gitSha = (await $`git rev-parse --short HEAD`.text()).trim(); + + const tags = [ + `tahminator/codebloom:${tagPrefix}latest`, + `tahminator/codebloom:${tagPrefix}${timestamp}`, + `tahminator/codebloom:${tagPrefix}${gitSha}`, + ]; + + console.log("Building image with following tags:"); + tags.forEach((tag) => console.log(tag)); + + if (dockerHubPat) { + console.log("DOCKER_HUB_PAT found"); + } else { + console.log("DOCKER_HUB_PAT missing or empty"); + } + + await $`echo ${dockerHubPat} | docker login -u tahminator --password-stdin`; + + try { + await $`docker buildx create --use --name codebloom-builder`; + } catch { + await $`docker buildx use codebloom-builder`; + } + + const buildMode = shouldDockerUpload ? "--push" : "--load"; + + const viteStagingArg = + serverProfiles === "stg" ? "--build-arg VITE_STAGING=true" : ""; + + const tagArgs = tags.map((tag) => `--tag ${tag}`).join(" "); + + await $`docker buildx build ${buildMode} \ + --file infra/Dockerfile \ + --build-arg SERVER_PROFILES=${serverProfiles} \ + --build-arg COMMIT_SHA=${gitSha} \ + --cache-from=type=gha \ + --cache-to=type=gha,mode=max \ + ${viteStagingArg} \ + ${tagArgs} \ + .`.quiet(); + + console.log("Image pushed successfully."); + } finally { + await backend.end(); + await db.end(); + } +} + +main() + .then(() => { + process.exit(0); + }) + .catch((e) => { + console.error(e); + process.exit(1); + }); diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 13e897cc6..44e73da23 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -25,7 +25,7 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - - name: Run backend pre test + - name: Run workflow uses: ./.github/composite/test/backend-pre-test backendTests: @@ -37,7 +37,7 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - - name: Load secrets + - name: Run workflow uses: ./.github/composite/test/backend-test with: GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} @@ -52,7 +52,7 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - - name: Load secrets + - name: Run workflow uses: ./.github/composite/test/frontend-test with: GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} @@ -69,35 +69,12 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - - name: Disable man-db - uses: ./.github/composite/disable-mandb - - - name: Set up OpenJDK 25 - uses: actions/setup-java@v4 - with: - distribution: "temurin" - java-version: "25" - cache: "maven" - - - name: Verify Java version - run: | - java -version - javac -version - echo "JAVA_HOME=$JAVA_HOME" - - - name: Expose GitHub Runtime - uses: crazy-max/ghaction-github-runtime@v3 - - - name: Load secrets - uses: ./.github/composite/load-secrets + - name: Run workflow + uses: ./.github/composite/build-image with: GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} - UNLOAD_ENVIRONMENTS: ci,ci-app - - - name: Run script - run: bash .github/scripts/build-image.sh - env: + TAG_PREFIX: test- DOCKER_UPLOAD: false validateDBSchema: @@ -146,34 +123,12 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - - name: Disable man-db - uses: ./.github/composite/disable-mandb - - - name: Set up OpenJDK 25 - uses: actions/setup-java@v4 - with: - distribution: "temurin" - java-version: "25" - cache: "maven" - - - name: Verify Java version - run: | - java -version - javac -version - echo "JAVA_HOME=$JAVA_HOME" - - - name: Load secrets - uses: ./.github/composite/load-secrets + - name: Run workflow + uses: ./.github/composite/build-image with: GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} - UNLOAD_ENVIRONMENTS: ci,ci-app - - - name: Expose GitHub Runtime - uses: crazy-max/ghaction-github-runtime@v3 - - name: Run script - run: bash .github/scripts/build-image.sh redeploy: name: Redeploy on DigitalOcean From 8d61d5ca64cb150f39886c74c4d7bc668912dcc1 Mon Sep 17 00:00:00 2001 From: Tahmid Ahmed Date: Fri, 16 Jan 2026 02:26:53 -0500 Subject: [PATCH 09/10] 641: attempt --- .github/scripts/build-image.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/scripts/build-image.ts b/.github/scripts/build-image.ts index 742f093bd..7918c768a 100644 --- a/.github/scripts/build-image.ts +++ b/.github/scripts/build-image.ts @@ -64,9 +64,9 @@ async function main() { const buildMode = shouldDockerUpload ? "--push" : "--load"; const viteStagingArg = - serverProfiles === "stg" ? "--build-arg VITE_STAGING=true" : ""; + serverProfiles === "stg" ? ["--build-arg", "VITE_STAGING=true"] : []; - const tagArgs = tags.map((tag) => `--tag ${tag}`).join(" "); + const tagArgs = tags.flatMap((tag) => ["--tag", tag]); await $`docker buildx build ${buildMode} \ --file infra/Dockerfile \ From 1091b04e8feec61e57f346bdd2330eb31f6f3421 Mon Sep 17 00:00:00 2001 From: Tahmid Ahmed Date: Fri, 16 Jan 2026 02:38:11 -0500 Subject: [PATCH 10/10] 641: try to fix messed up leetcodeclienttest --- .../codebloom/scheduled/auth/LeetcodeAuthStealer.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/org/patinanetwork/codebloom/scheduled/auth/LeetcodeAuthStealer.java b/src/main/java/org/patinanetwork/codebloom/scheduled/auth/LeetcodeAuthStealer.java index 0a0178936..6ecb3a20b 100644 --- a/src/main/java/org/patinanetwork/codebloom/scheduled/auth/LeetcodeAuthStealer.java +++ b/src/main/java/org/patinanetwork/codebloom/scheduled/auth/LeetcodeAuthStealer.java @@ -163,7 +163,6 @@ public String getCsrf() { } String stealCookieImpl() { - LOCK.writeLock().lock(); try (Playwright playwright = Playwright.create(); Browser browser = playwright .firefox() @@ -273,10 +272,7 @@ String stealCookieImpl() { } else { log.info("Should be authenticated but not authenticated."); } - } finally { - LOCK.writeLock().unlock(); } - return null; } }