-
Notifications
You must be signed in to change notification settings - Fork 6
Run full test suite in GitHub Actions with disposable test env #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,52 +1,29 @@ | ||||||||||||||||||||||||||||||||||
| # ────────────────────────────────────────────────────────────────────────────── | ||||||||||||||||||||||||||||||||||
| # Codra Environment Configuration Example | ||||||||||||||||||||||||||||||||||
| # Copy this file to .dev.vars for local development: cp .dev.vars.example .dev.vars | ||||||||||||||||||||||||||||||||||
| # ────────────────────────────────────────────────────────────────────────────── | ||||||||||||||||||||||||||||||||||
| # Codra local development environment example | ||||||||||||||||||||||||||||||||||
| # Copy this file to .dev.vars for local development. | ||||||||||||||||||||||||||||||||||
| # Keep real secrets only in .dev.vars or your deployment secret store. | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # --- GitHub App Authentication --- | ||||||||||||||||||||||||||||||||||
| # Create at: https://github.com/settings/apps | ||||||||||||||||||||||||||||||||||
| APP_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nREPLACE_WITH_YOUR_GITHUB_APP_PRIVATE_KEY_CONTENT\n-----END RSA PRIVATE KEY-----" | ||||||||||||||||||||||||||||||||||
| GITHUB_APP_ID="REPLACE_WITH_YOUR_APP_ID" | ||||||||||||||||||||||||||||||||||
| GITHUB_APP_SLUG="REPLACE_WITH_YOUR_APP_SLUG" | ||||||||||||||||||||||||||||||||||
| GITHUB_APP_WEBHOOK_SECRET="REPLACE_WITH_YOUR_WEBHOOK_SECRET" | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # --- Dashboard OAuth (GitHub) --- | ||||||||||||||||||||||||||||||||||
| # Use the same GitHub App's Client ID/Secret or a separate OAuth App | ||||||||||||||||||||||||||||||||||
| GITHUB_CLIENT_ID="REPLACE_WITH_YOUR_CLIENT_ID" | ||||||||||||||||||||||||||||||||||
| GITHUB_CLIENT_SECRET="REPLACE_WITH_YOUR_CLIENT_SECRET" | ||||||||||||||||||||||||||||||||||
| AUTH_CALLBACK_URL="http://localhost:8787/auth/github/callback" | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # --- Authorization --- | ||||||||||||||||||||||||||||||||||
| # Comma-separated list of GitHub usernames allowed to access the dashboard | ||||||||||||||||||||||||||||||||||
| DASHBOARD_ALLOWED_USERS="username1,username2" | ||||||||||||||||||||||||||||||||||
| # --- Integration tests --- | ||||||||||||||||||||||||||||||||||
| TEST_DATABASE_URL="postgresql://user:password@localhost:5432/codra" | ||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The previous version of .dev.vars.example included a critical warning (line 38) stating that TEST_DATABASE_URL MUST be a separate database to avoid data loss during test sweeps. The updated version removes this warning and changes the example database name from 'codra_test' to 'codra'. This increases the risk of developers accidentally running integration tests against their development or production database, potentially leading to catastrophic data loss.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The previous version of .dev.vars.example included a critical warning (line 38) stating that TEST_DATABASE_URL MUST be a separate database to avoid data loss during test sweeps. The updated version removes this warning and changes the example database name from 'codra_test' to 'codra'. This increases the risk of developers accidentally running integration tests against their development or production database, potentially leading to catastrophic data loss.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The previous version of .dev.vars.example included a critical warning (line 38) stating that TEST_DATABASE_URL MUST be a separate database to avoid data loss during test sweeps. The updated version removes this warning and changes the example database name from 'codra_test' to 'codra'. This increases the risk of developers accidentally running integration tests against their development or production database, potentially leading to catastrophic data loss.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The previous version of .dev.vars.example included a critical warning (line 38) stating that TEST_DATABASE_URL MUST be a separate database to avoid data loss during test sweeps. The updated version removes this warning and changes the example database name from 'codra_test' to 'codra'. This increases the risk of developers accidentally running integration tests against their development or production database, potentially leading to catastrophic data loss.
Suggested change
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # --- AI Intelligence (Gemini) --- | ||||||||||||||||||||||||||||||||||
| # Generate at: https://aistudio.google.com/app/apikey | ||||||||||||||||||||||||||||||||||
| # --- AI provider --- | ||||||||||||||||||||||||||||||||||
| GEMINI_API_KEY="REPLACE_WITH_YOUR_GEMINI_API_KEY" | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # --- Database Connections --- | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # 1. Local Development (Used by 'wrangler dev' for the HYPERDRIVE binding) | ||||||||||||||||||||||||||||||||||
| # This usually points to a local Postgres instance or a dev branch in Neon. | ||||||||||||||||||||||||||||||||||
| CLOUDFLARE_HYPERDRIVE_LOCAL_CONNECTION_STRING_HYPERDRIVE="postgresql://user:password@localhost:5432/codra_dev" | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # 2. Migrations (Used by 'npm run migrate') | ||||||||||||||||||||||||||||||||||
| # This script runs via Node.js and needs a direct connection to the DB you want to migrate. | ||||||||||||||||||||||||||||||||||
| DATABASE_URL="postgresql://user:password@localhost:5432/codra_dev" | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # 3. Integration Tests (Used by 'npm run test') | ||||||||||||||||||||||||||||||||||
| # MUST be a separate database to avoid data loss during test sweeps. | ||||||||||||||||||||||||||||||||||
| TEST_DATABASE_URL="postgresql://user:password@localhost:5432/codra_test" | ||||||||||||||||||||||||||||||||||
| # --- GitHub App and OAuth --- | ||||||||||||||||||||||||||||||||||
| GITHUB_APP_WEBHOOK_SECRET="REPLACE_WITH_YOUR_WEBHOOK_SECRET" | ||||||||||||||||||||||||||||||||||
| GITHUB_APP_ID="REPLACE_WITH_YOUR_APP_ID" | ||||||||||||||||||||||||||||||||||
| GITHUB_CLIENT_ID="REPLACE_WITH_YOUR_CLIENT_ID" | ||||||||||||||||||||||||||||||||||
| GITHUB_CLIENT_SECRET="REPLACE_WITH_YOUR_CLIENT_SECRET" | ||||||||||||||||||||||||||||||||||
| APP_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nREPLACE_WITH_YOUR_GITHUB_APP_PRIVATE_KEY_CONTENT\n-----END RSA PRIVATE KEY-----" | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # --- Cloudflare DLQ / Queue Management (Required) --- | ||||||||||||||||||||||||||||||||||
| # Required for DLQ inspection, replay, and purge via /api/dlq | ||||||||||||||||||||||||||||||||||
| # Create or identify the DLQ queue, then set CF_DLQ_ID to that queue's ID. | ||||||||||||||||||||||||||||||||||
| # Generate token at https://dash.cloudflare.com/profile/api-tokens (Queues:Edit permission) | ||||||||||||||||||||||||||||||||||
| CF_API_TOKEN="REPLACE_WITH_CLOUDFLARE_API_TOKEN" | ||||||||||||||||||||||||||||||||||
| # --- Cloudflare API --- | ||||||||||||||||||||||||||||||||||
|
devarshishimpi marked this conversation as resolved.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The variable CF_DLQ_ID, which was explicitly marked as '(Required)' in the previous version for Cloudflare DLQ inspection and management, has been removed from the example file. If the application still depends on this variable for DLQ functionality, new developers will be missing a critical configuration key, leading to runtime errors or broken functionality in the /api/dlq endpoints.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The variable CF_DLQ_ID, which was explicitly marked as '(Required)' in the previous version for Cloudflare DLQ inspection and management, has been removed from the example file. If the application still depends on this variable for DLQ functionality, new developers will be missing a critical configuration key, leading to runtime errors or broken functionality in the /api/dlq endpoints.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The variable CF_DLQ_ID, which was explicitly marked as '(Required)' in the previous version for Cloudflare DLQ inspection and management, has been removed from the example file. If the application still depends on this variable for DLQ functionality, new developers will be missing a critical configuration key, leading to runtime errors or broken functionality in the /api/dlq endpoints.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The variable CF_DLQ_ID, which was explicitly marked as '(Required)' in the previous version for Cloudflare DLQ inspection and management, has been removed from the example file. If the application still depends on this variable for DLQ functionality, new developers will be missing a critical configuration key, leading to runtime errors or broken functionality in the /api/dlq endpoints.
Suggested change
|
||||||||||||||||||||||||||||||||||
| CF_ACCOUNT_ID="REPLACE_WITH_YOUR_CLOUDFLARE_ACCOUNT_ID" | ||||||||||||||||||||||||||||||||||
| CF_DLQ_ID="REPLACE_WITH_YOUR_DLQ_QUEUE_ID" | ||||||||||||||||||||||||||||||||||
| CF_API_TOKEN="REPLACE_WITH_CLOUDFLARE_API_TOKEN" | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # --- Application Settings --- | ||||||||||||||||||||||||||||||||||
| # --- Application URLs and mode --- | ||||||||||||||||||||||||||||||||||
|
devarshishimpi marked this conversation as resolved.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The BOT_USERNAME variable has been removed from the example file. If the application logic still references this variable for bot identification or configuration, it will be missing from the environment of new developers who rely on this example file for setup.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The BOT_USERNAME variable has been removed from the example file. If the application logic still references this variable for bot identification or configuration, it will be missing from the environment of new developers who rely on this example file for setup.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The BOT_USERNAME variable has been removed from the example file. If the application logic still references this variable for bot identification or configuration, it will be missing from the environment of new developers who rely on this example file for setup.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The BOT_USERNAME variable has been removed from the example file. If the application logic still references this variable for bot identification or configuration, it will be missing from the environment of new developers who rely on this example file for setup.
Suggested change
|
||||||||||||||||||||||||||||||||||
| APP_URL="http://localhost:8787" | ||||||||||||||||||||||||||||||||||
| BOT_USERNAME="codra-app-dev" | ||||||||||||||||||||||||||||||||||
| AUTH_CALLBACK_URL="http://localhost:8787/auth/github/callback" | ||||||||||||||||||||||||||||||||||
| ENVIRONMENT="development" | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # --- Database connections --- | ||||||||||||||||||||||||||||||||||
| DATABASE_URL="postgresql://user:password@localhost:5432/codra_dev" | ||||||||||||||||||||||||||||||||||
| CLOUDFLARE_HYPERDRIVE_LOCAL_CONNECTION_STRING_HYPERDRIVE="postgresql://user:password@localhost:5432/codra_dev" | ||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,19 @@ | ||||||||||||||||||
| # Codra test environment example. | ||||||||||||||||||
| # Copy to .env.test for local tests. These values are fake and must not be | ||||||||||||||||||
| # reused for production, staging, or any real external service. | ||||||||||||||||||
|
|
||||||||||||||||||
| GITHUB_APP_SLUG="codra-test-app" | ||||||||||||||||||
| GITHUB_APP_WEBHOOK_SECRET="fake-webhook-secret" | ||||||||||||||||||
|
|
||||||||||||||||||
| GITHUB_CLIENT_ID="fake-dashboard-client-id" | ||||||||||||||||||
| GITHUB_CLIENT_SECRET="fake-dashboard-client-secret" | ||||||||||||||||||
| AUTH_CALLBACK_URL="https://codra.test/auth/github/callback" | ||||||||||||||||||
| DASHBOARD_ALLOWED_USERS="devarshishimpi" | ||||||||||||||||||
|
devarshishimpi marked this conversation as resolved.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The variable DASHBOARD_ALLOWED_USERS contains a specific username ('devarshishimpi'). Example environment files should generally use generic placeholders (e.g., 'your-github-username') to avoid coupling the project template to a specific individual's identity.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The variable DASHBOARD_ALLOWED_USERS contains a specific username ('devarshishimpi'). Example environment files should generally use generic placeholders (e.g., 'your-github-username') to avoid coupling the project template to a specific individual's identity.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The variable DASHBOARD_ALLOWED_USERS contains a specific username ('devarshishimpi'). Example environment files should generally use generic placeholders (e.g., 'your-github-username') to avoid coupling the project template to a specific individual's identity.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The variable DASHBOARD_ALLOWED_USERS contains a specific username ('devarshishimpi'). Example environment files should generally use generic placeholders (e.g., 'your-github-username') to avoid coupling the project template to a specific individual's identity.
Suggested change
|
||||||||||||||||||
|
|
||||||||||||||||||
| APP_URL="https://codra.test" | ||||||||||||||||||
| BOT_USERNAME="codra-test-app" | ||||||||||||||||||
|
|
||||||||||||||||||
| # Required. Must point at a disposable Postgres database because tests reset and | ||||||||||||||||||
| # write data while running. | ||||||||||||||||||
| DATABASE_URL="postgresql://postgres:postgres@127.0.0.1:5432/codra_test" | ||||||||||||||||||
| TEST_DATABASE_URL="postgresql://postgres:postgres@127.0.0.1:5432/codra_test" | ||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| import { spawnSync } from 'node:child_process'; | ||
| import { readFileSync } from 'node:fs'; | ||
| import path from 'node:path'; | ||
| import { fileURLToPath } from 'node:url'; | ||
|
|
||
| const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); | ||
| const envFiles = ['.env.test', '.env.local', '.env', '.dev.vars', '.env.test.example']; | ||
|
|
||
| function parseEnvValue(value) { | ||
| let trimmed = value.trim(); | ||
| if ( | ||
| (trimmed.startsWith('"') && trimmed.endsWith('"')) || | ||
| (trimmed.startsWith("'") && trimmed.endsWith("'")) | ||
| ) { | ||
| trimmed = trimmed.slice(1, -1); | ||
| } | ||
|
|
||
| return trimmed.replace(/\\n/g, '\n'); | ||
| } | ||
|
|
||
| function usableEnvValue(value) { | ||
| return value && value !== 'undefined' && value !== 'null' ? value : null; | ||
| } | ||
|
|
||
| function loadEnvFiles() { | ||
| for (const file of envFiles) { | ||
| try { | ||
| const content = readFileSync(path.join(rootDir, file), 'utf8'); | ||
| for (const line of content.split(/\r?\n/)) { | ||
| const trimmed = line.trim(); | ||
| if (!trimmed || trimmed.startsWith('#')) continue; | ||
|
|
||
| const separatorIndex = trimmed.indexOf('='); | ||
| if (separatorIndex === -1) continue; | ||
|
|
||
| const key = trimmed.slice(0, separatorIndex).trim(); | ||
| if (process.env[key] === undefined) { | ||
| process.env[key] = parseEnvValue(trimmed.slice(separatorIndex + 1)); | ||
| } | ||
| } | ||
| } catch (error) { | ||
| if (error?.code !== 'ENOENT') { | ||
| throw error; | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| function run(command, args) { | ||
| const result = spawnSync(command, args, { | ||
| cwd: rootDir, | ||
| env: process.env, | ||
| stdio: 'inherit', | ||
| }); | ||
|
|
||
| if (result.error) { | ||
| throw result.error; | ||
| } | ||
| if (result.status !== 0) { | ||
| process.exit(result.status ?? 1); | ||
| } | ||
| } | ||
|
|
||
| loadEnvFiles(); | ||
|
|
||
| if (!usableEnvValue(process.env.TEST_DATABASE_URL)) { | ||
| console.error([ | ||
| 'TEST_DATABASE_URL is required to run the full test suite.', | ||
| 'Copy .env.test.example to .env.test and point TEST_DATABASE_URL at a disposable Postgres database.', | ||
| ].join('\n')); | ||
| process.exit(1); | ||
| } | ||
|
|
||
| process.env.DATABASE_URL = usableEnvValue(process.env.DATABASE_URL) ?? process.env.TEST_DATABASE_URL; | ||
|
|
||
| run(process.execPath, ['scripts/migrate.mjs']); | ||
| run(process.execPath, ['node_modules/vitest/vitest.mjs', 'run']); |
Uh oh!
There was an error while loading. Please reload this page.