Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Manage migrations with postgres-migrations #507

Merged
merged 30 commits into from
May 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
31a2bd3
feat: activate account redirect
komninoschatzipapas May 2, 2021
43b0439
Add postgres-migrations package
nunopato May 3, 2021
918dea0
Add pg package
nunopato May 3, 2021
85c3d14
Remove AUTO_MIGRATE
nunopato May 4, 2021
5dfc49d
Run migrations on start with postgres-migrations
nunopato May 4, 2021
d9eb502
Remove console.log
nunopato May 4, 2021
9ca4e1b
Move migrations and hasura metadata to ./db
nunopato May 5, 2021
f207520
Move migrations and metadata into ./db
nunopato May 5, 2021
18b53e4
Run create auth schema and extensions on postgres start
nunopato May 5, 2021
3d2e73c
Remove migrations-v1
nunopato May 5, 2021
216d600
test: refactor
komninoschatzipapas May 7, 2021
140a159
Merge branch 'redirect-account-activation' into introduce-migrations-…
nunopato May 7, 2021
3c5b78c
No need to run migrations twice
nunopato May 7, 2021
ffc7f9d
fix: use REDIRECT_URL_SUCCESS
komninoschatzipapas May 9, 2021
f25f061
Run metadata apply
nunopato May 10, 2021
929fec3
Install Hasura Cli globally instead of using the hasura-cli npm package
nunopato May 11, 2021
58915d8
Fix tests
nunopato May 11, 2021
8072af5
Install Hasura CLI on CI also
nunopato May 11, 2021
7c15054
Fix CI
nunopato May 11, 2021
9ce7113
Install psql
nunopato May 11, 2021
c61c0c5
Add apt-get update
nunopato May 11, 2021
79f0721
Fix identation
nunopato May 11, 2021
4769eb5
Use one run
nunopato May 11, 2021
afafc5c
Remove sudo
nunopato May 11, 2021
4cb8743
Fix remaining tests
nunopato May 11, 2021
78f264d
Use v2
nunopato May 11, 2021
a5f44c1
Fix Dockerfile
nunopato May 11, 2021
f3fe099
Use ./data for volumes
nunopato May 15, 2021
8288900
Make initial SQL idempotent
nunopato May 16, 2021
e33c20f
Add COPY db db
nunopato May 17, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ module.exports = {
rules: {
'@typescript-eslint/camelcase': 'off',
'jest/expect-expect': 'off',
'jest/no-test-callback': 'off'
'jest/no-test-callback': 'off',
'@typescript-eslint/explicit-function-return-type': 'off'
},
parser: '@typescript-eslint/parser',
plugins: [
Expand All @@ -15,6 +16,6 @@ module.exports = {
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
'prettier/@typescript-eslint',
'plugin:jest/recommended'
'plugin:jest/recommended',
]
}
7 changes: 7 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ jobs:
S3_BUCKET: ${{ env.S3_BUCKET }}
S3_ACCESS_KEY_ID: ${{ env.S3_ACCESS_KEY_ID }}
S3_SECRET_ACCESS_KEY: ${{ env.S3_SECRET_ACCESS_KEY }}
DATABASE_URL: postgres://postgres:${{ env.POSTGRES_PASSWORD }}@postgres:5432/postgres
options: --hostname hasura-backend-plus
steps:
- uses: actions/checkout@v2
Expand All @@ -82,6 +83,12 @@ jobs:
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install Hasura Cli
run: curl -L https://github.com/hasura/graphql-engine/raw/master/cli/get.sh | bash
nunopato marked this conversation as resolved.
Show resolved Hide resolved
- name: Install psql
run: apt-get update && apt-get install --yes --no-install-recommends postgresql-client
- name: Init Database
run: psql -f ./db/00_init-schema.sql postgresql://postgres:${{ env.POSTGRES_PASSWORD }}@postgres:5432/postgres
- name: Install dependencies
run: yarn
- name: Lint files
Expand Down
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ dist
!.env.ci
!.env*.example
*.log
hasura
coverage
config.yaml
private.pem
node_modules
data
yarn-error.log
package-lock.json
4 changes: 1 addition & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ RUN yarn install && yarn cache clean

COPY --from=builder /app/dist/ dist/
COPY custom custom
COPY metadata metadata
COPY migrations migrations
COPY migrations-v1 migrations-v1
COPY db db

HEALTHCHECK --interval=60s --timeout=2s --retries=3 CMD wget localhost:${PORT}/healthz -q -O - > /dev/null 2>&1

Expand Down
13 changes: 13 additions & 0 deletions Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
FROM node:14.4.0-alpine3.11

# glibc is required by `cli_ext` used to apply metadata
RUN wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub
RUN wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.31-r0/glibc-2.31-r0.apk
RUN wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.31-r0/glibc-bin-2.31-r0.apk
RUN wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.31-r0/glibc-i18n-2.31-r0.apk
RUN apk add glibc-2.31-r0.apk glibc-bin-2.31-r0.apk glibc-i18n-2.31-r0.apk
RUN /usr/glibc-compat/bin/localedef -i en_US -f UTF-8 en_US.UTF-8
RUN apk add --no-cache libstdc++

# install Hasura Cli
RUN apk add curl
RUN curl -L https://github.com/hasura/graphql-engine/raw/stable/cli/get.sh | sh

ARG NODE_ENV=development
ENV NODE_ENV $NODE_ENV
ENV PORT 3000
Expand Down
17 changes: 17 additions & 0 deletions db/00_init-schema.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
CREATE SCHEMA IF NOT EXISTS auth;

CREATE EXTENSION IF NOT EXISTS pgcrypto;
CREATE EXTENSION IF NOT EXISTS citext;

CREATE OR REPLACE FUNCTION public.set_current_timestamp_updated_at() RETURNS trigger
LANGUAGE plpgsql
AS $$
declare
_new record;
begin
_new := new;
_new. "updated_at" = now();
return _new;
end;
$$;

4 changes: 4 additions & 0 deletions db/hasura/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version: 2
endpoint: http://localhost:8080
metadata_directory: metadata
admin_secret: a_long_secret_that_should_never_be_used_in_production
2 changes: 2 additions & 0 deletions db/hasura/metadata/actions.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@


File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
109 changes: 109 additions & 0 deletions db/migrations/00001_create-initial-tables.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
CREATE TABLE IF NOT EXISTS auth.account_providers (
id uuid DEFAULT public.gen_random_uuid() NOT NULL,
created_at timestamp with time zone DEFAULT now() NOT NULL,
updated_at timestamp with time zone DEFAULT now() NOT NULL,
account_id uuid NOT NULL,
auth_provider text NOT NULL,
auth_provider_unique_id text NOT NULL
);

CREATE TABLE IF NOT EXISTS auth.account_roles (
id uuid DEFAULT public.gen_random_uuid() NOT NULL,
created_at timestamp with time zone DEFAULT now() NOT NULL,
account_id uuid NOT NULL,
role text NOT NULL
);

CREATE TABLE IF NOT EXISTS auth.accounts (
id uuid DEFAULT public.gen_random_uuid() NOT NULL,
created_at timestamp with time zone DEFAULT now() NOT NULL,
updated_at timestamp with time zone DEFAULT now() NOT NULL,
user_id uuid NOT NULL,
active boolean DEFAULT false NOT NULL,
email public.citext,
new_email public.citext,
password_hash text,
default_role text DEFAULT 'user'::text NOT NULL,
is_anonymous boolean DEFAULT false NOT NULL,
custom_register_data jsonb,
otp_secret text,
mfa_enabled boolean DEFAULT false NOT NULL,
ticket uuid DEFAULT public.gen_random_uuid() NOT NULL,
ticket_expires_at timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT proper_email CHECK ((email OPERATOR(public.~*) '^[A-Za-z0-9._+%-]+@[A-Za-z0-9.-]+[.][A-Za-z]+$'::public.citext)),
CONSTRAINT proper_new_email CHECK ((new_email OPERATOR(public.~*) '^[A-Za-z0-9._+%-]+@[A-Za-z0-9.-]+[.][A-Za-z]+$'::public.citext))
);

CREATE TABLE IF NOT EXISTS auth.providers (
provider text NOT NULL
);

CREATE TABLE IF NOT EXISTS auth.refresh_tokens (
refresh_token uuid NOT NULL,
created_at timestamp with time zone DEFAULT now() NOT NULL,
expires_at timestamp with time zone NOT NULL,
account_id uuid NOT NULL
);

CREATE TABLE IF NOT EXISTS auth.roles (
role text NOT NULL
);

CREATE TABLE IF NOT EXISTS public.users (
id uuid DEFAULT public.gen_random_uuid() NOT NULL,
created_at timestamp with time zone DEFAULT now() NOT NULL,
updated_at timestamp with time zone DEFAULT now() NOT NULL,
display_name text,
avatar_url text
);

CREATE OR REPLACE FUNCTION create_constraint_if_not_exists (t_name text, c_name text, constraint_sql text)
RETURNS void
AS
$BODY$
BEGIN
-- Look for our constraint
IF NOT EXISTS (SELECT constraint_name
FROM information_schema.constraint_column_usage
WHERE constraint_name = c_name) THEN
EXECUTE 'ALTER TABLE ' || t_name || ' ADD CONSTRAINT ' || c_name || ' ' || constraint_sql;
END IF;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;

SELECT create_constraint_if_not_exists('auth.account_providers', 'account_providers_account_id_auth_provider_key', 'UNIQUE (account_id, auth_provider);');
SELECT create_constraint_if_not_exists('auth.account_providers', 'account_providers_auth_provider_auth_provider_unique_id_key', 'UNIQUE (auth_provider, auth_provider_unique_id);');
SELECT create_constraint_if_not_exists('auth.account_providers', 'account_providers_pkey', 'PRIMARY KEY (id);');
SELECT create_constraint_if_not_exists('auth.account_roles', 'account_roles_pkey', 'PRIMARY KEY (id);');
SELECT create_constraint_if_not_exists('auth.accounts', 'accounts_email_key', 'UNIQUE (email);');
SELECT create_constraint_if_not_exists('auth.accounts', 'accounts_new_email_key', 'UNIQUE (new_email);');
SELECT create_constraint_if_not_exists('auth.accounts', 'accounts_pkey', 'PRIMARY KEY (id);');
SELECT create_constraint_if_not_exists('auth.accounts', 'accounts_user_id_key', 'UNIQUE (user_id);');
SELECT create_constraint_if_not_exists('auth.providers', 'providers_pkey', 'PRIMARY KEY (provider);');
SELECT create_constraint_if_not_exists('auth.refresh_tokens', 'refresh_tokens_pkey', 'PRIMARY KEY (refresh_token);');
SELECT create_constraint_if_not_exists('auth.roles', 'roles_pkey', 'PRIMARY KEY (role);');
SELECT create_constraint_if_not_exists('auth.account_roles', 'user_roles_account_id_role_key', 'UNIQUE (account_id, role);');
SELECT create_constraint_if_not_exists('public.users', 'users_pkey', 'PRIMARY KEY (id);');
SELECT create_constraint_if_not_exists('auth.account_providers', 'account_providers_account_id_fkey', 'FOREIGN KEY (account_id) REFERENCES auth.accounts(id) ON UPDATE CASCADE ON DELETE CASCADE;');
SELECT create_constraint_if_not_exists('auth.account_providers', 'account_providers_auth_provider_fkey', 'FOREIGN KEY (auth_provider) REFERENCES auth.providers(provider) ON UPDATE RESTRICT ON DELETE RESTRICT;');
SELECT create_constraint_if_not_exists('auth.account_roles', 'account_roles_account_id_fkey', 'FOREIGN KEY (account_id) REFERENCES auth.accounts(id) ON UPDATE CASCADE ON DELETE CASCADE;');
SELECT create_constraint_if_not_exists('auth.account_roles', 'account_roles_role_fkey', 'FOREIGN KEY (role) REFERENCES auth.roles(role) ON UPDATE CASCADE ON DELETE RESTRICT;');
SELECT create_constraint_if_not_exists('auth.accounts', 'accounts_default_role_fkey', 'FOREIGN KEY (default_role) REFERENCES auth.roles(role) ON UPDATE CASCADE ON DELETE RESTRICT;');
SELECT create_constraint_if_not_exists('auth.accounts', 'accounts_user_id_fkey', 'FOREIGN KEY (user_id) REFERENCES public.users(id) ON UPDATE CASCADE ON DELETE CASCADE;');
SELECT create_constraint_if_not_exists('auth.refresh_tokens', 'refresh_tokens_account_id_fkey', 'FOREIGN KEY (account_id) REFERENCES auth.accounts(id) ON UPDATE CASCADE ON DELETE CASCADE;');

DROP TRIGGER IF EXISTS set_auth_account_providers_updated_at ON auth.account_providers;
CREATE TRIGGER set_auth_account_providers_updated_at BEFORE UPDATE ON auth.account_providers FOR EACH ROW EXECUTE FUNCTION public.set_current_timestamp_updated_at();

DROP TRIGGER IF EXISTS set_auth_accounts_updated_at ON auth.accounts;
CREATE TRIGGER set_auth_accounts_updated_at BEFORE UPDATE ON auth.accounts FOR EACH ROW EXECUTE FUNCTION public.set_current_timestamp_updated_at();

DROP TRIGGER IF EXISTS set_public_users_updated_at ON public.users;
CREATE TRIGGER set_public_users_updated_at BEFORE UPDATE ON public.users FOR EACH ROW EXECUTE FUNCTION public.set_current_timestamp_updated_at();

INSERT INTO auth.roles (role)
VALUES ('user'), ('anonymous'), ('me') ON CONFLICT DO NOTHING;

INSERT INTO auth.providers (provider)
VALUES ('github'), ('facebook'), ('twitter'), ('google'), ('apple'), ('linkedin'), ('windowslive'), ('spotify') ON CONFLICT DO NOTHING;
1 change: 1 addition & 0 deletions docker-compose.development.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
version: '3.6'
services:
hasura-backend-plus:
command: npm run dev-command
build:
context: .
dockerfile: Dockerfile.dev
Expand Down
10 changes: 4 additions & 6 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ services:
image: postgres:12
restart: always
volumes:
- db_data:/var/lib/postgresql/data
- ./data/db:/var/lib/postgresql/data
- ./db:/docker-entrypoint-initdb.d/
environment:
POSTGRES_PASSWORD: '${POSTGRES_PASSWORD:-postgrespassword}'
graphql-engine:
image: hasura/graphql-engine:v1.2.1
image: hasura/graphql-engine:v1.3.3
depends_on:
- 'postgres'
restart: always
Expand All @@ -34,13 +35,10 @@ services:
image: minio/minio
restart: always
volumes:
- 'minio_data:/data'
- ./data/minio:/data
environment:
S3_BUCKET: '${S3_BUCKET:-hasura-backend-plus}'
MINIO_ACCESS_KEY: '${S3_ACCESS_KEY_ID:-minio_access_key}' ## min 8 character
MINIO_SECRET_KEY: '${S3_SECRET_ACCESS_KEY:?S3_SECRET_ACCESS_KEY}' ## min 8 character
entrypoint: sh
command: "-c 'mkdir -p /data/$${S3_BUCKET:-hasura-backend-plus} && /usr/bin/minio server /data'"
volumes:
db_data:
minio_data:
1 change: 0 additions & 1 deletion examples/simple-hasura-minio/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ services:
S3_BUCKET: hasura-backend-plus
S3_ACCESS_KEY_ID: minio_access_key
S3_SECRET_ACCESS_KEY: '${S3_SECRET_ACCESS_KEY:?S3_SECRET_ACCESS_KEY}'
AUTO_MIGRATE: 'true'
minio:
image: minio/minio
restart: always
Expand Down
4 changes: 2 additions & 2 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
module.exports = {
globalSetup: './src/test/jest-global-setup.ts',
globalSetup: '<rootDir>/src/test/global-setup.ts',
verbose: true,
moduleNameMapper: {
'^@shared/(.*)$': '<rootDir>/src/shared/$1',
'^@test/(.*)$': '<rootDir>/src/test/$1'
},
testPathIgnorePatterns: ['<rootDir>/dist/', '<rootDir>/node_modules/'],
setupFilesAfterEnv: ['jest-extended'],
setupFilesAfterEnv: ['jest-extended', '<rootDir>/src/test/setup.ts'],
// transform: {
// '^.+\\.ts?$': 'ts-jest'
// }
Expand Down
Empty file removed metadata/actions.graphql
Empty file.
Empty file.
Loading