0
Fork 0
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:
Gao Sun 2023-01-17 17:52:54 +08:00
parent 39bc1a82f1
commit 03a8e84e2f
No known key found for this signature in database
GPG key ID: 13EBE123E4773688
7 changed files with 200 additions and 10 deletions

View file

@ -78,7 +78,7 @@ jobs:
- name: Extract - name: Extract
working-directory: tests working-directory: tests
run: | 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 - name: Check and add mock connectors
working-directory: tests working-directory: tests

View file

@ -85,19 +85,73 @@ jobs:
with: with:
context: . context: .
main-alteration-sequence: main-alteration:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
# ** Checkout fresh and alteration ref **
- uses: actions/checkout@v3 - uses: actions/checkout@v3
with: with:
fetch-depth: 2 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 - name: Setup Node and pnpm
uses: silverhand-io/actions-node-pnpm-run-steps@v2 uses: silverhand-io/actions-node-pnpm-run-steps@v2
with:
run-install: false
# ** 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: Build
run: pnpm prepack
- name: Check alteration sequence - name: Check alteration sequence
working-directory: ./fresh
run: node .scripts/check-alterations-sequence.js 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 **

View file

@ -1,7 +1,6 @@
/** /**
* This script runs a task to check alteration files seqence: * This script runs a task to check alteration files sequence:
* new files should come last * Newest files should come last.
*
*/ */
import { execSync } from "child_process"; import { execSync } from "child_process";

View 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),
);

View file

@ -24,7 +24,9 @@
"@commitlint/cli": "^17.0.0", "@commitlint/cli": "^17.0.0",
"@commitlint/config-conventional": "^17.0.0", "@commitlint/config-conventional": "^17.0.0",
"@commitlint/types": "^17.0.0", "@commitlint/types": "^17.0.0",
"@types/pg": "^8.6.6",
"husky": "^8.0.0", "husky": "^8.0.0",
"pg": "^8.8.0",
"typescript": "^4.9.4" "typescript": "^4.9.4"
}, },
"engines": { "engines": {

View file

@ -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;

View file

@ -9,7 +9,9 @@ importers:
'@commitlint/config-conventional': ^17.0.0 '@commitlint/config-conventional': ^17.0.0
'@commitlint/types': ^17.0.0 '@commitlint/types': ^17.0.0
'@logto/cli': ^1.0.0-beta.10 '@logto/cli': ^1.0.0-beta.10
'@types/pg': ^8.6.6
husky: ^8.0.0 husky: ^8.0.0
pg: ^8.8.0
typescript: ^4.9.4 typescript: ^4.9.4
dependencies: dependencies:
'@logto/cli': link:packages/cli '@logto/cli': link:packages/cli
@ -18,7 +20,9 @@ importers:
'@commitlint/cli': 17.0.0 '@commitlint/cli': 17.0.0
'@commitlint/config-conventional': 17.0.0 '@commitlint/config-conventional': 17.0.0
'@commitlint/types': 17.0.0 '@commitlint/types': 17.0.0
'@types/pg': 8.6.6
husky: 8.0.1 husky: 8.0.1
pg: 8.8.0
typescript: 4.9.4 typescript: 4.9.4
packages/cli: packages/cli:
@ -4084,6 +4088,14 @@ packages:
pg-types: 2.2.0 pg-types: 2.2.0
dev: false 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: /@types/pluralize/0.0.29:
resolution: {integrity: sha512-BYOID+l2Aco2nBik+iYS4SZX0Lf20KPILP5RGmM1IgzdwNdTs0eebiFriOPcej1sX9mLnSoiNte5zcFxssgpGA==} resolution: {integrity: sha512-BYOID+l2Aco2nBik+iYS4SZX0Lf20KPILP5RGmM1IgzdwNdTs0eebiFriOPcej1sX9mLnSoiNte5zcFxssgpGA==}
dev: true dev: true
@ -11558,7 +11570,6 @@ packages:
pg: '>=8.0' pg: '>=8.0'
dependencies: dependencies:
pg: 8.8.0 pg: 8.8.0
dev: false
/pg-protocol/1.5.0: /pg-protocol/1.5.0:
resolution: {integrity: sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ==} resolution: {integrity: sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ==}
@ -11630,7 +11641,6 @@ packages:
pg-protocol: 1.5.0 pg-protocol: 1.5.0
pg-types: 2.2.0 pg-types: 2.2.0
pgpass: 1.0.4 pgpass: 1.0.4
dev: false
/pgpass/1.0.4: /pgpass/1.0.4:
resolution: {integrity: sha512-YmuA56alyBq7M59vxVBfPJrGSozru8QAdoNlWuW3cz8l+UX3cWge0vTvjKhsSHSJpo3Bom8/Mm6hf0TR5GY0+w==} resolution: {integrity: sha512-YmuA56alyBq7M59vxVBfPJrGSozru8QAdoNlWuW3cz8l+UX3cWge0vTvjKhsSHSJpo3Bom8/Mm6hf0TR5GY0+w==}