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

tests: add Atlas migration tests #13

Draft
wants to merge 17 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
* text=auto

test/**/data/* text eol=lf
test/**/data/* text eol=lf
src/**/migrations/** text eol=lf
126 changes: 28 additions & 98 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,12 @@ jobs:
path: "./artifacts"

test-tool:
name: Test Tool (${{ matrix.os }})
name: Test tool on ${{ matrix.os }} - ${{ matrix.dialect }}
needs: build
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
os: [windows-latest]
dialect: [postgres]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
Expand All @@ -82,103 +83,32 @@ jobs:
- name: Print SQL from Demo project
shell: pwsh
working-directory: ./src/Atlas.Provider.Demo
run: dotnet atlas-ef -- sqlserver

test:
name: Test (${{ matrix.os }})
needs: build
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/[email protected]
with:
lfs: true
fetch-depth: 0
- name: Install .NET Core SDK
uses: actions/[email protected]
with:
dotnet-version: |
6.0.x
8.0.x
- name: Dotnet Tool Restore
shell: pwsh
run: dotnet tool restore
- name: Dotnet restore
shell: pwsh
run: dotnet restore
- name: Dotnet Cake Test
shell: pwsh
run: dotnet cake --target=Test
- name: Upload test results
uses: actions/upload-artifact@v4
with:
name: test-artifacts ( ${{ matrix.os }} )
path: "./artifacts/**/*.xml"

publish-test-results:
name: Publish Tests Results
needs: test
if: always()
permissions:
checks: write
pull-requests: write
runs-on: ubuntu-latest
steps:
- name: Download Artifacts
uses: actions/download-artifact@v4
with:
path: "./artifacts"
- name: Publish Test Summary
uses: test-summary/action@v2
if: always()
with:
paths: "./artifacts/*/*.xml"

push-github-packages:
name: Push GitHub Packages
needs: test
if: github.event_name == 'release' || github.ref == 'refs/heads/master'
environment:
name: GitHub Packages
url: https://github.com/${{ github.repository }}/packages
permissions:
packages: write
runs-on: windows-latest
steps:
- name: Download Artifact
uses: actions/download-artifact@v4
with:
name: build-artifacts
- name: Dotnet NuGet Add Source
shell: pwsh
run: dotnet tool restore && dotnet atlas-ef -- sqlserver
- name: Install Atlas CLI (Windows)
shell: bash
if: startsWith(runner.os, 'Windows')
run: |
dotnet nuget add source https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json `
--name GitHub --username ${{ github.repository_owner }} --password ${{ secrets.GITHUB_TOKEN }}
- name: Dotnet NuGet Push
mkdir "${{ runner.temp }}/bin"
curl -fSL https://release.ariga.io/atlas/atlas-windows-amd64-latest.exe -o "${{ runner.temp }}\bin\atlas.exe"
echo "${{ runner.temp }}\bin" >> $GITHUB_PATH
- name: Install Atlas CLI (Ubuntu / MacOS)
shell: pwsh
run: dotnet nuget push .\*.nupkg --api-key ${{ github.token }} --source GitHub --skip-duplicate

push-nuget:
name: Push NuGet Packages
needs: test
if: github.event_name == 'release'
environment:
name: NuGet
url: https://www.nuget.org/packages/atlas-ef
runs-on: windows-latest
steps:
- name: Download Artifact
uses: actions/download-artifact@v4
with:
name: build-artifacts
- name: Dotnet NuGet Push
if: startsWith(runner.os, 'Linux') || startsWith(runner.os, 'macOS')
run: curl -sSf 'https://atlasgo.sh?test=1' | sh
- name: Verify Atlas CLI version
shell: pwsh
run: atlas version
- name: Check migrations for ${{ matrix.dialect }}
working-directory: ./src/Atlas.Provider.Demo
run: |
atlas migrate diff --env ef --var dialect=${{ matrix.dialect }}
env:
ATLAS_TOKEN: ${{ secrets.ATLAS_TOKEN }}
- name: Verify migrations generated
shell: bash
run: |
Get-ChildItem .\ -Filter *.nupkg |
Where-Object { !$_.Name.Contains('preview') } |
ForEach-Object {
dotnet nuget push $_ --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
}
if git status --porcelain | grep -vq 'dotnet-tools.json' ; then
echo "you need to run 'atlas migrate diff --env ef' and commit the changes"
git --no-pager diff
exit 1
fi
128 changes: 64 additions & 64 deletions src/Atlas.Provider.Core/Program.cs
Original file line number Diff line number Diff line change
@@ -1,65 +1,65 @@
using System;
using System.IO;
using Atlas.Provider.Core.Executor;
namespace Atlas.Provider.Core
{
static class Program
{
static int Main(string[] args)
{
try
{
var options = new Options(args);
// prevent any output from being written to the stdout, including warn, info, error etc messages from EF Core
var originalOut = Console.Out;
Console.SetOut(Console.Error);
using var executor = new EFDesign(
options.Assembly,
options.StartupAssembly,
options.ProjectDir,
null,
options.RootNamespace,
options.Language,
options.Nullable,
options.PositionalArgs?.ToArray()
);
var types = executor.GetContextTypes();
foreach (var type in types)
{
if (!type.Contains("Name") || type["Name"] == null)
{
continue;
}
var name = type["Name"]!.ToString();
if (string.IsNullOrEmpty(name))
{
continue;
}
var ctxInfo = executor.GetContextInfo(name);
if (ctxInfo == null || !ctxInfo.Contains("ProviderName") || ctxInfo["ProviderName"] == null)
{
continue;
}
var sql = executor.ScriptDbContext(name);
Console.SetOut(originalOut);
Console.Out.NewLine = "\n";
if (!string.IsNullOrEmpty(sql))
{
if (ctxInfo["ProviderName"]!.ToString()!.EndsWith("SqlServer"))
{
Console.WriteLine("-- atlas:delimiter GO");
}
Console.WriteLine(sql.Replace(Environment.NewLine, "\n"));
}
}
return 0;
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.Message);
return 1;
}
}
}
using System;
using System.IO;
using Atlas.Provider.Core.Executor;

namespace Atlas.Provider.Core
{
static class Program
{
static int Main(string[] args)
{
try
{
var options = new Options(args);
// prevent any output from being written to the stdout, including warn, info, error etc messages from EF Core
var originalOut = Console.Out;
Console.SetOut(Console.Error);
using var executor = new EFDesign(
options.Assembly,
options.StartupAssembly,
options.ProjectDir,
null,
options.RootNamespace,
options.Language,
options.Nullable,
options.PositionalArgs?.ToArray()
);
var types = executor.GetContextTypes();
foreach (var type in types)
{
if (!type.Contains("Name") || type["Name"] == null)
{
continue;
}
var name = type["Name"]!.ToString();
if (string.IsNullOrEmpty(name))
{
continue;
}
var ctxInfo = executor.GetContextInfo(name);
if (ctxInfo == null || !ctxInfo.Contains("ProviderName") || ctxInfo["ProviderName"] == null)
{
continue;
}
var sql = executor.ScriptDbContext(name);
Console.SetOut(originalOut);
Console.Out.NewLine = "\n";
if (!string.IsNullOrEmpty(sql))
{
if (ctxInfo["ProviderName"]!.ToString()!.EndsWith("SqlServer"))
{
Console.WriteLine("-- atlas:delimiter GO");
}
Console.WriteLine(sql.Replace(Environment.NewLine, "\n"));
}
}
return 0;
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.Message);
return 1;
}
}
}
}
13 changes: 13 additions & 0 deletions src/Atlas.Provider.Demo/.config/dotnet-tools.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"version": 1,
"isRoot": true,
"tools": {
"atlas-ef": {
"version": "0.2.0",
"commands": [
"atlas-ef"
],
"rollForward": false
}
}
}
34 changes: 34 additions & 0 deletions src/Atlas.Provider.Demo/atlas.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
variable "dialect" {
type = string
}

locals {
dev_url = {
mysql = "docker://mysql/8/dev"
postgres = "docker://postgres/15"
sqlserver = "docker://sqlserver/2022-latest"
sqlite = "sqlite://file::memory:?cache=shared"
}[var.dialect]
}

data "external_schema" "ef" {
program = [
"dotnet",
"atlas-ef",
"--", var.dialect,
]
}

env {
name = atlas.env
src = data.external_schema.ef.url
dev = local.dev_url
migration {
dir = "file://migrations/${var.dialect}"
}
format {
migrate {
diff = "{{ sql . \" \" }}"
}
}
}
21 changes: 21 additions & 0 deletions src/Atlas.Provider.Demo/migrations/mysql/20240801062628.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
-- Create "Blogs" table
CREATE TABLE `Blogs` (
`BlogId` int NOT NULL AUTO_INCREMENT,
`Url` varchar(200) NOT NULL,
`Rating` decimal(5,2) NOT NULL,
`Title` longtext NOT NULL,
`Content` longtext NOT NULL,
`Author` varchar(200) NOT NULL DEFAULT "Anonymous",
PRIMARY KEY (`BlogId`),
UNIQUE INDEX `AK_Blogs_Url` (`Url`)
) CHARSET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
-- Create "Post" table
CREATE TABLE `Post` (
`PostId` int NOT NULL AUTO_INCREMENT,
`Title` longtext NOT NULL,
`Content` longtext NOT NULL,
`BlogUrl` varchar(200) NULL,
PRIMARY KEY (`PostId`),
INDEX `IX_Post_BlogUrl` (`BlogUrl`),
CONSTRAINT `FK_Post_Blogs_BlogUrl` FOREIGN KEY (`BlogUrl`) REFERENCES `Blogs` (`Url`) ON UPDATE NO ACTION ON DELETE NO ACTION
) CHARSET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
2 changes: 2 additions & 0 deletions src/Atlas.Provider.Demo/migrations/mysql/20240827163211.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- Modify "Blogs" table
ALTER TABLE `Blogs` MODIFY COLUMN `Content` longtext NOT NULL COMMENT "Content contains new lines \\n\\r and \n for example";
3 changes: 3 additions & 0 deletions src/Atlas.Provider.Demo/migrations/mysql/atlas.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
h1:a2dOeFlhAZPmpRHZPrEo3yzDipUa59zYQPM2/qXU/P0=
20240801062628.sql h1:Fe+/2wnZoHlL8dkd4M+AUQ5HDN8MWOqO+HYRiKNgVkg=
20240827163211.sql h1:8n/hMWgMkoQW05VQ3WUUXcfYAcwfonDo3igPOzPziLE=
22 changes: 22 additions & 0 deletions src/Atlas.Provider.Demo/migrations/postgres/20240801063041.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
-- Create "Blogs" table
CREATE TABLE "public"."Blogs" (
"BlogId" integer NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"Url" character varying(200) NOT NULL,
"Rating" numeric(5,2) NOT NULL,
"Title" text NOT NULL,
"Content" text NOT NULL,
"Author" character varying(200) NOT NULL DEFAULT 'Anonymous',
PRIMARY KEY ("BlogId"),
CONSTRAINT "AK_Blogs_Url" UNIQUE ("Url")
);
-- Create "Post" table
CREATE TABLE "public"."Post" (
"PostId" integer NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"Title" text NOT NULL,
"Content" text NOT NULL,
"BlogUrl" character varying(200) NULL,
PRIMARY KEY ("PostId"),
CONSTRAINT "FK_Post_Blogs_BlogUrl" FOREIGN KEY ("BlogUrl") REFERENCES "public"."Blogs" ("Url") ON UPDATE NO ACTION ON DELETE NO ACTION
);
-- Create index "IX_Post_BlogUrl" to table: "Post"
CREATE INDEX "IX_Post_BlogUrl" ON "public"."Post" ("BlogUrl");
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-- Set comment to column: "Content" on table: "Blogs"
COMMENT ON COLUMN "public"."Blogs"."Content" IS 'Content contains new lines \n\r and
for example';
3 changes: 3 additions & 0 deletions src/Atlas.Provider.Demo/migrations/postgres/atlas.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
h1:tst+YUc91J4jm4dWLn3L1UM7+M+b0f8LsMQ6PPyGjtw=
20240801063041.sql h1:TeGzHV6ca+FPLdTm5X4jiMyXCui1YzmSjKKPtxorAi0=
20240827163245.sql h1:HI5dH/gAwh5AS2RS71HDoPTyg3ggzFBSLix+4mKQ3sw=
Loading
Loading