mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
refactor: fix alteration issues and add tests
This commit is contained in:
parent
39bc1a82f1
commit
03a8e84e2f
7 changed files with 200 additions and 10 deletions
2
.github/workflows/integration-test.yml
vendored
2
.github/workflows/integration-test.yml
vendored
|
@ -78,7 +78,7 @@ jobs:
|
|||
- name: Extract
|
||||
working-directory: tests
|
||||
run: |
|
||||
npm run cli init -- -p ../logto --db postgres://postgres:postgres@localhost:5432/postgres --no-oc --du ../logto.tar.gz
|
||||
npm run cli init -- -p ../logto --db postgres://postgres:postgres@localhost:5432/postgres --du ../logto.tar.gz
|
||||
|
||||
- name: Check and add mock connectors
|
||||
working-directory: tests
|
||||
|
|
60
.github/workflows/main.yml
vendored
60
.github/workflows/main.yml
vendored
|
@ -85,19 +85,73 @@ jobs:
|
|||
with:
|
||||
context: .
|
||||
|
||||
main-alteration-sequence:
|
||||
main-alteration:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
# ** Checkout fresh and alteration ref **
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 2
|
||||
path: ./fresh
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: v1.0.0-beta.11
|
||||
path: ./alteration
|
||||
# ** End **
|
||||
|
||||
- name: Copy lockfile # Make setup workflow happy
|
||||
run: cp ./fresh/pnpm-lock.yaml ./
|
||||
|
||||
- name: Setup Node and pnpm
|
||||
uses: silverhand-io/actions-node-pnpm-run-steps@v2
|
||||
with:
|
||||
run-install: false
|
||||
|
||||
- name: Build
|
||||
run: pnpm prepack
|
||||
# ** Prepack packages **
|
||||
- name: Prepack fresh
|
||||
working-directory: ./fresh
|
||||
run: pnpm i && pnpm prepack
|
||||
|
||||
- name: Prepack alteration
|
||||
working-directory: ./alteration
|
||||
run: pnpm i && pnpm prepack
|
||||
# ** End **
|
||||
|
||||
- name: Check alteration sequence
|
||||
working-directory: ./fresh
|
||||
run: node .scripts/check-alterations-sequence.js
|
||||
|
||||
- name: Setup Postgres
|
||||
uses: ikalnytskyi/action-setup-postgres@v4
|
||||
|
||||
# ** Setup up-to-date databases and compare (test `up`) **
|
||||
- name: Setup fresh database
|
||||
working-directory: ./fresh
|
||||
run: pnpm cli db seed
|
||||
env:
|
||||
DB_URL: postgres://postgres:postgres@localhost:5432/fresh
|
||||
|
||||
- name: Setup alteration database
|
||||
working-directory: ./alteration
|
||||
run: |
|
||||
cd packages/cli
|
||||
pnpm start db seed
|
||||
env:
|
||||
DB_URL: postgres://postgres:postgres@localhost:5432/alteration
|
||||
|
||||
- name: Run alteration scripts
|
||||
working-directory: ./fresh
|
||||
run: pnpm cli db alt deploy next
|
||||
env:
|
||||
DB_URL: postgres://postgres:postgres@localhost:5432/alteration
|
||||
|
||||
- name: Compare manifests
|
||||
working-directory: ./fresh
|
||||
run: node .scripts/compare-database.js fresh alteration
|
||||
# ** End **
|
||||
|
||||
# ** Setup old databases and compare (test `down`) **
|
||||
# TBD
|
||||
# ** End **
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/**
|
||||
* This script runs a task to check alteration files seqence:
|
||||
* new files should come last
|
||||
*
|
||||
* This script runs a task to check alteration files sequence:
|
||||
* Newest files should come last.
|
||||
*/
|
||||
|
||||
import { execSync } from "child_process";
|
||||
|
|
84
.scripts/compare-database.js
Normal file
84
.scripts/compare-database.js
Normal file
|
@ -0,0 +1,84 @@
|
|||
import pg from 'pg';
|
||||
import assert from 'node:assert';
|
||||
|
||||
const omit = (object, ...keys) => Object.fromEntries(Object.entries(object).filter(([key]) => !keys.includes(key)));
|
||||
const omitArray = (arrayOfObjects, ...keys) => arrayOfObjects.map((value) => omit(value, ...keys));
|
||||
|
||||
const schema = 'public';
|
||||
|
||||
const queryDatabaseManifest = async (database) => {
|
||||
const pool = new pg.Pool({ database, user: 'postgres', password: 'postgres' });
|
||||
|
||||
const { rows: tables } = await pool.query(/* sql */`
|
||||
select *
|
||||
from information_schema.tables
|
||||
where table_schema = '${schema}'
|
||||
order by table_name asc;
|
||||
`);
|
||||
|
||||
const { rows: columns } = await pool.query(/* sql */`
|
||||
select *
|
||||
from information_schema.columns
|
||||
where table_schema = '${schema}'
|
||||
order by table_name, column_name asc;
|
||||
`);
|
||||
|
||||
const { rows: enums } = await pool.query(/* sql */`
|
||||
select pg_type.typname, pg_enum.enumlabel
|
||||
from pg_type
|
||||
join pg_enum
|
||||
on pg_enum.enumtypid = pg_type.oid
|
||||
order by pg_type.typname, pg_enum.enumlabel asc;
|
||||
`);
|
||||
|
||||
const { rows: constraints } = await pool.query(/* sql */`
|
||||
select conrelid::regclass AS table, con.*, pg_get_constraintdef(con.oid)
|
||||
from pg_catalog.pg_constraint con
|
||||
inner join pg_catalog.pg_class rel
|
||||
on rel.oid = con.conrelid
|
||||
inner join pg_catalog.pg_namespace nsp
|
||||
on nsp.oid = connamespace
|
||||
where nsp.nspname = 'public'
|
||||
order by conname asc;
|
||||
`);
|
||||
|
||||
const { rows: indexes } = await pool.query(/* sql */`
|
||||
select *
|
||||
from pg_indexes
|
||||
where schemaname='${schema}'
|
||||
order by tablename, indexname asc;
|
||||
`);
|
||||
|
||||
return {
|
||||
tables: omitArray(tables, 'table_catalog'),
|
||||
columns: omitArray(columns, 'table_catalog', 'udt_catalog', 'ordinal_position', 'dtd_identifier'),
|
||||
enums,
|
||||
constraints: omitArray(
|
||||
constraints,
|
||||
'oid',
|
||||
'connamespace',
|
||||
'conrelid',
|
||||
'contypid',
|
||||
'conindid',
|
||||
'conparentid',
|
||||
'confrelid',
|
||||
'conkey',
|
||||
'confkey',
|
||||
'conpfeqop',
|
||||
'conppeqop',
|
||||
'conffeqop',
|
||||
'confdelsetcols',
|
||||
'conexclop',
|
||||
),
|
||||
indexes,
|
||||
};
|
||||
};
|
||||
|
||||
const [,, database1, database2] = process.argv;
|
||||
|
||||
console.log('Compare database manifest between', database1, 'and', database2)
|
||||
|
||||
assert.deepStrictEqual(
|
||||
await queryDatabaseManifest(database1),
|
||||
await queryDatabaseManifest(database2),
|
||||
);
|
|
@ -24,7 +24,9 @@
|
|||
"@commitlint/cli": "^17.0.0",
|
||||
"@commitlint/config-conventional": "^17.0.0",
|
||||
"@commitlint/types": "^17.0.0",
|
||||
"@types/pg": "^8.6.6",
|
||||
"husky": "^8.0.0",
|
||||
"pg": "^8.8.0",
|
||||
"typescript": "^4.9.4"
|
||||
},
|
||||
"engines": {
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
import { sql } from 'slonik';
|
||||
|
||||
import type { AlterationScript } from '../lib/types/alteration.js';
|
||||
|
||||
const alteration: AlterationScript = {
|
||||
up: async (pool) => {
|
||||
await pool.query(sql`
|
||||
alter table roles_scopes
|
||||
drop constraint roles_scopes_role_id_fkey;
|
||||
`);
|
||||
await pool.query(sql`
|
||||
alter table users_roles
|
||||
drop constraint users_roles_role_id_fkey;
|
||||
`);
|
||||
await pool.query(sql`drop index roles_pkey;`);
|
||||
await pool.query(sql`
|
||||
alter table roles
|
||||
add primary key (id);
|
||||
`);
|
||||
|
||||
await pool.query(sql`
|
||||
alter table roles_scopes
|
||||
drop constraint roles_permissison_pkey,
|
||||
add primary key (role_id, scope_id);
|
||||
`);
|
||||
|
||||
await pool.query(sql`
|
||||
alter table users_roles
|
||||
add foreign key (role_id) references roles (id) on update cascade on delete cascade;
|
||||
`);
|
||||
await pool.query(sql`
|
||||
alter table roles_scopes
|
||||
add foreign key (role_id) references roles (id) on update cascade on delete cascade;
|
||||
`);
|
||||
},
|
||||
down: async (pool) => {
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
};
|
||||
|
||||
export default alteration;
|
|
@ -9,7 +9,9 @@ importers:
|
|||
'@commitlint/config-conventional': ^17.0.0
|
||||
'@commitlint/types': ^17.0.0
|
||||
'@logto/cli': ^1.0.0-beta.10
|
||||
'@types/pg': ^8.6.6
|
||||
husky: ^8.0.0
|
||||
pg: ^8.8.0
|
||||
typescript: ^4.9.4
|
||||
dependencies:
|
||||
'@logto/cli': link:packages/cli
|
||||
|
@ -18,7 +20,9 @@ importers:
|
|||
'@commitlint/cli': 17.0.0
|
||||
'@commitlint/config-conventional': 17.0.0
|
||||
'@commitlint/types': 17.0.0
|
||||
'@types/pg': 8.6.6
|
||||
husky: 8.0.1
|
||||
pg: 8.8.0
|
||||
typescript: 4.9.4
|
||||
|
||||
packages/cli:
|
||||
|
@ -4084,6 +4088,14 @@ packages:
|
|||
pg-types: 2.2.0
|
||||
dev: false
|
||||
|
||||
/@types/pg/8.6.6:
|
||||
resolution: {integrity: sha512-O2xNmXebtwVekJDD+02udOncjVcMZQuTEQEMpKJ0ZRf5E7/9JJX3izhKUcUifBkyKpljyUM6BTgy2trmviKlpw==}
|
||||
dependencies:
|
||||
'@types/node': 18.11.18
|
||||
pg-protocol: 1.5.0
|
||||
pg-types: 2.2.0
|
||||
dev: true
|
||||
|
||||
/@types/pluralize/0.0.29:
|
||||
resolution: {integrity: sha512-BYOID+l2Aco2nBik+iYS4SZX0Lf20KPILP5RGmM1IgzdwNdTs0eebiFriOPcej1sX9mLnSoiNte5zcFxssgpGA==}
|
||||
dev: true
|
||||
|
@ -11558,7 +11570,6 @@ packages:
|
|||
pg: '>=8.0'
|
||||
dependencies:
|
||||
pg: 8.8.0
|
||||
dev: false
|
||||
|
||||
/pg-protocol/1.5.0:
|
||||
resolution: {integrity: sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ==}
|
||||
|
@ -11630,7 +11641,6 @@ packages:
|
|||
pg-protocol: 1.5.0
|
||||
pg-types: 2.2.0
|
||||
pgpass: 1.0.4
|
||||
dev: false
|
||||
|
||||
/pgpass/1.0.4:
|
||||
resolution: {integrity: sha512-YmuA56alyBq7M59vxVBfPJrGSozru8QAdoNlWuW3cz8l+UX3cWge0vTvjKhsSHSJpo3Bom8/Mm6hf0TR5GY0+w==}
|
||||
|
|
Loading…
Reference in a new issue