Skip to content

Commit

Permalink
src/commands: support schema plan (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
datdao authored Oct 7, 2024
1 parent cfa1ea9 commit 6d0b722
Show file tree
Hide file tree
Showing 6 changed files with 407 additions and 2 deletions.
148 changes: 147 additions & 1 deletion .circleci/test-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,123 @@ jobs:
grep -qe "INPUT_CONFIG=file://atlas.hcl" /tmp/env.out
# check vars should be set in the environment
grep -qe "INPUT_VARS={\"foo\": \"bar\", \"baz\": \"qux\", \"quux\": \"corge\"}" /tmp/env.out
command-test-schema-plan:
executor: atlas-orb/default
steps:
- checkout
- run:
name: Mock atlas with echo.sh
command: |
sudo cp ./src/scripts/echo.sh /bin/atlas
sudo cp ./src/scripts/echo.sh /bin/atlasaction
- atlas-orb/schema_plan:
working_directory: testdata/schema-plan
schema_name: "my-cool-project"
plan_name: "my-plan"
from: "atlas://my-cool-project?tag=latest"
to: "file://schema.hcl"
dev_url: "postgres://postgres:pass@localhost:5432/dev?sslmode=disable"
env: "circleci-test"
config: "file://atlas.hcl"
vars: '{"foo": "bar", "baz": "qux", "quux": "corge"}'
- run:
name: Check echo.out for expected output
command: |
grep -qe "--action schema/plan" /tmp/echo.out
# check schema_name should be set in the environment
grep -qe "INPUT_SCHEMA_NAME=my-cool-project" /tmp/env.out
# check plan_name should be set in the environment
grep -qe "INPUT_NAME=my-plan" /tmp/env.out
# check from should be set in the environment
grep -qe "INPUT_FROM=atlas://my-cool-project?tag=latest" /tmp/env.out
# check to should be set in the environment
grep -qe "INPUT_TO=file://schema.hcl" /tmp/env.out
# check dev_url should be set in the environment
grep -qe "INPUT_DEV_URL=postgres://postgres:pass@localhost:5432/dev?sslmode=disable" /tmp/env.out
# check env should be set in the environment
grep -qe "INPUT_ENV=circleci-test" /tmp/env.out
# check config should be set in the environment
grep -qe "INPUT_CONFIG=file://atlas.hcl" /tmp/env.out
# check vars should be set in the environment
grep -qe "INPUT_VARS={\"foo\": \"bar\", \"baz\": \"qux\", \"quux\": \"corge\"}" /tmp/env.out
command-test-schema-plan-approve:
executor: atlas-orb/default
steps:
- checkout
- run:
name: Mock atlas with echo.sh
command: |
sudo cp ./src/scripts/echo.sh /bin/atlas
sudo cp ./src/scripts/echo.sh /bin/atlasaction
- atlas-orb/schema_plan_approve:
working_directory: testdata/schema-plan
schema_name: "my-cool-project"
plan: "my-plan"
from: "atlas://my-cool-project?tag=latest"
to: "file://schema.hcl"
dev_url: "postgres://postgres:pass@localhost:5432/dev?sslmode=disable"
env: "circleci-test"
config: "file://atlas.hcl"
vars: '{"foo": "bar", "baz": "qux", "quux": "corge"}'
- run:
name: Check echo.out for expected output
command: |
grep -qe "--action schema/plan/approve" /tmp/echo.out
# check schema_name should be set in the environment
grep -qe "INPUT_SCHEMA_NAME=my-cool-project" /tmp/env.out
# check plan_name should be set in the environment
grep -qe "INPUT_PLAN=my-plan" /tmp/env.out
# check from should be set in the environment
grep -qe "INPUT_FROM=atlas://my-cool-project?tag=latest" /tmp/env.out
# check to should be set in the environment
grep -qe "INPUT_TO=file://schema.hcl" /tmp/env.out
# check dev_url should be set in the environment
grep -qe "INPUT_DEV_URL=postgres://postgres:pass@localhost:5432/dev?sslmode=disable" /tmp/env.out
# check env should be set in the environment
grep -qe "INPUT_ENV=circleci-test" /tmp/env.out
# check config should be set in the environment
grep -qe "INPUT_CONFIG=file://atlas.hcl" /tmp/env.out
# check vars should be set in the environment
grep -qe "INPUT_VARS={\"foo\": \"bar\", \"baz\": \"qux\", \"quux\": \"corge\"}" /tmp/env.out
command-test-schema-apply:
executor: atlas-orb/default
steps:
- checkout
- run:
name: Mock atlas with echo.sh
command: |
sudo cp ./src/scripts/echo.sh /bin/atlas
sudo cp ./src/scripts/echo.sh /bin/atlasaction
- atlas-orb/schema_apply:
working_directory: testdata/schema-apply
to: "file://schema.hcl"
plan: "atlas://my-cool-project/plans/id"
url: "postgres://postgres:pass@localhost:5432/test?sslmode=disable"
dev_url: "postgres://postgres:pass@localhost:5432/dev?sslmode=disable"
auto_approve: true
env: "circleci-test"
config: "file://atlas.hcl"
vars: '{"foo": "bar", "baz": "qux", "quux": "corge"}'
- run:
name: Check echo.out for expected output
command: |
grep -qe "--action schema/apply" /tmp/echo.out
# check schema_name should be set in the environment
grep -qe "INPUT_TO=file://schema.hcl" /tmp/env.out
# check plan should be set in the environment
grep -qe "INPUT_PLAN=atlas://my-cool-project/plans/id" /tmp/env.out
# check url should be set in the environment
grep -qe "INPUT_URL=postgres://postgres:pass@localhost:5432/test?sslmode=disable" /tmp/env.out
# check dev_url should be set in the environment
grep -qe "INPUT_DEV_URL=postgres://postgres:pass@localhost:5432/dev?sslmode=disable" /tmp/env.out
# check auto_approve should be set in the environment
grep -qe "INPUT_AUTO_APPROVE=1" /tmp/env.out
# check env should be set in the environment
grep -qe "INPUT_ENV=circleci-test" /tmp/env.out
# check config should be set in the environment
grep -qe "INPUT_CONFIG=file://atlas.hcl" /tmp/env.out
# check vars should be set in the environment
grep -qe "INPUT_VARS={\"foo\": \"bar\", \"baz\": \"qux\", \"quux\": \"corge\"}" /tmp/env.out
integration-test-versioned:
docker:
- image: cimg/base:current
Expand Down Expand Up @@ -486,11 +603,31 @@ jobs:
version: "latest"
cloud_token_env: "ATLAS_TOKEN"
- atlas-orb/schema_push:
working_directory: testdata/schema-push
working_directory: testdata/schema-plan
schema_name: "circleci-schema-test"
tag: "latest"
url: "postgres://postgres:pass@localhost:5432/test?sslmode=disable"
dev_url: postgres://postgres:pass@localhost:5432/dev?sslmode=disable
- atlas-orb/schema_plan:
working_directory: testdata/schema-plan
schema_name: "circleci-schema-test"
from: "atlas://circleci-schema-test?tag=latest"
to: "file://schema.hcl"
plan_name: << pipeline.git.revision >>
dev_url: postgres://postgres:pass@localhost:5432/dev?sslmode=disable
vars: '{"comment": "<< pipeline.git.revision >>"}'
- run:
name: Aprrove schema plan before apply
command: |
atlas schema plan approve --url atlas://circleci-schema-test/plans/<< pipeline.git.revision >>
- atlas-orb/schema_apply:
working_directory: testdata/schema-plan
to: "file://schema.hcl"
plan: "atlas://circleci-schema-test/plans/<< pipeline.git.revision >>"
url: "postgres://postgres:pass@localhost:5432/test?sslmode=disable"
dev_url: "postgres://postgres:pass@localhost:5432/dev?sslmode=disable"
auto_approve: true
vars: '{"comment": "<< pipeline.git.revision >>"}'
integration-test-declarative-gh-test:
docker:
- image: cimg/base:current
Expand Down Expand Up @@ -543,6 +680,12 @@ workflows:
filters: *filters
- command-test-schema-push:
filters: *filters
- command-test-schema-plan:
filters: *filters
- command-test-schema-plan-approve:
filters: *filters
- command-test-schema-apply:
filters: *filters
- integration-test-versioned:
context: ariga-atlas
filters: *filters
Expand Down Expand Up @@ -589,6 +732,9 @@ workflows:
- command-test-setup
- command-test-schema-test
- command-test-schema-push
- command-test-schema-plan
- command-test-schema-plan-approve
- command-test-schema-apply
- integration-test-declarative-gh-test:
context: ariga-atlas-gh
filters: *filters
Expand Down
71 changes: 71 additions & 0 deletions src/commands/schema_apply.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
description: >
Apply a declarative migrations to a database.
parameters:
to:
type: string
default: ''
description: |
The URL(s) of the desired schema state.
url:
type: string
default: ''
description: |
The URL of the target database. For example: `mysql://root:pass@localhost:3306/prod`.
plan:
type: string
default: ''
description: |
Optional plan file to use for applying the migrations. For example: `atlas://<schema>/plans/<id>`.
dry_run:
type: boolean
default: false
description: |
Print SQL (and optional analysis) without executing it. Either `true` or `false`. Defaults to `false`.
auto_approve:
type: boolean
default: false
description: |
Automatically approve and apply changes. Either `true` or `false`. Defaults to `false`.
dev_url:
type: string
default: ''
description: |
The URL of the dev-database to use for analysis. For example: mysql://root:pass@localhost:3306/dev.
Read more about [dev-databases](https://atlasgo.io/concepts/dev-database).
config:
type: string
default: ''
description: |
The path to the Atlas configuration file. By default, Atlas will look for a file named `atlas.hcl` in the current directory.
For example, `file://config/atlas.hcl`. Learn more about [Atlas configuration files](https://atlasgo.io/atlas-schema/projects).
vars:
type: string
default: ''
description: |
Stringify JSON object containing variables to be used inside the Atlas configuration file. For example: '{"var1": "value1", "var2": "value2"}'
working_directory:
type: string
default: "."
description: |
The working directory to run from. Defaults to project root.
env:
type: string
default: ''
description: |
The environment to use from the Atlas configuration file. For example, `dev`.
steps:
- run:
name: Apply a declarative migrations to a database
working_directory: <<parameters.working_directory>>
command: atlasaction --action schema/apply
environment:
INPUT_TO: <<parameters.to>>
INPUT_URL: <<parameters.url>>
INPUT_PLAN: <<parameters.plan>>
INPUT_DRY_RUN: <<parameters.dry_run>>
INPUT_AUTO_APPROVE: <<parameters.auto_approve>>
INPUT_DEV_URL: <<parameters.dev_url>>
INPUT_CONFIG: <<parameters.config>>
INPUT_ENV: <<parameters.env>>
INPUT_VARS: <<parameters.vars>>
85 changes: 85 additions & 0 deletions src/commands/schema_plan.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
description: >
Plan a declarative migration for a schema transition.
parameters:
schema_name:
type: string
default: ''
description: |
The name (slug) of the schema repository in [Atlas Registry](https://atlasgo.io/registry).
from:
type: string
default: ''
description: |
URL(s) of the current schema state to transition from.
to:
type: string
default: ''
description: |
URL(s) of the desired schema state to transition to.
plan_name:
type: string
default: ''
description: |
Optional name for the plan. If not provided, a default plan is generated by Atlas.
dev_url:
type: string
default: ''
description: |
The URL of the dev-database to use for analysis. For example: mysql://root:pass@localhost:3306/dev.
Read more about [dev-databases](https://atlasgo.io/concepts/dev-database).
config:
type: string
default: ''
description: |
The path to the Atlas configuration file. By default, Atlas will look for a file named `atlas.hcl` in the current directory.
For example, `file://config/atlas.hcl`. Learn more about [Atlas configuration files](https://atlasgo.io/atlas-schema/projects).
vars:
type: string
default: ''
description: |
Extra variables to pass to the Atlas configuration file. For example, `key=value`.
working_directory:
type: string
default: "."
description: |
The working directory to run from. Defaults to project root.
env:
type: string
default: ''
description: |
The environment to use from the Atlas configuration file. For example, `dev`.
github_repo_env:
type: env_var_name
default: GITHUB_REPOSITORY
description: |
The repository name that linting results will be posted to.
github_token_env:
type: env_var_name
default: GITHUB_TOKEN
description: |
Environment variable containing the GitHub token.
If provided, the command will authenticate to GitHub.
(e.g. `GITHUB_TOKEN`)
steps:
- run:
name: Plan a declarative migration for a schema transition
working_directory: <<parameters.working_directory>>
command: |
# replace GITHUB_REPOSITORY with the github_repo_env if provided
if [ -n "${<<parameters.github_repo_env>>}" ]; then
GITHUB_REPOSITORY=${<<parameters.github_repo_env>>}
fi
# replace GITHUB_TOKEN with the github_token_env if provided
if [ -n "${<<parameters.github_token_env>>}" ]; then
GITHUB_TOKEN=${<<parameters.github_token_env>>}
fi
atlasaction --action schema/plan
environment:
INPUT_SCHEMA_NAME: <<parameters.schema_name>>
INPUT_FROM: <<parameters.from>>
INPUT_TO: <<parameters.to>>
INPUT_NAME: <<parameters.plan_name>>
INPUT_DEV_URL: <<parameters.dev_url>>
INPUT_CONFIG: <<parameters.config>>
INPUT_ENV: <<parameters.env>>
INPUT_VARS: <<parameters.vars>>
Loading

0 comments on commit 6d0b722

Please sign in to comment.