Skip to content

Fix CI: eliminate duplicate runs and automate test DB schema#56

Merged
SimonOneNineEight merged 6 commits into
mainfrom
epic-9/bug-fixes-workflow-stability
Mar 20, 2026
Merged

Fix CI: eliminate duplicate runs and automate test DB schema#56
SimonOneNineEight merged 6 commits into
mainfrom
epic-9/bug-fixes-workflow-stability

Conversation

@SimonOneNineEight

Copy link
Copy Markdown
Owner

Summary

  • Scope push trigger to branches: [main] only — prevents duplicate CI runs (push + pull_request) on feature branches
  • Replace 350-line static SQL schema in testutil/database.go with actual migration runner using database.RunMigrations() — prevents test/production schema drift that caused multiple CI failures in Epic 9

Test plan

  • CI runs once per PR (not twice)
  • Backend tests pass in CI with migration-based schema setup
  • Adding a new migration automatically updates the test DB schema (no manual sync needed)

- Scope push trigger to branches: [main] to prevent duplicate CI runs
  on push + pull_request for the same branch
- Replace 350-line static SQL schema in testutil with actual migration
  runner, preventing test/production schema drift
Copilot AI review requested due to automatic review settings March 13, 2026 15:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to stabilize CI by preventing duplicate workflow executions and ensuring backend tests always use the same database schema definition as production (via the real migration files).

Changes:

  • Restrict CI push trigger to main to avoid double-running CI on feature branches (push + pull_request).
  • Replace the large in-test static SQL schema with a migration-based setup by calling database.RunMigrations() after resetting the schema.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
backend/internal/testutil/database.go Resets the test DB schema and applies the real migration files instead of maintaining a hard-coded test schema.
.github/workflows/ci.yml Scopes push CI runs to main to reduce duplicate workflow runs on PR branches.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +69 to +73
_, err := td.Exec(`
DROP SCHEMA public CASCADE;
CREATE SCHEMA public;
GRANT ALL ON SCHEMA public TO CURRENT_USER;
`)
// RunMigrations runs database migrations on test database
// migrationsPath returns the absolute path to the migrations directory
func migrationsPath() string {
_, filename, _, _ := runtime.Caller(0)
SimonOneNineEight and others added 2 commits March 15, 2026 19:44
Move test DB and LocalStack out of the main docker-compose.yml into a
dedicated test compose file with ephemeral storage. Update run_tests.sh
to use -p 1 to prevent parallel DB conflicts.
Copilot AI review requested due to automatic review settings March 16, 2026 02:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to stabilize CI by preventing duplicate workflow runs on feature branches and by making backend tests use the real SQL migrations (instead of a hand-maintained schema) to avoid schema drift.

Changes:

  • Scope GitHub Actions push trigger to main only to avoid duplicate CI runs on PR branches.
  • Replace the large static test schema with a migration-based test DB setup (reset schema, then database.RunMigrations()).
  • Introduce a dedicated docker-compose.test.yml (test Postgres + LocalStack) and serialize go test execution in the local test runner.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
docker-compose.yml Removes init-time DB bootstrap/migrations and removes LocalStack from the default dev stack.
docker-compose.test.yml Adds a separate compose stack for a tmpfs-backed test Postgres and LocalStack.
backend/run_tests.sh Runs go test with -p 1 to reduce concurrency across packages.
backend/internal/testutil/database.go Resets DB via schema drop + runs real migrations instead of static SQL.
.github/workflows/ci.yml Restricts push workflow trigger to main only.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

_, err := td.Exec(`
DROP SCHEMA public CASCADE;
CREATE SCHEMA public;
GRANT ALL ON SCHEMA public TO CURRENT_USER;
Comment thread docker-compose.yml
Comment on lines 57 to 60
volumes:
db_data:
driver: local
localstack_data:
driver: local

Comment thread docker-compose.yml
Comment on lines 12 to 16
ports:
- "5432:5432"
volumes:
- db_data:/var/lib/postgresql/data
- ./backend_go/migrations:/docker-entrypoint-initdb.d
- ./scripts/init-test-db.sh:/docker-entrypoint-initdb.d/00-init-test-db.sh
healthcheck:
Comment thread docker-compose.test.yml
POSTGRES_PASSWORD: test_password
POSTGRES_DB: ditto_test
ports:
- "5432:5432"
Simon Huang added 3 commits March 19, 2026 18:14
Requests from www.jobditto.com to jobditto.com/api were blocked
by CORS policy since they are different origins. Redirect www
visitors to the canonical non-www domain instead of serving both.
- Use assert.Contains for scheduled_time since API returns full ISO format
- Use NoteTypeReflection in SoftDelete test to avoid duplicate with earlier NoteTypeGeneral
…que constraint

The test was sharing createdInterview with other tests, causing a
duplicate key violation on the interview_notes unique type constraint.
Copilot AI review requested due to automatic review settings March 20, 2026 02:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to stabilize CI by avoiding duplicate workflow runs and ensuring the test database schema is always derived from the real SQL migrations (preventing drift between test and production).

Changes:

  • Scope GitHub Actions push trigger to main only to prevent duplicate CI runs on feature branches.
  • Replace the large static test schema with database.RunMigrations() after resetting the Postgres schema.
  • Add a dedicated docker-compose.test.yml for ephemeral Postgres + LocalStack test dependencies, plus small test adjustments and config tweaks.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
docker-compose.yml Simplifies dev DB container setup by removing test DB init and init-time mounts.
docker-compose.test.yml Adds a separate compose stack for test DB + LocalStack.
backend/run_tests.sh Serializes Go tests (-p 1) to reduce DB-related test flakiness.
backend/internal/testutil/database.go Resets schema by dropping public and runs real migrations via database.RunMigrations().
backend/internal/repository/interview_note_test.go Improves test isolation by using a dedicated interview for soft-delete tests.
backend/internal/handlers/interview_test.go Makes scheduled time assertion tolerant of formatting differences.
Caddyfile Adds www → apex redirect behavior.
.github/workflows/ci.yml Limits push runs to main to eliminate duplicate CI runs per PR push.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docker-compose.test.yml
Comment on lines +4 to +10
container_name: ditto-test-postgres
environment:
POSTGRES_USER: ditto_test_user
POSTGRES_PASSWORD: test_password
POSTGRES_DB: ditto_test
ports:
- "5432:5432"

Copilot AI Mar 20, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This compose file binds Postgres to host port 5432 and sets a fixed container_name. That will conflict with the dev DB in docker-compose.yml (also 5432 / fixed name) if both are running, making it hard to run dev + tests concurrently. Consider removing container_name and/or mapping to a different host port (or rely on the Compose network and avoid host port publishing when not needed).

Suggested change
container_name: ditto-test-postgres
environment:
POSTGRES_USER: ditto_test_user
POSTGRES_PASSWORD: test_password
POSTGRES_DB: ditto_test
ports:
- "5432:5432"
environment:
POSTGRES_USER: ditto_test_user
POSTGRES_PASSWORD: test_password
POSTGRES_DB: ditto_test
ports:
- "5433:5432"

Copilot uses AI. Check for mistakes.
Comment thread docker-compose.yml
Comment on lines 9 to 16
POSTGRES_USER: ditto_user
POSTGRES_PASSWORD: ditto_password
POSTGRES_DB: ditto_dev
# Create test database on init
POSTGRES_MULTIPLE_DATABASES: ditto_dev,ditto_test
ports:
- "5432:5432"
volumes:
- db_data:/var/lib/postgresql/data
- ./backend_go/migrations:/docker-entrypoint-initdb.d
- ./scripts/init-test-db.sh:/docker-entrypoint-initdb.d/00-init-test-db.sh
healthcheck:

Copilot AI Mar 20, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By removing the init-time test DB creation/migration mounts, this dev compose now only provisions ditto_dev. Since the repo’s test tooling expects a separate ditto_test DB/user, consider adding an inline comment here pointing developers to docker-compose.test.yml (or using Compose profiles) so running tests locally doesn’t become a silent setup footgun.

Copilot uses AI. Check for mistakes.
Comment thread Caddyfile
@@ -1,4 +1,8 @@
{$DOMAIN:localhost}, www.{$DOMAIN:localhost} {
www.{$DOMAIN:localhost} {
redir https://{$DOMAIN}{uri} permanent

Copilot AI Mar 20, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The redirect target uses {$DOMAIN} without a default, while the site labels use {$DOMAIN:localhost}. If DOMAIN is unset, this will generate an invalid redirect URL (e.g., https://{uri}). Use the same default placeholder (or a request placeholder like {host}) in the redirect target to keep behavior consistent when DOMAIN isn’t provided.

Suggested change
redir https://{$DOMAIN}{uri} permanent
redir https://{$DOMAIN:localhost}{uri} permanent

Copilot uses AI. Check for mistakes.
_, err := td.Exec(`
DROP SCHEMA public CASCADE;
CREATE SCHEMA public;
GRANT ALL ON SCHEMA public TO CURRENT_USER;

Copilot AI Mar 20, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RunMigrations drops the entire public schema, which will also drop extensions installed into public (common for pgcrypto). The SQL migrations rely on gen_random_uuid() defaults, but there is no CREATE EXTENSION in the migrations or codebase, so a fresh Postgres container is likely to fail during migration. Consider ensuring pgcrypto is installed after recreating the schema (or add an initial migration to create required extensions).

Suggested change
GRANT ALL ON SCHEMA public TO CURRENT_USER;
GRANT ALL ON SCHEMA public TO CURRENT_USER;
CREATE EXTENSION IF NOT EXISTS pgcrypto;

Copilot uses AI. Check for mistakes.
// RunMigrations runs database migrations on test database
// migrationsPath returns the absolute path to the migrations directory
func migrationsPath() string {
_, filename, _, _ := runtime.Caller(0)

Copilot AI Mar 20, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

migrationsPath() ignores the boolean return from runtime.Caller. While it usually succeeds, failing to handle the ok flag can make debugging path issues harder in unusual build/test environments. Consider checking ok and either panicking with a clear message or returning a safe fallback.

Suggested change
_, filename, _, _ := runtime.Caller(0)
_, filename, _, ok := runtime.Caller(0)
if !ok {
panic("testutil: unable to determine caller for migrationsPath")
}

Copilot uses AI. Check for mistakes.
@SimonOneNineEight SimonOneNineEight merged commit 946eab2 into main Mar 20, 2026
9 checks passed
@SimonOneNineEight SimonOneNineEight deleted the epic-9/bug-fixes-workflow-stability branch March 20, 2026 02:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants