diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index b81d6b1..0a83e79 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -15,18 +15,6 @@ jobs: TURBO_TEAM: ${{ secrets.TURBO_TEAM }} DO_NOT_TRACK: 1 - services: - mysql: - image: mysql:8.0 - env: - MYSQL_ROOT_PASSWORD: root - MYSQL_DATABASE: emigrate - MYSQL_USER: emigrate - MYSQL_PASSWORD: emigrate - ports: - - 3306:3306 - options: --health-cmd="mysqladmin ping -h localhost" --health-interval=10s --health-timeout=5s --health-retries=5 - steps: - name: Check out code uses: actions/checkout@v4 @@ -44,16 +32,5 @@ jobs: - name: Install dependencies run: pnpm install - - name: Wait for MySQL to be ready - run: | - for i in {1..30}; do - nc -z localhost 3306 && echo "MySQL is up!" && break - echo "Waiting for MySQL..." - sleep 2 - done - - name: Checks - env: - MYSQL_HOST: localhost - MYSQL_PORT: 3306 run: pnpm checks diff --git a/.github/workflows/integration.yaml b/.github/workflows/integration.yaml new file mode 100644 index 0000000..388e546 --- /dev/null +++ b/.github/workflows/integration.yaml @@ -0,0 +1,62 @@ +name: Integration Tests + +on: + push: + branches: ['main', 'changeset-release/main'] + pull_request: + +jobs: + mysql_integration: + name: Emigrate MySQL integration tests + timeout-minutes: 15 + runs-on: ubuntu-latest + env: + TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} + TURBO_TEAM: ${{ secrets.TURBO_TEAM }} + DO_NOT_TRACK: 1 + + services: + mysql: + image: mysql:8.0 + env: + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: emigrate + MYSQL_USER: emigrate + MYSQL_PASSWORD: emigrate + ports: + - 3306:3306 + options: --health-cmd="mysqladmin ping -h localhost" --health-interval=10s --health-timeout=5s --health-retries=5 + + steps: + - name: Check out code + uses: actions/checkout@v4 + with: + fetch-depth: 2 + + - uses: pnpm/action-setup@v4.0.0 + + - name: Setup Node.js environment + uses: actions/setup-node@v4 + with: + node-version: 22.15.0 + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install + + - name: Wait for MySQL to be ready + run: | + for i in {1..30}; do + nc -z localhost 3306 && echo "MySQL is up!" && break + echo "Waiting for MySQL..." + sleep 2 + done + + - name: Build package + run: pnpm build --filter @emigrate/mysql + + - name: Integration Tests + env: + MYSQL_HOST: '127.0.0.1' + MYSQL_PORT: 3306 + run: pnpm --filter @emigrate/mysql integration diff --git a/package.json b/package.json index a2207a0..7667a61 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,10 @@ }, "overrides": [ { - "files": "packages/**/*.test.ts", + "files": [ + "packages/**/*.test.ts", + "packages/**/*.integration.ts" + ], "rules": { "@typescript-eslint/no-floating-promises": 0, "max-params": 0 diff --git a/packages/mysql/package.json b/packages/mysql/package.json index db38ba1..7e9aca7 100644 --- a/packages/mysql/package.json +++ b/packages/mysql/package.json @@ -25,8 +25,8 @@ "build": "tsc --pretty", "build:watch": "tsc --pretty --watch", "lint": "xo --cwd=../.. $(pwd)", - "test-disabled": "glob -c \"node --import tsx --test-reporter spec --test\" \"./src/**/*.test.ts\"", - "test:watch": "glob -c \"node --watch --import tsx --test-reporter spec --test\" \"./src/**/*.test.ts\"" + "integration": "glob -c \"node --import tsx --test-reporter spec --test\" \"./src/**/*.integration.ts\"", + "integration:watch": "glob -c \"node --watch --import tsx --test-reporter spec --test\" \"./src/**/*.integration.ts\"" }, "keywords": [ "emigrate", diff --git a/packages/mysql/src/index.test.ts b/packages/mysql/src/index.integration.ts similarity index 91% rename from packages/mysql/src/index.test.ts rename to packages/mysql/src/index.integration.ts index 240e3ff..d8d6cd0 100644 --- a/packages/mysql/src/index.test.ts +++ b/packages/mysql/src/index.integration.ts @@ -7,6 +7,8 @@ import { createMysqlStorage } from './index.js'; let db: { port: number; host: string }; +const toEnd = new Set<{ end: () => Promise }>(); + describe('emigrate-mysql', async () => { before( async () => { @@ -17,6 +19,12 @@ describe('emigrate-mysql', async () => { after( async () => { + for (const storage of toEnd) { + // eslint-disable-next-line no-await-in-loop + await storage.end(); + } + + toEnd.clear(); await stopDatabase(); }, { timeout: 10_000 }, @@ -37,6 +45,9 @@ describe('emigrate-mysql', async () => { const [storage1, storage2] = await Promise.all([initializeStorage(), initializeStorage()]); + toEnd.add(storage1); + toEnd.add(storage2); + const migrations = toMigrations('/emigrate', 'migrations', [ '2023-10-01-01-test.js', '2023-10-01-02-test.js', diff --git a/packages/mysql/src/tests/database.ts b/packages/mysql/src/tests/database.ts index 2270969..38b534f 100644 --- a/packages/mysql/src/tests/database.ts +++ b/packages/mysql/src/tests/database.ts @@ -6,11 +6,15 @@ let container: StartedTestContainer | undefined; export const startDatabase = async (): Promise<{ port: number; host: string }> => { if (process.env['CI']) { - return { + const config = { port: process.env['MYSQL_PORT'] ? Number.parseInt(process.env['MYSQL_PORT'], 10) : 3306, // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing host: process.env['MYSQL_HOST'] || 'localhost', }; + + console.log(`Connecting to MySQL from environment variables: ${JSON.stringify(config)}`); + + return config; } if (!container) {