From 73683381e6ff5fa8bc4fafeb1bdaf8bb4a8fe178 Mon Sep 17 00:00:00 2001 From: Nancy Huang <205217630+naanci@users.noreply.github.com> Date: Sat, 15 Aug 2026 17:29:53 -0400 Subject: [PATCH 1/8] TAN-36: changes made to read CI secrets from process.env instead of decrypted .env.ci files TAN-36: error call fix TAN-36: changed secret call in composite folder TAN-36: fix composite actions calling toJSON(secrets) directly TAN-36: restore GPG secret forwarding for git-crypt --- .github/composite/build-image/action.yml | 8 ++++++-- .../build-image/internal/standup-bot/action.yml | 8 ++++++-- .github/composite/deploy-standup-bot/action.yaml | 8 ++++++-- .github/composite/notion-checks/action.yml | 8 ++++++-- .github/composite/redeploy/action.yml | 8 ++++++-- .../redeploy/internal/standup-bot/action.yml | 8 ++++++-- .github/composite/setup-ci/action.yml | 3 +++ .github/composite/test/backend-test/action.yml | 8 ++++++-- .github/composite/test/frontend-pre-test/action.yml | 8 ++++++-- .github/composite/test/frontend-test/action.yml | 8 ++++++-- .github/composite/validate-db/action.yml | 8 ++++++-- .github/scripts/auto-approval/index.ts | 5 ++--- .github/scripts/build-image/index.ts | 5 ++--- .github/scripts/build-image/internal/standup-bot.ts | 6 ++---- .github/scripts/deploy/index.ts | 7 +++---- .github/scripts/notion/index.ts | 7 ++----- .../scripts/redeploy/internal/standup-bot/index.ts | 6 ++---- .github/scripts/test/run-backend-tests.ts | 5 ++--- .github/scripts/test/run-e2e-tests.ts | 6 ++---- .github/scripts/test/run-frontend-tests.ts | 5 ++--- .github/workflows/ai-command.yml | 2 ++ .github/workflows/ai-review.yml | 3 +++ .github/workflows/ci-cd.yml | 11 +++++++++-- .github/workflows/copy-command.yml | 1 + .github/workflows/deploy-command.yml | 6 ++++++ .github/workflows/e2e.yml | 1 + .github/workflows/help-command.yml | 1 + .github/workflows/pr-verifications.yml | 3 +-- .github/workflows/slash.yml | 2 ++ 29 files changed, 108 insertions(+), 57 deletions(-) diff --git a/.github/composite/build-image/action.yml b/.github/composite/build-image/action.yml index 52052de53..ad72c49d1 100644 --- a/.github/composite/build-image/action.yml +++ b/.github/composite/build-image/action.yml @@ -9,11 +9,14 @@ inputs: ENVIRONMENT: description: "'staging' or 'production'" required: true + SECRETS: + description: "Pass toJSON(secrets) from the calling workflow to expose all secrets as env vars." + required: false GPG_PRIVATE_KEY: - description: "GPG private key for decrypting secrets." + description: "GPG Private Key" required: false GPG_PASSPHRASE: - description: "GPG passphrase for decrypting secrets." + description: "GPG Passphrase" required: false outputs: @@ -27,6 +30,7 @@ runs: - name: Setup CI uses: ./.github/composite/setup-ci with: + SECRETS: ${{ inputs.SECRETS }} GPG_PRIVATE_KEY: ${{ inputs.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ inputs.GPG_PASSPHRASE }} diff --git a/.github/composite/build-image/internal/standup-bot/action.yml b/.github/composite/build-image/internal/standup-bot/action.yml index 4232fa653..7551f5eae 100644 --- a/.github/composite/build-image/internal/standup-bot/action.yml +++ b/.github/composite/build-image/internal/standup-bot/action.yml @@ -2,12 +2,15 @@ name: "Build & Upload Docker Image for codebloom-standup-bot" description: "Build & (optionally) upload Docker Image to Docker Registry" inputs: + SECRETS: + description: "Pass toJSON(secrets) from the calling workflow to expose all secrets as env vars." + required: false GPG_PRIVATE_KEY: description: "GPG Private Key" - required: true + required: false GPG_PASSPHRASE: description: "GPG Passphrase" - required: true + required: false DOCKER_UPLOAD: description: "Boolean indicating whether the image should be uploaded to Docker registry or not." required: false @@ -24,6 +27,7 @@ runs: - name: Setup CI uses: ./.github/composite/setup-ci with: + SECRETS: ${{ inputs.SECRETS }} GPG_PRIVATE_KEY: ${{ inputs.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ inputs.GPG_PASSPHRASE }} diff --git a/.github/composite/deploy-standup-bot/action.yaml b/.github/composite/deploy-standup-bot/action.yaml index ea18f44a2..30a73b430 100644 --- a/.github/composite/deploy-standup-bot/action.yaml +++ b/.github/composite/deploy-standup-bot/action.yaml @@ -5,12 +5,15 @@ inputs: ENVIRONMENT: description: "'staging' or 'production'" required: true + SECRETS: + description: "Pass toJSON(secrets) from the calling workflow to expose all secrets as env vars." + required: false GPG_PRIVATE_KEY: description: "GPG Private Key" - required: true + required: false GPG_PASSPHRASE: description: "GPG Passphrase" - required: true + required: false runs: using: composite @@ -19,6 +22,7 @@ runs: id: build-image uses: ./.github/composite/build-image/internal/standup-bot with: + SECRETS: ${{ inputs.SECRETS }} GPG_PRIVATE_KEY: ${{ inputs.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ inputs.GPG_PASSPHRASE }} diff --git a/.github/composite/notion-checks/action.yml b/.github/composite/notion-checks/action.yml index 2d506d33c..8198c37de 100644 --- a/.github/composite/notion-checks/action.yml +++ b/.github/composite/notion-checks/action.yml @@ -5,12 +5,15 @@ inputs: PR_ID: description: "PR ID" required: true + SECRETS: + description: "Pass toJSON(secrets) from the calling workflow to expose all secrets as env vars." + required: false GPG_PRIVATE_KEY: description: "GPG Private Key" - required: true + required: false GPG_PASSPHRASE: description: "GPG Passphrase" - required: true + required: false GET_GHA_OUTPUT: description: "If set to `true`, will output an object with data that can be interfaced in GitHub Actions." required: false @@ -31,6 +34,7 @@ runs: - name: Setup CI uses: ./.github/composite/setup-ci with: + SECRETS: ${{ inputs.SECRETS }} GPG_PRIVATE_KEY: ${{ inputs.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ inputs.GPG_PASSPHRASE }} diff --git a/.github/composite/redeploy/action.yml b/.github/composite/redeploy/action.yml index 3076545a5..f65b14983 100644 --- a/.github/composite/redeploy/action.yml +++ b/.github/composite/redeploy/action.yml @@ -2,12 +2,15 @@ name: "Re-Deploy to DigitalOcean" description: "Trigger a deployment to DigitalOcean and migrate the associated database." inputs: + SECRETS: + description: "Pass toJSON(secrets) from the calling workflow to expose all secrets as env vars." + required: false GPG_PRIVATE_KEY: description: "GPG Private Key" - required: true + required: false GPG_PASSPHRASE: description: "GPG Passphrase" - required: true + required: false ENVIRONMENT: description: '"staging" or "production"' required: false @@ -22,6 +25,7 @@ runs: - name: Setup CI uses: ./.github/composite/setup-ci with: + SECRETS: ${{ inputs.SECRETS }} GPG_PRIVATE_KEY: ${{ inputs.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ inputs.GPG_PASSPHRASE }} diff --git a/.github/composite/redeploy/internal/standup-bot/action.yml b/.github/composite/redeploy/internal/standup-bot/action.yml index 7eae77290..254accb68 100644 --- a/.github/composite/redeploy/internal/standup-bot/action.yml +++ b/.github/composite/redeploy/internal/standup-bot/action.yml @@ -2,12 +2,15 @@ name: "Re-Deploy codebloom-standup-bot to Coolify" description: "Trigger a deployment of the standup bot to Coolify." inputs: + SECRETS: + description: "Pass toJSON(secrets) from the calling workflow to expose all secrets as env vars." + required: false GPG_PRIVATE_KEY: description: "GPG Private Key" - required: true + required: false GPG_PASSPHRASE: description: "GPG Passphrase" - required: true + required: false runs: using: "composite" @@ -15,6 +18,7 @@ runs: - name: Setup CI uses: ./.github/composite/setup-ci with: + SECRETS: ${{ inputs.SECRETS }} GPG_PRIVATE_KEY: ${{ inputs.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ inputs.GPG_PASSPHRASE }} diff --git a/.github/composite/setup-ci/action.yml b/.github/composite/setup-ci/action.yml index 6e236f41d..92a34199d 100644 --- a/.github/composite/setup-ci/action.yml +++ b/.github/composite/setup-ci/action.yml @@ -12,6 +12,9 @@ inputs: description: "GitHub token used to send message" required: false default: ${{ github.token }} + SECRETS: + description: "Pass toJSON(secrets) from the calling workflow to expose all secrets as env vars." + required: false runs: using: "composite" diff --git a/.github/composite/test/backend-test/action.yml b/.github/composite/test/backend-test/action.yml index 79d26f443..d31133a10 100644 --- a/.github/composite/test/backend-test/action.yml +++ b/.github/composite/test/backend-test/action.yml @@ -2,12 +2,15 @@ name: "Backend test" description: "Run backend tests" inputs: + SECRETS: + description: "Pass toJSON(secrets) from the calling workflow to expose all secrets as env vars." + required: false GPG_PRIVATE_KEY: description: "GPG Private Key" - required: true + required: false GPG_PASSPHRASE: description: "GPG Passphrase" - required: true + required: false UPLOAD_TEST_COV: description: "Boolean indicating whether tests should be uploaded to our code coverage provider or not." required: false @@ -19,6 +22,7 @@ runs: - name: Setup CI uses: ./.github/composite/setup-ci with: + SECRETS: ${{ inputs.SECRETS }} GPG_PRIVATE_KEY: ${{ inputs.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ inputs.GPG_PASSPHRASE }} diff --git a/.github/composite/test/frontend-pre-test/action.yml b/.github/composite/test/frontend-pre-test/action.yml index 369a62619..b8fd0434b 100644 --- a/.github/composite/test/frontend-pre-test/action.yml +++ b/.github/composite/test/frontend-pre-test/action.yml @@ -2,12 +2,15 @@ name: "Frontend Pre Test" description: "Run frontend linter & formatter checks + attempt to compile (NO TESTS)" inputs: + SECRETS: + description: "Pass toJSON(secrets) from the calling workflow to expose all secrets as env vars." + required: false GPG_PRIVATE_KEY: description: "GPG Private Key" - required: true + required: false GPG_PASSPHRASE: description: "GPG Passphrase" - required: true + required: false runs: using: "composite" @@ -15,6 +18,7 @@ runs: - name: Setup CI uses: ./.github/composite/setup-ci with: + SECRETS: ${{ inputs.SECRETS }} GPG_PRIVATE_KEY: ${{ inputs.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ inputs.GPG_PASSPHRASE }} diff --git a/.github/composite/test/frontend-test/action.yml b/.github/composite/test/frontend-test/action.yml index 61bf09067..f53f9c421 100644 --- a/.github/composite/test/frontend-test/action.yml +++ b/.github/composite/test/frontend-test/action.yml @@ -2,12 +2,15 @@ name: "Frontend Test" description: "Run frontend tests" inputs: + SECRETS: + description: "Pass toJSON(secrets) from the calling workflow to expose all secrets as env vars." + required: false GPG_PRIVATE_KEY: description: "GPG Private Key" - required: true + required: false GPG_PASSPHRASE: description: "GPG Passphrase" - required: true + required: false UPLOAD_TEST_COV: description: "Boolean indicating whether tests should be uploaded to our code coverage or not." required: false @@ -19,6 +22,7 @@ runs: - name: Setup CI uses: ./.github/composite/setup-ci with: + SECRETS: ${{ inputs.SECRETS }} GPG_PRIVATE_KEY: ${{ inputs.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ inputs.GPG_PASSPHRASE }} diff --git a/.github/composite/validate-db/action.yml b/.github/composite/validate-db/action.yml index 70fb3a18a..5470098a9 100644 --- a/.github/composite/validate-db/action.yml +++ b/.github/composite/validate-db/action.yml @@ -2,12 +2,15 @@ name: "Validate DB" description: "Validate the current db/ folder at a current commit against a database" inputs: + SECRETS: + description: "Pass toJSON(secrets) from the calling workflow to expose all secrets as env vars." + required: false GPG_PRIVATE_KEY: description: "GPG Private Key" - required: true + required: false GPG_PASSPHRASE: description: "GPG Passphrase" - required: true + required: false ENVIRONMENT: description: '"staging" or "production"' required: false @@ -22,6 +25,7 @@ runs: - name: Setup CI uses: ./.github/composite/setup-ci with: + SECRETS: ${{ inputs.SECRETS }} GPG_PRIVATE_KEY: ${{ inputs.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ inputs.GPG_PASSPHRASE }} diff --git a/.github/scripts/auto-approval/index.ts b/.github/scripts/auto-approval/index.ts index 675b39418..5a28d5089 100644 --- a/.github/scripts/auto-approval/index.ts +++ b/.github/scripts/auto-approval/index.ts @@ -1,6 +1,5 @@ import type { RestEndpointMethodTypes } from "@octokit/rest"; -import { getEnvVariables } from "load-secrets/env/load"; import { checkNotionPrAndGetTask } from "notion/pr"; import { getNotionClient } from "notion/sdk"; import { Octokit } from "octokit"; @@ -34,7 +33,7 @@ const { .strict() .parse(); -function parseCiEnv(ciEnv: Record) { +function parseCiEnv(ciEnv: Record) { const notionDbId = (() => { const v = ciEnv["NOTION_TASK_DB_ID"]; if (!v) { @@ -57,7 +56,7 @@ function parseCiEnv(ciEnv: Record) { }; } -const { notionDbId, notionSecret } = parseCiEnv(await getEnvVariables(["ci"])); +const { notionDbId, notionSecret } = parseCiEnv(process.env); const notionClient = getNotionClient(notionSecret); const taskAndPr = await checkNotionPrAndGetTask(notionClient, prId, notionDbId); diff --git a/.github/scripts/build-image/index.ts b/.github/scripts/build-image/index.ts index 458157e5f..d249d70ae 100644 --- a/.github/scripts/build-image/index.ts +++ b/.github/scripts/build-image/index.ts @@ -40,8 +40,7 @@ const serverProfiles = environment === "staging" ? "stg" : "prod"; async function main() { try { - const ciEnv = await getEnvVariables(["ci"]); - const { dockerHubPat } = parseCiEnv(ciEnv); + const { dockerHubPat } = parseCiEnv(process.env); const localDbEnv = await db.start(); const ciAppEnv = await getEnvVariables(["ci-app"]); @@ -126,7 +125,7 @@ async function main() { } } -function parseCiEnv(ciEnv: Record) { +function parseCiEnv(ciEnv: Record) { const dockerHubPat = (() => { const v = ciEnv["DOCKER_HUB_PAT"]; if (!v) { diff --git a/.github/scripts/build-image/internal/standup-bot.ts b/.github/scripts/build-image/internal/standup-bot.ts index 6b3405133..44227c1d6 100644 --- a/.github/scripts/build-image/internal/standup-bot.ts +++ b/.github/scripts/build-image/internal/standup-bot.ts @@ -1,5 +1,4 @@ import { $ } from "bun"; -import { getEnvVariables } from "load-secrets/env/load"; import yargs from "yargs"; import { hideBin } from "yargs/helpers"; @@ -27,8 +26,7 @@ const { dockerUpload, getGhaOutput, githubOutputFile } = await yargs( .parse(); async function main() { - const ciEnv = await getEnvVariables(["ci"]); - const { dockerHubPat } = parseCiEnv(ciEnv); + const { dockerHubPat } = parseCiEnv(process.env); // copy old tz format from build-image.sh const timestamp = new Date() @@ -94,7 +92,7 @@ async function main() { } } -function parseCiEnv(ciEnv: Record) { +function parseCiEnv(ciEnv: Record) { const dockerHubPat = (() => { const v = ciEnv["DOCKER_HUB_PAT"]; if (!v) { diff --git a/.github/scripts/deploy/index.ts b/.github/scripts/deploy/index.ts index 15de5e56d..d49ca1918 100644 --- a/.github/scripts/deploy/index.ts +++ b/.github/scripts/deploy/index.ts @@ -1,7 +1,7 @@ import type { Environment } from "@tahminator/pipeline"; import type { Type } from "types"; -import { GitHubClient, Utils } from "@tahminator/pipeline"; +import { GitHubClient } from "@tahminator/pipeline"; import yargs from "yargs"; import { hideBin } from "yargs/helpers"; @@ -24,8 +24,7 @@ const { environment, newTagVersion, type } = await yargs(hideBin(process.argv)) .parse(); async function main() { - const ciEnv = await Utils.getEnvVariables(["ci"]); - const { ghPat } = parseCiEnv(ciEnv); + const { ghPat } = parseCiEnv(process.env); const ghClient = new GitHubClient(ghPat); if (type === "web") { @@ -51,7 +50,7 @@ async function main() { } } -function parseCiEnv(ciEnv: Record) { +function parseCiEnv(ciEnv: Record) { const ghPat = (() => { const v = ciEnv["GH_PAT"]; if (!v) { diff --git a/.github/scripts/notion/index.ts b/.github/scripts/notion/index.ts index 3587b25c3..ce37f70eb 100644 --- a/.github/scripts/notion/index.ts +++ b/.github/scripts/notion/index.ts @@ -1,4 +1,3 @@ -import { getEnvVariables } from "load-secrets/env/load"; import { _checkCommits } from "notion/commits"; import { checkNotionPrAndGetTask } from "notion/pr"; import { _validateNotionTask } from "notion/pr/validate-ticket"; @@ -42,9 +41,7 @@ const { async function main() { console.log(`GET_GHA_OUTPUT=${getGhaOutput}`); - const { notionDbId, notionSecret } = parseCiEnv( - await getEnvVariables(["ci"]), - ); + const { notionDbId, notionSecret } = parseCiEnv(process.env); const client = getNotionClient(notionSecret); const { taskId, taskContent, task, taskPublicUrl } = @@ -72,7 +69,7 @@ async function main() { } } -function parseCiEnv(ciEnv: Record) { +function parseCiEnv(ciEnv: Record) { const notionDbId = (() => { const v = ciEnv["NOTION_TASK_DB_ID"]; if (!v) { diff --git a/.github/scripts/redeploy/internal/standup-bot/index.ts b/.github/scripts/redeploy/internal/standup-bot/index.ts index 12274da87..d25d1b356 100644 --- a/.github/scripts/redeploy/internal/standup-bot/index.ts +++ b/.github/scripts/redeploy/internal/standup-bot/index.ts @@ -11,9 +11,7 @@ async function main() { // await $`git-crypt unlock`; const { bearerAuth, serverUrl, projectUuid, serverUuid } = parseCiEnv( - await getEnvVariables(["ci"], { - baseDir: "internal", - }), + process.env, ); const client = await initClient(bearerAuth, serverUrl); @@ -74,7 +72,7 @@ async function main() { } } -function parseCiEnv(ciEnv: Record) { +function parseCiEnv(ciEnv: Record) { const bearerAuth = (() => { const v = ciEnv["COOLIFY_BEARER_AUTH"]; if (!v) { diff --git a/.github/scripts/test/run-backend-tests.ts b/.github/scripts/test/run-backend-tests.ts index 4c078b7d6..7548c88a8 100644 --- a/.github/scripts/test/run-backend-tests.ts +++ b/.github/scripts/test/run-backend-tests.ts @@ -44,8 +44,7 @@ async function main() { await $$`./mvnw clean verify -Dspring.profiles.active=ci`; if (shouldUploadCoverage) { - const ciEnv = await getEnvVariables(["ci"]); - const { sonarToken } = parseCiEnv(ciEnv); + const { sonarToken } = parseCiEnv(process.env); await uploadBackendTests(sonarToken); } } finally { @@ -55,7 +54,7 @@ async function main() { } } -function parseCiEnv(ciEnv: Record) { +function parseCiEnv(ciEnv: Record) { const sonarToken = (() => { const v = ciEnv["SONAR_TOKEN"]; if (!v) { diff --git a/.github/scripts/test/run-e2e-tests.ts b/.github/scripts/test/run-e2e-tests.ts index 6f73b39d5..fa9b63552 100644 --- a/.github/scripts/test/run-e2e-tests.ts +++ b/.github/scripts/test/run-e2e-tests.ts @@ -20,9 +20,7 @@ const { actionUrl, skipDiscordMessage } = await yargs(hideBin(process.argv)) .parse(); async function main() { - const { discordToken, discordChannelId } = parseCiEnv( - await getEnvVariables(["ci"]), - ); + const { discordToken, discordChannelId } = parseCiEnv(process.env); try { const ciAppEnv = await getEnvVariables(["ci-app"]); @@ -81,7 +79,7 @@ main() process.exit(1); }); -function parseCiEnv(env: Record) { +function parseCiEnv(env: Record) { const discordToken = env["DISCORD_TOKEN"]; if (!discordToken) { throw new Error("Missing DISCORD_TOKEN from .env.ci"); diff --git a/.github/scripts/test/run-frontend-tests.ts b/.github/scripts/test/run-frontend-tests.ts index 6d53421d2..3aca02e51 100644 --- a/.github/scripts/test/run-frontend-tests.ts +++ b/.github/scripts/test/run-frontend-tests.ts @@ -30,8 +30,7 @@ async function main() { await $$`pnpm --dir js run test`; if (shouldUploadCoverage) { - const ciEnv = await getEnvVariables(["ci"]); - const { sonarToken } = parseCiEnv(ciEnv); + const { sonarToken } = parseCiEnv(process.env); await uploadFrontendTests(sonarToken); } @@ -41,7 +40,7 @@ async function main() { } } -function parseCiEnv(ciEnv: Record) { +function parseCiEnv(ciEnv: Record) { const sonarToken = (() => { const v = ciEnv["SONAR_TOKEN"]; if (!v) { diff --git a/.github/workflows/ai-command.yml b/.github/workflows/ai-command.yml index 80c021c1d..5be5975e6 100644 --- a/.github/workflows/ai-command.yml +++ b/.github/workflows/ai-command.yml @@ -61,12 +61,14 @@ jobs: - name: Setup CI uses: ./.github/composite/setup-ci with: + SECRETS: ${{ toJSON(secrets) }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} - name: Load secrets uses: ./.github/composite/load-secrets with: + SECRETS: ${{ toJSON(secrets) }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} UNLOAD_ENVIRONMENTS: ci diff --git a/.github/workflows/ai-review.yml b/.github/workflows/ai-review.yml index 9fd324022..5f8d21e97 100644 --- a/.github/workflows/ai-review.yml +++ b/.github/workflows/ai-review.yml @@ -58,12 +58,14 @@ jobs: - name: Setup CI uses: ./.github/composite/setup-ci with: + SECRETS: ${{ toJSON(secrets) }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} - name: Load secrets uses: ./.github/composite/load-secrets with: + SECRETS: ${{ toJSON(secrets) }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} UNLOAD_ENVIRONMENTS: ci @@ -73,6 +75,7 @@ jobs: id: notion_check with: PR_ID: ${{ github.event.number || github.event.issue.number }} + SECRETS: ${{ toJSON(secrets) }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} GET_GHA_OUTPUT: "true" diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index b6c0344cd..147a9efc8 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -61,6 +61,7 @@ jobs: - name: Run workflow uses: ./.github/composite/test/backend-test with: + SECRETS: ${{ toJSON(secrets) }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} @@ -76,6 +77,7 @@ jobs: - name: Run workflow uses: ./.github/composite/test/frontend-test with: + SECRETS: ${{ toJSON(secrets) }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} @@ -93,6 +95,7 @@ jobs: - name: Setup CI uses: ./.github/composite/setup-ci with: + SECRETS: ${{ toJSON(secrets) }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} @@ -140,6 +143,7 @@ jobs: - name: Run workflow uses: ./.github/composite/build-image/internal/standup-bot with: + SECRETS: ${{ toJSON(secrets) }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} DOCKER_UPLOAD: false @@ -156,6 +160,7 @@ jobs: - name: Run workflow uses: ./.github/composite/validate-db with: + SECRETS: ${{ toJSON(secrets) }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} @@ -174,6 +179,7 @@ jobs: uses: ./.github/composite/build-image with: environment: production + SECRETS: ${{ toJSON(secrets) }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} @@ -190,6 +196,7 @@ jobs: - name: Run workflow uses: ./.github/composite/build-image/internal/standup-bot with: + SECRETS: ${{ toJSON(secrets) }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} @@ -208,6 +215,7 @@ jobs: - name: Run workflow uses: ./.github/composite/redeploy with: + SECRETS: ${{ toJSON(secrets) }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} @@ -226,5 +234,4 @@ jobs: # - name: Run workflow # uses: ./.github/composite/redeploy/internal/standup-bot # with: - # GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} - # GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} + # SECRETS: ${{ toJSON(secrets) }} diff --git a/.github/workflows/copy-command.yml b/.github/workflows/copy-command.yml index bf802fc33..724e1e0a8 100644 --- a/.github/workflows/copy-command.yml +++ b/.github/workflows/copy-command.yml @@ -56,6 +56,7 @@ jobs: - name: Setup CI uses: ./.github/composite/setup-ci with: + SECRETS: ${{ toJSON(secrets) }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} diff --git a/.github/workflows/deploy-command.yml b/.github/workflows/deploy-command.yml index b97ccde82..f7301965f 100644 --- a/.github/workflows/deploy-command.yml +++ b/.github/workflows/deploy-command.yml @@ -111,12 +111,14 @@ jobs: - name: Setup CI uses: ./.github/composite/setup-ci with: + SECRETS: ${{ toJSON(secrets) }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} - name: Load secrets uses: ./.github/composite/load-secrets with: + SECRETS: ${{ toJSON(secrets) }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} UNLOAD_ENVIRONMENTS: ci @@ -151,6 +153,7 @@ jobs: - name: Run workflow uses: ./.github/composite/test/frontend-pre-test with: + SECRETS: ${{ toJSON(secrets) }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} @@ -185,6 +188,7 @@ jobs: - name: Run workflow uses: ./.github/composite/validate-db with: + SECRETS: ${{ toJSON(secrets) }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} ENVIRONMENT: staging @@ -213,6 +217,7 @@ jobs: uses: ./.github/composite/build-image with: ENVIRONMENT: staging + SECRETS: ${{ toJSON(secrets) }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} @@ -232,6 +237,7 @@ jobs: - name: Run workflow uses: ./.github/composite/redeploy with: + SECRETS: ${{ toJSON(secrets) }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} ENVIRONMENT: staging diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 5c0052bfa..2fc7bf193 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -23,6 +23,7 @@ jobs: - name: Setup CI uses: ./.github/composite/setup-ci with: + SECRETS: ${{ toJSON(secrets) }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} diff --git a/.github/workflows/help-command.yml b/.github/workflows/help-command.yml index 00616e2c4..d851b3f68 100644 --- a/.github/workflows/help-command.yml +++ b/.github/workflows/help-command.yml @@ -20,6 +20,7 @@ jobs: - name: Setup CI uses: ./.github/composite/setup-ci with: + SECRETS: ${{ toJSON(secrets) }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} diff --git a/.github/workflows/pr-verifications.yml b/.github/workflows/pr-verifications.yml index e03580eac..45f67bfc2 100644 --- a/.github/workflows/pr-verifications.yml +++ b/.github/workflows/pr-verifications.yml @@ -34,5 +34,4 @@ jobs: # id: notion_check # with: # PR_ID: ${{ github.event.number }} -# GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} -# GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} +# SECRETS: ${{ toJSON(secrets) }} diff --git a/.github/workflows/slash.yml b/.github/workflows/slash.yml index d66c9c3af..4d76b2f3c 100644 --- a/.github/workflows/slash.yml +++ b/.github/workflows/slash.yml @@ -51,6 +51,7 @@ jobs: - name: Setup CI uses: ./.github/composite/setup-ci with: + SECRETS: ${{ toJSON(secrets) }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} @@ -61,6 +62,7 @@ jobs: - name: Load secrets uses: ./.github/composite/load-secrets with: + SECRETS: ${{ toJSON(secrets) }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} UNLOAD_ENVIRONMENTS: ci From 06e05912871eced172750306b7b7a356d9b1aca8 Mon Sep 17 00:00:00 2001 From: Nancy Huang <205217630+naanci@users.noreply.github.com> Date: Sun, 30 Aug 2026 21:19:05 -0400 Subject: [PATCH 2/8] TAN-36: fix setup-ci not exporting SECRETS to process.env --- .github/composite/setup-ci/action.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/composite/setup-ci/action.yml b/.github/composite/setup-ci/action.yml index 92a34199d..bd1ccdc1c 100644 --- a/.github/composite/setup-ci/action.yml +++ b/.github/composite/setup-ci/action.yml @@ -23,6 +23,17 @@ runs: shell: bash run: echo "GH_TOKEN=${{ inputs.GITHUB_TOKEN }}" >> $GITHUB_ENV + - name: Export secrets to environment + if: inputs.SECRETS != '' + shell: bash + env: + SECRETS_JSON: ${{ inputs.SECRETS }} + run: | + echo "$SECRETS_JSON" | jq -r 'to_entries[] | "\(.key)=\(.value)"' | while IFS='=' read -r key value; do + echo "::add-mask::$value" + echo "$key=$value" >> "$GITHUB_ENV" + done + - name: Disable man-db shell: bash run: sudo bash -ec 'echo "set man-db/auto-update false" | debconf-communicate; dpkg-reconfigure man-db' From 2815d32a3c8c29d5a62ad07a2a14ebbe28f46d6d Mon Sep 17 00:00:00 2001 From: Nancy Huang <205217630+naanci@users.noreply.github.com> Date: Mon, 31 Aug 2026 13:50:39 -0400 Subject: [PATCH 3/8] TAN-36: finish process.env secret migration hopefully --- .github/composite/setup-ci/action.yml | 50 +++---------------- .github/scripts/build-image/index.ts | 4 +- .github/scripts/load-secrets/env/load.ts | 14 ++++++ .github/scripts/test/run-backend-tests.ts | 4 +- .github/scripts/test/run-e2e-tests.ts | 4 +- .../scripts/test/run-frontend-pre-tests.ts | 4 +- .github/scripts/test/run-frontend-tests.ts | 4 +- 7 files changed, 30 insertions(+), 54 deletions(-) diff --git a/.github/composite/setup-ci/action.yml b/.github/composite/setup-ci/action.yml index bd1ccdc1c..18410f13f 100644 --- a/.github/composite/setup-ci/action.yml +++ b/.github/composite/setup-ci/action.yml @@ -19,52 +19,14 @@ inputs: runs: using: "composite" steps: - - name: Export GitHub Token - shell: bash - run: echo "GH_TOKEN=${{ inputs.GITHUB_TOKEN }}" >> $GITHUB_ENV - - - name: Export secrets to environment - if: inputs.SECRETS != '' - shell: bash - env: - SECRETS_JSON: ${{ inputs.SECRETS }} - run: | - echo "$SECRETS_JSON" | jq -r 'to_entries[] | "\(.key)=\(.value)"' | while IFS='=' read -r key value; do - echo "::add-mask::$value" - echo "$key=$value" >> "$GITHUB_ENV" - done - - - name: Disable man-db - shell: bash - run: sudo bash -ec 'echo "set man-db/auto-update false" | debconf-communicate; dpkg-reconfigure man-db' - - - uses: oven-sh/setup-bun@v2 + - name: Setup + uses: tahminator/pipeline/actions/setup@1.0.70 with: - bun-version: latest - - - name: Cache Bun dependencies - uses: actions/cache@v5 - 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 + GITHUB_TOKEN: ${{ inputs.GITHUB_TOKEN }} + GPG_PRIVATE_KEY: ${{ inputs.GPG_PRIVATE_KEY }} + GPG_PASSPHRASE: ${{ inputs.GPG_PASSPHRASE }} + SECRETS: ${{ inputs.SECRETS }} - name: Test CI scripts shell: bash run: bun run --cwd .github/scripts test - - - name: Load GPG secret key - uses: crazy-max/ghaction-import-gpg@v7 - if: inputs.GPG_PRIVATE_KEY != '' && inputs.GPG_PASSPHRASE != '' - with: - gpg_private_key: ${{ inputs.GPG_PRIVATE_KEY }} - passphrase: ${{ inputs.GPG_PASSPHRASE }} - - - name: Install git-crypt - if: inputs.GPG_PRIVATE_KEY != '' && inputs.GPG_PASSPHRASE != '' - uses: flydiverny/setup-git-crypt@v4 diff --git a/.github/scripts/build-image/index.ts b/.github/scripts/build-image/index.ts index d249d70ae..9e0c6a06c 100644 --- a/.github/scripts/build-image/index.ts +++ b/.github/scripts/build-image/index.ts @@ -1,7 +1,7 @@ import type { Environment } from "types"; import { $ } from "bun"; -import { getEnvVariables } from "load-secrets/env/load"; +import { getEnvVariablesFromProcess } from "load-secrets/env/load"; import { backend } from "utils/run-backend-instance"; import { db } from "utils/run-local-db"; import yargs from "yargs"; @@ -42,7 +42,7 @@ async function main() { try { const { dockerHubPat } = parseCiEnv(process.env); const localDbEnv = await db.start(); - const ciAppEnv = await getEnvVariables(["ci-app"]); + const ciAppEnv = getEnvVariablesFromProcess("CI_APP_"); await backend.start(ciAppEnv); diff --git a/.github/scripts/load-secrets/env/load.ts b/.github/scripts/load-secrets/env/load.ts index 62bcff1f8..9e0e9cdd7 100644 --- a/.github/scripts/load-secrets/env/load.ts +++ b/.github/scripts/load-secrets/env/load.ts @@ -81,3 +81,17 @@ export async function getEnvVariables( return Object.fromEntries(loaded); } + +export function getEnvVariablesFromProcess( + prefix: string, +): Record { + const result: Record = {}; + + for (const [key, value] of Object.entries(process.env)) { + if (key.startsWith(prefix) && value !== undefined) { + result[key.slice(prefix.length)] = value; + } + } + + return result; +} diff --git a/.github/scripts/test/run-backend-tests.ts b/.github/scripts/test/run-backend-tests.ts index 7548c88a8..543537be3 100644 --- a/.github/scripts/test/run-backend-tests.ts +++ b/.github/scripts/test/run-backend-tests.ts @@ -1,5 +1,5 @@ import { $ } from "bun"; -import { getEnvVariables } from "load-secrets/env/load"; +import { getEnvVariablesFromProcess } from "load-secrets/env/load"; import { backend } from "utils/run-backend-instance"; import { frontend } from "utils/run-frontend-instance"; import { db } from "utils/run-local-db"; @@ -17,7 +17,7 @@ const { shouldUploadCoverage } = await yargs(hideBin(process.argv)) async function main() { try { - const ciAppEnv = await getEnvVariables(["ci-app"]); + const ciAppEnv = getEnvVariablesFromProcess("CI_APP_"); const localDbEnv = await db.start(); // backend starts so we can generate schema, then kill it. diff --git a/.github/scripts/test/run-e2e-tests.ts b/.github/scripts/test/run-e2e-tests.ts index fa9b63552..b692d305c 100644 --- a/.github/scripts/test/run-e2e-tests.ts +++ b/.github/scripts/test/run-e2e-tests.ts @@ -1,5 +1,5 @@ import { $ } from "bun"; -import { getEnvVariables } from "load-secrets/env/load"; +import { getEnvVariablesFromProcess } from "load-secrets/env/load"; import { sendDiscordMessage } from "utils/discord/send-message"; import { backend } from "utils/run-backend-instance"; import { db } from "utils/run-local-db"; @@ -22,7 +22,7 @@ const { actionUrl, skipDiscordMessage } = await yargs(hideBin(process.argv)) async function main() { const { discordToken, discordChannelId } = parseCiEnv(process.env); try { - const ciAppEnv = await getEnvVariables(["ci-app"]); + const ciAppEnv = getEnvVariablesFromProcess("CI_APP_"); //type-gen try { diff --git a/.github/scripts/test/run-frontend-pre-tests.ts b/.github/scripts/test/run-frontend-pre-tests.ts index 1df1be9ce..8aa3fb741 100644 --- a/.github/scripts/test/run-frontend-pre-tests.ts +++ b/.github/scripts/test/run-frontend-pre-tests.ts @@ -1,10 +1,10 @@ import { $ } from "bun"; -import { getEnvVariables } from "load-secrets/env/load"; +import { getEnvVariablesFromProcess } from "load-secrets/env/load"; import { backend } from "utils/run-backend-instance"; import { db } from "utils/run-local-db"; async function main() { - const ciAppEnv = await getEnvVariables(["ci-app"]); + const ciAppEnv = getEnvVariablesFromProcess("CI_APP_"); const localDbEnv = await db.start(); await backend.start({ ...ciAppEnv, ...localDbEnv }); diff --git a/.github/scripts/test/run-frontend-tests.ts b/.github/scripts/test/run-frontend-tests.ts index 3aca02e51..ffc3d5dcd 100644 --- a/.github/scripts/test/run-frontend-tests.ts +++ b/.github/scripts/test/run-frontend-tests.ts @@ -1,5 +1,5 @@ import { $ } from "bun"; -import { getEnvVariables } from "load-secrets/env/load"; +import { getEnvVariablesFromProcess } from "load-secrets/env/load"; import { backend } from "utils/run-backend-instance"; import { db } from "utils/run-local-db"; import { uploadFrontendTests } from "utils/upload"; @@ -16,7 +16,7 @@ const { shouldUploadCoverage } = await yargs(hideBin(process.argv)) async function main() { try { - const ciAppEnv = await getEnvVariables(["ci-app"]); + const ciAppEnv = getEnvVariablesFromProcess("CI_APP_"); const localDbEnv = await db.start(); await backend.start({ ...ciAppEnv, ...localDbEnv }); From 12a467e5bd9f83d4ebb8e819093d293d2eb7f139 Mon Sep 17 00:00:00 2001 From: Nancy Huang <205217630+naanci@users.noreply.github.com> Date: Mon, 31 Aug 2026 14:20:15 -0400 Subject: [PATCH 4/8] TAN-36: fix validate-db reading from stale prod db host --- .github/scripts/validate-db/index.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/scripts/validate-db/index.ts b/.github/scripts/validate-db/index.ts index 16bc73ec5..78fca60e9 100644 --- a/.github/scripts/validate-db/index.ts +++ b/.github/scripts/validate-db/index.ts @@ -1,7 +1,10 @@ import type { Environment } from "types"; import { $ } from "bun"; -import { getEnvVariables } from "load-secrets/env/load"; +import { + getEnvVariables, + getEnvVariablesFromProcess, +} from "load-secrets/env/load"; import yargs from "yargs"; import { hideBin } from "yargs/helpers"; @@ -43,9 +46,13 @@ export async function main() { } } - const appEnv = await getEnvVariables([ - environment === "staging" ? "staging" : "production-ro", - ]); + const appEnv = + environment === "staging" ? + await getEnvVariables(["staging"]) + : { + ...getEnvVariablesFromProcess("DB_MIGRATIOR_"), + DATABASE_NAME: "codebloom-prod", + }; await $.env({ ...process.env, From feda89044168410359ae329178167aeaec96d7e5 Mon Sep 17 00:00:00 2001 From: Nancy Huang <205217630+naanci@users.noreply.github.com> Date: Tue, 1 Sep 2026 15:50:46 -0400 Subject: [PATCH 5/8] TAN-36: resolve PR comments --- .github/scripts/build-image/index.ts | 4 ++-- .github/scripts/load-secrets/env/load.ts | 14 ++++++++++++-- .github/scripts/test/run-backend-tests.ts | 4 ++-- .github/scripts/test/run-e2e-tests.ts | 4 ++-- .github/scripts/test/run-frontend-pre-tests.ts | 4 ++-- .github/scripts/test/run-frontend-tests.ts | 4 ++-- .github/scripts/validate-db/index.ts | 9 +++------ 7 files changed, 25 insertions(+), 18 deletions(-) diff --git a/.github/scripts/build-image/index.ts b/.github/scripts/build-image/index.ts index 9e0c6a06c..ffd3e8873 100644 --- a/.github/scripts/build-image/index.ts +++ b/.github/scripts/build-image/index.ts @@ -1,7 +1,7 @@ import type { Environment } from "types"; import { $ } from "bun"; -import { getEnvVariablesFromProcess } from "load-secrets/env/load"; +import { getEnvVariablesByPrefix } from "load-secrets/env/load"; import { backend } from "utils/run-backend-instance"; import { db } from "utils/run-local-db"; import yargs from "yargs"; @@ -42,7 +42,7 @@ async function main() { try { const { dockerHubPat } = parseCiEnv(process.env); const localDbEnv = await db.start(); - const ciAppEnv = getEnvVariablesFromProcess("CI_APP_"); + const ciAppEnv = getEnvVariablesByPrefix("CI_APP_"); await backend.start(ciAppEnv); diff --git a/.github/scripts/load-secrets/env/load.ts b/.github/scripts/load-secrets/env/load.ts index 9e0e9cdd7..fb611d3bf 100644 --- a/.github/scripts/load-secrets/env/load.ts +++ b/.github/scripts/load-secrets/env/load.ts @@ -82,12 +82,22 @@ export async function getEnvVariables( return Object.fromEntries(loaded); } -export function getEnvVariablesFromProcess( +/** + * @param prefix - Prefix to filter `envObject` keys by. + * @param envObject - Object to read variables from. Defaults to `process.env`. + * + * @returns a map of the matching variables, keyed without the `prefix`. + * + * _Please note that keys are stripped of `prefix` before being returned, so + * `PREFIX_FOO` becomes `FOO`._ + */ +export function getEnvVariablesByPrefix( prefix: string, + envObject: Record = process.env, ): Record { const result: Record = {}; - for (const [key, value] of Object.entries(process.env)) { + for (const [key, value] of Object.entries(envObject)) { if (key.startsWith(prefix) && value !== undefined) { result[key.slice(prefix.length)] = value; } diff --git a/.github/scripts/test/run-backend-tests.ts b/.github/scripts/test/run-backend-tests.ts index 543537be3..d620d879d 100644 --- a/.github/scripts/test/run-backend-tests.ts +++ b/.github/scripts/test/run-backend-tests.ts @@ -1,5 +1,5 @@ import { $ } from "bun"; -import { getEnvVariablesFromProcess } from "load-secrets/env/load"; +import { getEnvVariablesByPrefix } from "load-secrets/env/load"; import { backend } from "utils/run-backend-instance"; import { frontend } from "utils/run-frontend-instance"; import { db } from "utils/run-local-db"; @@ -17,7 +17,7 @@ const { shouldUploadCoverage } = await yargs(hideBin(process.argv)) async function main() { try { - const ciAppEnv = getEnvVariablesFromProcess("CI_APP_"); + const ciAppEnv = getEnvVariablesByPrefix("CI_APP_"); const localDbEnv = await db.start(); // backend starts so we can generate schema, then kill it. diff --git a/.github/scripts/test/run-e2e-tests.ts b/.github/scripts/test/run-e2e-tests.ts index b692d305c..41523fd4b 100644 --- a/.github/scripts/test/run-e2e-tests.ts +++ b/.github/scripts/test/run-e2e-tests.ts @@ -1,5 +1,5 @@ import { $ } from "bun"; -import { getEnvVariablesFromProcess } from "load-secrets/env/load"; +import { getEnvVariablesByPrefix } from "load-secrets/env/load"; import { sendDiscordMessage } from "utils/discord/send-message"; import { backend } from "utils/run-backend-instance"; import { db } from "utils/run-local-db"; @@ -22,7 +22,7 @@ const { actionUrl, skipDiscordMessage } = await yargs(hideBin(process.argv)) async function main() { const { discordToken, discordChannelId } = parseCiEnv(process.env); try { - const ciAppEnv = getEnvVariablesFromProcess("CI_APP_"); + const ciAppEnv = getEnvVariablesByPrefix("CI_APP_"); //type-gen try { diff --git a/.github/scripts/test/run-frontend-pre-tests.ts b/.github/scripts/test/run-frontend-pre-tests.ts index 8aa3fb741..b17d11731 100644 --- a/.github/scripts/test/run-frontend-pre-tests.ts +++ b/.github/scripts/test/run-frontend-pre-tests.ts @@ -1,10 +1,10 @@ import { $ } from "bun"; -import { getEnvVariablesFromProcess } from "load-secrets/env/load"; +import { getEnvVariablesByPrefix } from "load-secrets/env/load"; import { backend } from "utils/run-backend-instance"; import { db } from "utils/run-local-db"; async function main() { - const ciAppEnv = getEnvVariablesFromProcess("CI_APP_"); + const ciAppEnv = getEnvVariablesByPrefix("CI_APP_"); const localDbEnv = await db.start(); await backend.start({ ...ciAppEnv, ...localDbEnv }); diff --git a/.github/scripts/test/run-frontend-tests.ts b/.github/scripts/test/run-frontend-tests.ts index ffc3d5dcd..af8ad3779 100644 --- a/.github/scripts/test/run-frontend-tests.ts +++ b/.github/scripts/test/run-frontend-tests.ts @@ -1,5 +1,5 @@ import { $ } from "bun"; -import { getEnvVariablesFromProcess } from "load-secrets/env/load"; +import { getEnvVariablesByPrefix } from "load-secrets/env/load"; import { backend } from "utils/run-backend-instance"; import { db } from "utils/run-local-db"; import { uploadFrontendTests } from "utils/upload"; @@ -16,7 +16,7 @@ const { shouldUploadCoverage } = await yargs(hideBin(process.argv)) async function main() { try { - const ciAppEnv = getEnvVariablesFromProcess("CI_APP_"); + const ciAppEnv = getEnvVariablesByPrefix("CI_APP_"); const localDbEnv = await db.start(); await backend.start({ ...ciAppEnv, ...localDbEnv }); diff --git a/.github/scripts/validate-db/index.ts b/.github/scripts/validate-db/index.ts index 78fca60e9..bf7a8d363 100644 --- a/.github/scripts/validate-db/index.ts +++ b/.github/scripts/validate-db/index.ts @@ -1,10 +1,7 @@ import type { Environment } from "types"; import { $ } from "bun"; -import { - getEnvVariables, - getEnvVariablesFromProcess, -} from "load-secrets/env/load"; +import { getEnvVariablesByPrefix } from "load-secrets/env/load"; import yargs from "yargs"; import { hideBin } from "yargs/helpers"; @@ -48,9 +45,9 @@ export async function main() { const appEnv = environment === "staging" ? - await getEnvVariables(["staging"]) + getEnvVariablesByPrefix("STAGING_") : { - ...getEnvVariablesFromProcess("DB_MIGRATIOR_"), + ...getEnvVariablesByPrefix("DB_MIGRATIOR_"), DATABASE_NAME: "codebloom-prod", }; From 77818a20a373ba06235fbb0c9bad679788afd5d2 Mon Sep 17 00:00:00 2001 From: Nancy Huang <205217630+naanci@users.noreply.github.com> Date: Wed, 2 Sep 2026 19:18:05 -0400 Subject: [PATCH 6/8] TAN-36: fix prefix to match secrets --- .github/scripts/validate-db/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/validate-db/index.ts b/.github/scripts/validate-db/index.ts index bf7a8d363..107dbe4bd 100644 --- a/.github/scripts/validate-db/index.ts +++ b/.github/scripts/validate-db/index.ts @@ -45,7 +45,7 @@ export async function main() { const appEnv = environment === "staging" ? - getEnvVariablesByPrefix("STAGING_") + getEnvVariablesByPrefix("STAGING_DB_MIGRATIOR_") : { ...getEnvVariablesByPrefix("DB_MIGRATIOR_"), DATABASE_NAME: "codebloom-prod", From 11a180829dba9869d7ddcd51c1c4cd927d7350b1 Mon Sep 17 00:00:00 2001 From: Nancy Huang <205217630+naanci@users.noreply.github.com> Date: Wed, 2 Sep 2026 19:35:06 -0400 Subject: [PATCH 7/8] TAN-36: update redeploy/db/index.ts to read secrets from github --- .github/scripts/redeploy/db/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/scripts/redeploy/db/index.ts b/.github/scripts/redeploy/db/index.ts index 51854c4d1..aa00f57e5 100644 --- a/.github/scripts/redeploy/db/index.ts +++ b/.github/scripts/redeploy/db/index.ts @@ -1,7 +1,7 @@ import type { Environment } from "types"; import { $ } from "bun"; -import { getEnvVariables } from "load-secrets/env/load"; +import { getEnvVariablesByPrefix } from "load-secrets/env/load"; export async function _migrateDb({ environment, @@ -22,7 +22,7 @@ export async function _migrateDb({ } } - const migratorEnv = await getEnvVariables(["migrator"]); + const migratorEnv = getEnvVariablesByPrefix("DB_MIGRATIOR_"); const DATABASE_NAME = environment === "production" ? "codebloom-prod" : "codebloom-stg"; From 0e9305a12b0bd80c266460e5000df7c8b33da3ae Mon Sep 17 00:00:00 2001 From: Nancy Huang <205217630+naanci@users.noreply.github.com> Date: Wed, 2 Sep 2026 19:47:42 -0400 Subject: [PATCH 8/8] TAN-36: delete env for testing --- .env.ci | Bin 854 -> 0 bytes .env.ci-app | Bin 1331 -> 0 bytes .env.migrator | Bin 179 -> 0 bytes 3 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .env.ci delete mode 100644 .env.ci-app delete mode 100644 .env.migrator diff --git a/.env.ci b/.env.ci deleted file mode 100644 index 8eea77872ef7b20be9640f38f18c161621376426..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 854 zcmV-c1F8G~M@dveQdv+`06Eu+Vi#ekpOc%L>ZzFei3q^K3ZDbA1NXcMn)ziyopJ;v zJCg9{5>Aj&jD3FklVEh)2u{14p-u=QBhxjyAjaj$Q`n; zbZEaZFy-MCjbh2p5}T{RYs;Vz_!%f-C6_9Ea(tbtS$=289<5{?r6?jJqgxGP64IPl ztb3k)(i{ij1Ei=sD0&djY*(@cDhu?Epr8W;5SnMm&+DQ4Zn6=Hz=8}1WSW0?zGo0P z1WxGg^XY&@ZN6Yszle8CBV=iQoiT|r!u{p#Tp9;pKBpwkywB{$z}V-2L=%azIF1w` z>I6Z;=!%MBEuD^q6Zql$is2J8L~z(!`GR^zfJIDoEabX1l=ZwWl;`pRZ>}At<)kVF zrmcoYtw}kR^#EaJt(6bM95QSZZ83w*-7-Au!EM}9d~<;8bPDKkcqUX7bZiyY`x z!(2AI&%-UU@`o&q2UOAVhtM3YAt{sM!SZgj`ibp9{k2_*HssaL;ABz*Thad=e|H8_ zFy+vwHw>utN^C4RM}y6zD*My}ME2uu%0ZHMM~ygo=?}=V(0ObfI!7eCuX<{V!vls6 z`R#fBVO+Lrf1!SEm*H6o6~B627mXL`z4g8*tI?q4M2XC`Fs#h~gwDc*U;|rc{ZrjG zde8O!d1%5mvW|<7Iaho@IgK~oF`WyQR^d1tc~NOd>|>YhtfZ)_2)ndg%=zO_J{U6I zcYG7VsN0p&JtC}EhHsX=YX*X7+Vv-vrJz^y8kg*9BV~HG!;e0ow2+w;R~Zg;d_9H$ z;MCYM4%Y)HAP3`oiuBq^h#uzd-O@gb^GaK{pec;4KcOM7P5D|lovGbZ$xib@f)9^? zNj@7@R*jp@dDHKg&t%ZzN-z{qI|=MUEKGw+!ylJa#zHMy8W_#A7d1JPNGo0@)ycdsxj_ZHHNtny&JPCF_=KZ1AZ14vO&&-`dOy9GgccH@1Z81l)NEi}z%Tt1r+T<2|jh)>` z*bawhm@l(`vWzLho5mF3{n0H=p~O$Sh+IMw`C2%!kB{K@qajWd=Us5IWwuVHJpnA6 z*3?8vJ2emh+4)AYIdJ%@#=sV|=r5J=BS*WTwp%zV8$zkcN-Ma8rds&(v0vybuY)@2 zopZo}_w^V9!6vducq@DX7~l&QG$V7nX%4o3+mqjwa5Brtym@mDRYf7#5FLt;KlNcM zcj*5U;>+yb3s0B9X)6p(#Y3MQ;rq2g--yVBky&I|05Yh?ufSMR^Qy@g1hloVovrI3 z_Tc0S?IF*j9sAZe?0T|X(dJ+lhrYeFn}#VlT8qRz<<)WnQ(hRP17Rg|6S#bXrr(8#5b!xz6kwwKug|$<0z8THZ}I@${-QEa%}J7B*p@s5 z+7S^P$zn&?3`WlR)`6vNk2zZ>R&E4~~=^f^@hqg2t;H+?9(o zHo$(J+iTJ+Vl05)Zi4FIzfi;l8GnS}YhWP^ij!kxNyC)vc`MDYujW>UZUH9B=$$>T zcG^N`yyAHX>!P*Bg}nNFRUR3J-^E^3j?J?G;Si5&%QjRl^giI)I`>6f2Mmh;dox(R zO$T!}pCKihs4*kN5Enb!s)6m)q}Kdq1rNocO!k>PNiD6KVo7s4D$tOy_2P>@1vjD? zV&F~s769k*AX0a^$UK2&sJCcs3vd0Y#W8iLh*Y-A%=ToZBo!v6FcgLT>FHh=8)$z`!lOq3{ShZzN8X9r< ze*X&EPBQssNy(BPhRx6VGUgEyaLq`mAVyIq2{S38uH2i9n4P=D?;OW6gzLZoG?A3N zp0NXyEWJC%YA%T@=i;LOXS#a1ZsS#YV}*xvDR z5W=?Djwxz3av3go>Rm0dNJG|1$^`^%9Xp29-rtm0rt8GRTd=W2#L?$xU*$PmG>o#f zUn pA%k~lcgf`oRp_5gL9S;pwQK3V*e^oxQr|nYt)9y!S3ks!Xm)`&Y diff --git a/.env.migrator b/.env.migrator deleted file mode 100644 index f688ea3c7af76f6e1d33a7ae3082c512f963f1a7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 179 zcmV;k08IY?M@dveQdv+`01qTz9W`{N3qQDf8n+Xe1H4~aG0h>tA}WWQJ!;N`))2BTAB2|x4f hzSHB$tun17=Ts+L)P}1wlhAeCJD>2bT4O+{a+nm2SEc{}