Skip to content

Commit

Permalink
allow migration table name in config (#1)
Browse files Browse the repository at this point in the history
* allow migration table name in config

* empty commit

* fix initial migration integration test

* 5.3.1

* add workflow for publishing

* prepare for publish

* fix validate bin

* add npmrc for publish

* another attempt at publishing

* publish using github token

* 5.3.2

* Revert "5.3.2"

This reverts commit 24379b9.

* publish to npm

* scoped publish public

* add registry url during node setup

* update readme
  • Loading branch information
Ashniu123 authored Aug 15, 2021
1 parent 0314717 commit f30129b
Show file tree
Hide file tree
Showing 19 changed files with 279 additions and 65 deletions.
37 changes: 24 additions & 13 deletions .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,38 @@ name: Node.js CI

on:
push:
branches: [ master ]
branches: [master]
pull_request:
branches: [ master ]
branches: [master]

env:
cache-name: postgres-migrations

jobs:
build:

runs-on: ubuntu-latest

strategy:
matrix:
node-version: [12.x, 14.x, 16.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/

steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm run
- run: docker pull postgres:9.4
- run: npm test
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- run: npm ci
- run: docker pull postgres:13.2
- run: npm test
36 changes: 36 additions & 0 deletions .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Publish package

on:
push:
tags:
- "v*"

env:
cache-name: postgres-migrations

jobs:
test-and-publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Nodejs
uses: actions/setup-node@v2
with:
node-version: 14.x
registry-url: "https://registry.npmjs.org"
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- run: npm ci
- run: docker pull postgres:13.2
- env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npm publish --access public
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ node_modules
*.log
test-reports
dist/
.vscode
.env
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
dist
node_modules
8 changes: 3 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
# Postgres migrations

![GitHub Actions](https://github.com/ThomWright/postgres-migrations/actions/workflows/node.js.yml/badge.svg)
[![npm](https://img.shields.io/npm/v/postgres-migrations.svg)](https://www.npmjs.com/package/postgres-migrations)
[![David](https://img.shields.io/david/ThomWright/postgres-migrations.svg)](https://david-dm.org/ThomWright/postgres-migrations)
[![David](https://img.shields.io/david/dev/ThomWright/postgres-migrations.svg)](https://david-dm.org/ThomWright/postgres-migrations)
![GitHub Actions](https://github.com/nektarai/postgres-migrations/actions/workflows/node.js.yml/badge.svg)
[![npm](https://img.shields.io/npm/v/@nektarai/postgres-migrations.svg)](https://www.npmjs.com/package/@nektarai/postgres-migrations)

A PostgreSQL migration library inspired by the Stack Overflow system described in [Nick Craver's blog](http://nickcraver.com/blog/2016/05/03/stack-overflow-how-we-do-deployment-2016-edition/#database-migrations).

Expand Down Expand Up @@ -68,7 +66,7 @@ async function() {
const client = new pg.Client(dbConfig) // or a Pool, or a PoolClient
await client.connect()
try {
await migrate({client}, "path/to/migration/files")
await migrate({client}, "path/to/migration/files", { migrationTableName: "my_schema.migrations" })
} finally {
await client.end()
}
Expand Down
1 change: 1 addition & 0 deletions ava.config.cjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
module.exports = {
extensions: ["ts"],
require: ["ts-node/register"],
verbose: true,
}
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 11 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"name": "postgres-migrations",
"version": "5.3.0",
"name": "@nektarai/postgres-migrations",
"version": "5.3.1",
"description": "Stack Overflow style database migrations for PostgreSQL",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"bin": {
"pg-validate-migrations": "./dist/bin/validate.js"
},
"author": "Thom Wright",
"author": "Nektar AI<[email protected]>",
"keywords": [
"postgres",
"postgresql",
Expand All @@ -17,25 +17,24 @@
"database",
"db"
],
"homepage": "https://github.com/thomwright/postgres-migrations#readme",
"homepage": "https://github.com/nektarai/postgres-migrations#readme",
"license": "MIT",
"repository": {
"type": "git",
"url": "[email protected]:thomwright/postgres-migrations.git"
"url": "[email protected]:nektarai/postgres-migrations.git"
},
"bugs": {
"url": "https://github.com/thomwright/postgres-migrations/issues"
"url": "https://github.com/nektarai/postgres-migrations/issues"
},
"engines": {
"node": ">10.17.0"
},
"scripts": {
"checkPushed": "[ \"$(git rev-list --count @{upstream}..HEAD)\" -eq 0 ] || (echo You have unpushed commits && exit 1)",
"prepublishOnly": "npm run checkPushed && npm test && npm run build",
"check-formatting": "./node_modules/.bin/prettier '**/*.ts' --list-different",
"fix-formatting": "./node_modules/.bin/prettier '**/*.ts' --write",
"prepublishOnly": "npm test && npm run build",
"check-formatting": "prettier '**/*.ts' --list-different",
"fix-formatting": "prettier '**/*.ts' --write",
"lint": "npm run tslint && npm run check-formatting",
"tslint": "tslint 'src/**/*.ts' --type-check --project tsconfig.json --format verbose",
"tslint": "tslint 'src/**/*.ts' --project tsconfig.json --format verbose",
"test-integration": "ava --config ava.config.integration.cjs",
"test-unit": "ava --config ava.config.unit.cjs",
"test": "npm run test-unit && npm run lint && npm run test-integration",
Expand Down Expand Up @@ -68,4 +67,4 @@
"typescript": "^4.3.4",
"typescript-tslint-plugin": "^1.0.1"
}
}
}
2 changes: 1 addition & 1 deletion src/__tests__/fixtures/docker-postgres.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export const startPostgres = (containerName: string, t: CbExecutionContext) => {
--health-interval=1s \
--health-retries=30 \
--health-timeout=1s \
postgres:9.4`)
postgres:13.2`)

const portMapping = execSync(`docker port ${containerName} 5432`).toString()
const port = parseInt(portMapping.split(":")[1], 10)
Expand Down
3 changes: 3 additions & 0 deletions src/__tests__/fixtures/success-existing-db/1_success.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
CREATE TABLE success (
id integer
);
3 changes: 3 additions & 0 deletions src/__tests__/fixtures/success-existing-table/1_success.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
CREATE TABLE success (
id integer
);
129 changes: 118 additions & 11 deletions src/__tests__/migrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import test from "ava"
import * as pg from "pg"
import SQL from "sql-template-strings"
import {createDb, migrate, MigrateDBConfig} from "../"
import {loadInitialMigration} from "../initial-migration"
import {PASSWORD, startPostgres, stopPostgres} from "./fixtures/docker-postgres"

const CONTAINER_NAME = "pg-migrations-test-migrate"
Expand Down Expand Up @@ -688,35 +689,141 @@ test("rollback", (t) => {
})
})

test("with custom migration table name", async (t) => {
const databaseName = "migration-test-custom-migration-table"
const dbConfig = {
database: databaseName,
user: "postgres",
password: PASSWORD,
host: "localhost",
port,
}

const migrateWithCustomMigrationTable = () =>
migrate(dbConfig, "src/__tests__/fixtures/success-first", {
migrationTableName: "my_migrations",
})

await createDb(databaseName, dbConfig)
await migrateWithCustomMigrationTable()

t.truthy(await doesTableExist(dbConfig, "my_migrations"))
t.truthy(await doesTableExist(dbConfig, "success"))

await migrateWithCustomMigrationTable()
})

test("with custom migration table name in a custom schema", async (t) => {
const databaseName = "migration-test-custom-schema-custom-migration-table"
const dbConfig = {
database: databaseName,
user: "postgres",
password: PASSWORD,
host: "localhost",
port,
}

const migrateWithCustomMigrationTable = () =>
migrate(dbConfig, "src/__tests__/fixtures/success-first", {
migrationTableName: "my_schema.my_migrations",
})

const pool = new pg.Pool(dbConfig)

try {
await createDb(databaseName, dbConfig)
await pool.query("CREATE SCHEMA IF NOT EXISTS my_schema")
await migrateWithCustomMigrationTable()

t.truthy(await doesTableExist(dbConfig, "my_schema.my_migrations"))
t.truthy(await doesTableExist(dbConfig, "success"))

await migrateWithCustomMigrationTable()
} finally {
await pool.end()
}
})

test("with custom migration table name in a custom schema with same table name in another schema", async (t) => {
const databaseName = "migration-test-success-existing-table"
const dbConfig = {
database: databaseName,
user: "postgres",
password: PASSWORD,
host: "localhost",
port,
}

const pool = new pg.Pool(dbConfig)

try {
await createDb(databaseName, dbConfig)
await pool.query(`
CREATE SCHEMA IF NOT EXISTS existing_schema;
CREATE TABLE existing_schema.migrations (
id integer
);
`)
await migrate(dbConfig, "src/__tests__/fixtures/success-existing-table")
t.truthy(await doesTableExist(dbConfig, "success"))
} finally {
await pool.end()
}
})

test("successful migration on an existing database", async (t) => {
const databaseName = "migration-test-success-existing-db"
const dbConfig = {
database: databaseName,
user: "postgres",
password: PASSWORD,
host: "localhost",
port,
}

const pool = new pg.Pool(dbConfig)

try {
await createDb(databaseName, dbConfig)
const initSql = await loadInitialMigration("migrations")
await pool.query(`
${initSql.sql}
INSERT INTO migrations ("id","name","hash","executed_at") VALUES (${initSql.id},'${initSql.fileName}','${initSql.hash}','2020-06-29 18:38:05.064546');
`)
await migrate(dbConfig, "src/__tests__/fixtures/success-existing-db")
t.truthy(await doesTableExist(dbConfig, "success"))
} finally {
await pool.end()
}
})

function doesTableExist(dbConfig: pg.ClientConfig, tableName: string) {
const client = new pg.Client(dbConfig)
client.on("error", (err) => console.log("doesTableExist on error", err))
return client
.connect()
.then(() =>
client.query(SQL`
SELECT EXISTS (
SELECT 1
FROM pg_catalog.pg_class c
WHERE c.relname = ${tableName}
AND c.relkind = 'r'
);
`),
client.query(SQL`SELECT to_regclass(${tableName}) as matching_tables;`),
)
.then((result) => {
try {
return client
.end()
.then(() => {
return result.rows.length > 0 && result.rows[0].exists
return (
result.rows.length > 0 && result.rows[0].matching_tables !== null
)
})
.catch((error) => {
console.log("Async error in 'doesTableExist", error)
return result.rows.length > 0 && result.rows[0].exists
return (
result.rows.length > 0 && result.rows[0].matching_tables !== null
)
})
} catch (error) {
console.log("Sync error in 'doesTableExist", error)
return result.rows.length > 0 && result.rows[0].exists
return result.rows.length > 0 && result.rows[0].matching_tables !== null
}
})
}
2 changes: 2 additions & 0 deletions src/__unit__/migration-file-validation/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ test("two migrations with the same id", async (t) => {
const error = await t.throwsAsync(async () =>
loadMigrationFiles(
"src/__unit__/migration-file-validation/fixtures/conflict",
console.log,
"migrations",
),
)
t.regex(error.message, /non-consecutive/)
Expand Down
7 changes: 6 additions & 1 deletion src/bin/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@ import {loadMigrationFiles} from "../files-loader"

async function main(args: Array<string>) {
const directory = args[0]
const migrationTableName = args[1] ?? "migrations"

await loadMigrationFiles(directory, (x) => console.error(x))
await loadMigrationFiles(
directory,
(x) => console.error(x),
migrationTableName,
)
}

main(argv.slice(2)).catch((e) => {
Expand Down
Loading

0 comments on commit f30129b

Please sign in to comment.