Skip to content

Commit

Permalink
all: add support for migrate test (#176)
Browse files Browse the repository at this point in the history
  • Loading branch information
datdao authored Jun 24, 2024
1 parent 03ac207 commit cd8c820
Show file tree
Hide file tree
Showing 13 changed files with 10,868 additions and 6 deletions.
25 changes: 25 additions & 0 deletions .github/workflows/ci-go.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,31 @@ jobs:
# Verifies that the output we got for lint tests are URLs as expected
[[ "${{ steps.lint_success.outputs.report-url }}" =~ ^https://[a-zA-Z-]*\.atlasgo\.[a-zA-Z-]*/.*$ ]]
[[ "${{ steps.lint_failure.outputs.report-url }}" =~ ^https://[a-zA-Z-]*\.atlasgo\.[a-zA-Z-]*/.*$ ]]
- id: test_success
uses: ./migrate/test
with:
dir: file://migrations
working-directory: atlasaction/testdata
dev-url: sqlite://file.db?mode=memory
run: "expected_success"
env:
GITHUB_TOKEN: ${{ github.token }}
- id: test_failure
uses: ./migrate/test
continue-on-error: true
with:
working-directory: atlasaction/testdata
dir: file://migrations
dev-url: sqlite://file.db?mode=memory
run: "expected_failure"
env:
GITHUB_TOKEN: ${{ github.token }}
- id: check-test-failure
if: steps.test_failure.outcome == 'success'
uses: actions/github-script@v3
with:
script: |
core.setFailed('expected test to fail, but it did not')
migrate-down:
runs-on: ubuntu-latest
steps:
Expand Down
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ To learn more about the recommended way to build workflows, read our guide on
| [ariga/atlas-action/migrate/lint](#arigaatlas-actionmigratelint) | Lint migrations (required `atlas login` ) |
| [ariga/atlas-action/migrate/apply](#arigaatlas-actionmigrateapply) | Apply migrations to a database |
| [ariga/atlas-action/migrate/down](#arigaatlas-actionmigratedown) | Revert migrations to a database |
| [ariga/atlas-action/migrate/test](#arigaatlas-actionmigratetest) | Test migrations on a database |

## Examples

Expand Down Expand Up @@ -290,6 +291,28 @@ All inputs are optional as they may be specified in the Atlas configuration file
* `reverted_count` - The number of migrations that were reverted.
* `url` - The URL of the plan to review and approve / reject.

### `ariga/atlas-action/migrate/test`

Test migrations on a database.

#### Inputs

All inputs are optional as they may be specified in the Atlas configuration file.

* `dev-url` - 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).
* `dir` - The URL of the migration directory to apply. For example: `atlas://dir-name` for cloud
based directories or `file://migrations` for local ones.
* `run` - Filter tests to run by regexp. For example, `^test_.*` will only run tests that start with `test_`.
Default is to run all tests.
* `config` - The URL of 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).
* `env` - The environment to use from the Atlas configuration file. For example, `dev`.
* `vars` - Stringify JSON object containing variables to be used inside the Atlas configuration file.
For example: `'{"var1": "value1", "var2": "value2"}'`.
* `working-directory` - The working directory to run from. Defaults to project root.

### Legal

The source code for this GitHub Action is released under the Apache 2.0
Expand Down
25 changes: 25 additions & 0 deletions atlasaction/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,31 @@ func MigrateLint(ctx context.Context, client *atlasexec.Client, act Action) erro
return nil
}

// MigrateTest runs the GitHub Action for "ariga/atlas-action/migrate/test"
func MigrateTest(ctx context.Context, client *atlasexec.Client, act Action) error {
var vars atlasexec.Vars
if v := act.GetInput("vars"); v != "" {
if err := json.Unmarshal([]byte(v), &vars); err != nil {
return fmt.Errorf("failed to parse vars: %w", err)
}
}
params := &atlasexec.MigrateTestParams{
DirURL: act.GetInput("dir"),
DevURL: act.GetInput("dev-url"),
Run: act.GetInput("run"),
ConfigURL: act.GetInput("config"),
Env: act.GetInput("env"),
Vars: vars,
}
result, err := client.MigrateTest(ctx, params)
if err != nil {
return fmt.Errorf("`atlas migrate test` completed with errors:\n%s", err)
}
act.Infof("`atlas migrate test` completed successfully, no issues found")
act.Infof(result)
return nil
}

// Returns true if the summary report has diagnostics or errors.
func hasComments(s *atlasexec.SummaryReport) bool {
for _, f := range s.Files {
Expand Down
29 changes: 29 additions & 0 deletions atlasaction/action_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,35 @@ func TestMigratePushWithCloud(t *testing.T) {
})
}

func TestMigrateTest(t *testing.T) {
t.Run("all inputs", func(t *testing.T) {
tt := newT(t)
tt.cli, _ = atlasexec.NewClient("", "./mock-atlas-test.sh")
os.Remove("test-out.txt")
t.Cleanup(func() {
os.Remove("test-out.txt")
})
tt.setInput("dir", "file://testdata/migrations")
tt.setInput("dev-url", "sqlite://file?mode=memory")
tt.setInput("run", "example")
tt.setInput("config", "file://testdata/config/atlas.hcl")
tt.setInput("env", "test")
tt.setInput("vars", `{"var1": "value1", "var2": "value2"}`)
err := MigrateTest(context.Background(), tt.cli, tt.act)
require.NoError(t, err)
out, err := os.ReadFile("test-out.txt")
require.NoError(t, err)
lines := strings.Split(strings.TrimSpace(string(out)), "\n")
require.Len(t, lines, 1)
require.Contains(t, lines[0], "--env test")
require.Contains(t, lines[0], "--run example")
require.Contains(t, lines[0], "--var var1=value1")
require.Contains(t, lines[0], "--var var2=value2")
require.Contains(t, lines[0], "--dir file://testdata/migrations")
require.Contains(t, lines[0], "--dev-url sqlite://file?mode=memory")
})
}

func TestMigrateE2E(t *testing.T) {
type (
pushDir struct {
Expand Down
2 changes: 2 additions & 0 deletions atlasaction/mock-atlas-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/bash
echo $@ >> test-out.txt
19 changes: 19 additions & 0 deletions atlasaction/testdata/migrations.test.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
test "migrate" "expected_success" {
migrate {
to = "20230922132634"
}
exec {
sql = "select * from t1"
output = ""
}
}

test "migrate" "expected_failure" {
migrate {
to = "20230922132634"
}
exec {
sql = "select * from t1"
output = "0"
}
}
3 changes: 3 additions & 0 deletions cmd/atlas-action/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const (
CmdMigrateLint = "migrate/lint"
CmdMigrateApply = "migrate/apply"
CmdMigrateDown = "migrate/down"
CmdMigrateTest = "migrate/test"
)

var cli RunAction
Expand Down Expand Up @@ -84,6 +85,8 @@ func (r *RunAction) Run(ctx context.Context, client *atlasexec.Client, action at
return atlasaction.MigratePush(ctx, client, action)
case CmdMigrateLint:
return atlasaction.MigrateLint(ctx, client, action)
case CmdMigrateTest:
return atlasaction.MigrateTest(ctx, client, action)
}
return fmt.Errorf("unknown action: %s", r.Action)
}
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ toolchain go1.22.0

require (
ariga.io/atlas v0.21.2-0.20240418081819-02b3f6239b04
ariga.io/atlas-go-sdk v0.5.6-0.20240619082333-a9fdd42c282f
ariga.io/atlas-go-sdk v0.5.7-0.20240621080352-37a79ac08f34
github.com/alecthomas/kong v0.8.0
github.com/mattn/go-sqlite3 v1.14.17
github.com/mitchellh/mapstructure v1.1.2
Expand Down
10 changes: 6 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
ariga.io/atlas v0.21.2-0.20240418081819-02b3f6239b04 h1:YF3qiqtnhn+y4tfhZKTfZKfizpjqHYt7rWPUb+eA4ZA=
ariga.io/atlas v0.21.2-0.20240418081819-02b3f6239b04/go.mod h1:VPlcXdd4w2KqKnH54yEZcry79UAhpaWaxEsmn5JRNoE=
ariga.io/atlas-go-sdk v0.5.5-0.20240616123349-321ed4f6f793 h1:yK2p2lD9AIxXezosE1pZW3xZ0DJbSFwwGjznvC5ELX0=
ariga.io/atlas-go-sdk v0.5.5-0.20240616123349-321ed4f6f793/go.mod h1:9Q+/04PVyJHUse1lEE9Kp6E18xj/6mIzaUTcWYSjSnQ=
ariga.io/atlas-go-sdk v0.5.6-0.20240619082333-a9fdd42c282f h1:EJb6n4kzPhdpSoI8Ugv2W+vdYlGUVtRpGAct2iNS2a8=
ariga.io/atlas-go-sdk v0.5.6-0.20240619082333-a9fdd42c282f/go.mod h1:9Q+/04PVyJHUse1lEE9Kp6E18xj/6mIzaUTcWYSjSnQ=
ariga.io/atlas-go-sdk v0.5.4-0.20240509103754-bec74f82c66e h1:k4llFPMKcRQPHiu0/pf4DtylguW17xGz9VI4KmRgcVo=
ariga.io/atlas-go-sdk v0.5.4-0.20240509103754-bec74f82c66e/go.mod h1:9Q+/04PVyJHUse1lEE9Kp6E18xj/6mIzaUTcWYSjSnQ=
ariga.io/atlas-go-sdk v0.5.6 h1:7Hb5AyvrCeVZpQeHVqn6PbdEBm/YocgSCL4UafE2Les=
ariga.io/atlas-go-sdk v0.5.6/go.mod h1:9Q+/04PVyJHUse1lEE9Kp6E18xj/6mIzaUTcWYSjSnQ=
ariga.io/atlas-go-sdk v0.5.7-0.20240621080352-37a79ac08f34 h1:jjeCychy4CvNQtkl7kV98Q3DT2WIRrP39ejNf4HHETY=
ariga.io/atlas-go-sdk v0.5.7-0.20240621080352-37a79ac08f34/go.mod h1:9Q+/04PVyJHUse1lEE9Kp6E18xj/6mIzaUTcWYSjSnQ=
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
Expand Down
41 changes: 41 additions & 0 deletions migrate/test/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: 'Migrate Test'
description: 'CI for database schema changes with Atlas'
branding:
icon: database
author: 'Ariga'
inputs:
dev-url:
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).
required: false
dir:
description: |
The URL of the migration directory to apply. For example: `atlas://dir-name` for cloud
based directories or `file://migrations` for local ones.
required: false
run:
description: |
Filter tests to run by regexp. For example, `^test_.*` will only run tests that start with `test_`.
Default is to run all tests.
required: false
config:
description: |
The URL of 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).
required: false
env:
description: The environment to use from the Atlas configuration file. For example, `dev`.
required: false
working-directory:
description: Atlas working directory, default is project root
required: false
vars:
description: |
A JSON object containing variables to be used in the Atlas configuration file.
For example, `{"var1": "value1", "var2": "value2"}`.
required: false
runs:
using: node20
main: dist/index.js
Loading

0 comments on commit cd8c820

Please sign in to comment.