Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
2cc72c0
feat:添加Admin后台管理
zhouda1fu Jan 20, 2026
6a1af5f
feat:将admin和demo code 相关的类文件在template.json中排除
zhouda1fu Jan 21, 2026
a96ac8c
feat:添加对UseAdmin和UseDemoCode的参数验证
zhouda1fu Jan 21, 2026
be6b3c8
fix:修复ABC.Template.Domain 命名空间无条件引入bug
Jan 22, 2026
f5fbd2b
fix:修复OrderTests测试类命名空间引用bug
Jan 22, 2026
6e17193
fix:修复template.json 的 (!UseDemoCode) 条件添加错误
Jan 22, 2026
b72df21
fix:修复template.json 的测试条件报错bug
Jan 22, 2026
2ed1b70
fix:修复template.json 的测试条件报错bug
Jan 22, 2026
e0feacc
fix:修复template.json 的测试条件报错bug
Jan 22, 2026
b78b338
fix:修复template.json 的测试条件报错bug
Jan 22, 2026
badd9c7
fix:修复template.json 的测试条件报错bug
Jan 22, 2026
84a9887
refactor: 移除 UseDemoCode 功能并优化迁移文件生成
Jan 22, 2026
87e0735
fix:修复种子数据未正确初始化的bug
Jan 22, 2026
d746227
fix:修复种子数据未正确初始化的bug
Jan 22, 2026
b5981a0
feat:删除多余接口并在aspire添加前端配置
Jan 22, 2026
0090800
fix:修复Aspire.Hosting.JavaScript包未引用错误
Jan 22, 2026
98f84e6
fix:修复Aspire.Hosting.JavaScript包引用错误
Jan 22, 2026
94cc696
feat:配置JWT认证
Jan 22, 2026
71ca176
feat:移除template.json中AppConfiguration的条件筛选
Jan 22, 2026
2b6ff7e
fix:修复命名空间未引用的问题
Jan 22, 2026
73ce42a
feat:将测试改成串行执行
Jan 22, 2026
d5d2a40
feat:增加测试时间
zhouda1fu Jan 22, 2026
0de2944
feat:添加前端frontend缺少的包
Jan 23, 2026
ad57f79
修改.gitignore 规则
Jan 23, 2026
34287c1
1
Jan 23, 2026
7c4b362
feat:在模板加入src/frontend/scripts/turbo-run/bin
Jan 23, 2026
1afa69b
feat:添加HelloEndpoint
Jan 23, 2026
791af7a
fix(template): 支持 MongoDB + UseAdmin 生成的 Web 项目
zhouda1fu Jan 24, 2026
0c7901b
fix:修复文件编码
zhouda1fu Jan 26, 2026
20718a0
fix:文件编码修复失败,先回滚到正确版本
Jan 27, 2026
06b6ff2
fix:将DateTimeOffset.Now换成DateTimeOffset.UtcNow
Jan 27, 2026
0a57326
fix:MongoDB支持事物,移除禁用自动事务
Jan 27, 2026
38cc54a
style: 统一 Endpoint 代码格式
zhouda1fu Jan 27, 2026
6a4368f
fix:修复FastEndpoints.Swagger命名空间未引入错误
zhouda1fu Jan 27, 2026
abf4251
fix:删除测试的项目上传
zhouda1fu Jan 27, 2026
7257519
feat: 添加权限映射辅助类,自动填充权限名称和描述
zhouda1fu Jan 27, 2026
7f73a30
fix:删除RolePermission不完整的构造函数
Jan 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
118 changes: 98 additions & 20 deletions .github/workflows/template-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ jobs:
matrix:
framework: [ 'net10.0', 'net8.0', 'net9.0' ]
aspire: [ 'true', 'false' ]
use-admin: [ 'true', 'false' ]
scenario:
# Test all databases with RabbitMQ
- { database: 'MySql', messagequeue: 'RabbitMQ' }
Expand All @@ -38,7 +39,7 @@ jobs:
- { database: 'MySql', messagequeue: 'NATS' }
- { database: 'MySql', messagequeue: 'AzureServiceBus' }
- { database: 'MySql', messagequeue: 'AmazonSQS' }
name: ${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}
name: ${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}-admin-${{ matrix.use-admin }}

steps:
- uses: actions/checkout@v3
Expand Down Expand Up @@ -68,53 +69,53 @@ jobs:
- name: Install template locally
run: dotnet new install .

- name: Generate project from template - ${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}
- name: Generate project from template - ${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}-admin-${{ matrix.use-admin }}
run: |
mkdir -p test-projects/${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}
cd test-projects/${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}
mkdir -p test-projects/${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}-admin-${{ matrix.use-admin }}
cd test-projects/${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}-admin-${{ matrix.use-admin }}
if [ "${{ matrix.aspire }}" == "true" ]; then
dotnet new netcorepal-web -n TestProject -F ${{ matrix.framework }} -D ${{ matrix.scenario.database }} -M ${{ matrix.scenario.messagequeue }} --UseAspire
dotnet new netcorepal-web -n TestProject -F ${{ matrix.framework }} -D ${{ matrix.scenario.database }} -M ${{ matrix.scenario.messagequeue }} --UseAspire --UseAdmin ${{ matrix.use-admin }}
else
dotnet new netcorepal-web -n TestProject -F ${{ matrix.framework }} -D ${{ matrix.scenario.database }} -M ${{ matrix.scenario.messagequeue }}
dotnet new netcorepal-web -n TestProject -F ${{ matrix.framework }} -D ${{ matrix.scenario.database }} -M ${{ matrix.scenario.messagequeue }} --UseAdmin ${{ matrix.use-admin }}
fi

- name: Restore dependencies for generated project
run: |
cd test-projects/${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}/TestProject
cd test-projects/${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}-admin-${{ matrix.use-admin }}/TestProject
# Restore dependencies, but allow missing preview packages
if ! dotnet restore --ignore-failed-sources; then
echo "❌ RESTORE FAILED for ${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}"
echo "❌ RESTORE FAILED for ${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}-admin-${{ matrix.use-admin }}"
exit 1
fi

- name: Build generated project
run: |
cd test-projects/${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}/TestProject
cd test-projects/${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}-admin-${{ matrix.use-admin }}/TestProject
# Build the project - this must succeed
if ! dotnet build --no-restore --configuration Release --verbosity minimal; then
echo "❌ BUILD FAILED for ${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}"
echo "❌ BUILD FAILED for ${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}-admin-${{ matrix.use-admin }}"
echo "Build logs:"
dotnet build --no-restore --configuration Release --verbosity normal
exit 1
fi
echo "✅ BUILD SUCCEEDED for ${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}"
echo "✅ BUILD SUCCEEDED for ${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}-admin-${{ matrix.use-admin }}"

- name: Run tests for generated project
if: ${{ inputs.include-tests }}
run: |
cd test-projects/${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}/TestProject
cd test-projects/${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}-admin-${{ matrix.use-admin }}/TestProject
# Run tests - this must succeed
if ! dotnet test --no-build --configuration Release \
--verbosity normal \
--logger "console;verbosity=normal"; then
echo "❌ TESTS FAILED for ${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}"
echo "❌ TESTS FAILED for ${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}-admin-${{ matrix.use-admin }}"
exit 1
fi
echo "✅ TESTS SUCCEEDED for ${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}"
echo "✅ TESTS SUCCEEDED for ${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}-admin-${{ matrix.use-admin }}"

- name: Verify project structure and templates
run: |
cd test-projects/${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}/TestProject
cd test-projects/${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}-admin-${{ matrix.use-admin }}/TestProject
echo "Project structure verification:"
ls -la src/
echo "Framework verification in csproj:"
Expand All @@ -141,10 +142,87 @@ jobs:
echo "✅ Aspire projects correctly not generated"
fi
fi
if [ "${{ matrix.use-admin }}" == "true" ]; then
echo "Verifying Admin files are present when UseAdmin=true"
if [ -d "src/TestProject.Domain/AggregatesModel/UserAggregate" ]; then
echo "✅ UserAggregate found"
else
echo "❌ UserAggregate not found when UseAdmin=true"
exit 1
fi
if [ -d "src/TestProject.Domain/AggregatesModel/RoleAggregate" ]; then
echo "✅ RoleAggregate found"
else
echo "❌ RoleAggregate not found when UseAdmin=true"
exit 1
fi
if [ -d "src/TestProject.Domain/AggregatesModel/DeptAggregate" ]; then
echo "✅ DeptAggregate found"
else
echo "❌ DeptAggregate not found when UseAdmin=true"
exit 1
fi
if [ -d "src/TestProject.Web/Endpoints/Identity/Admin" ]; then
echo "✅ Admin endpoints directory found"
else
echo "❌ Admin endpoints directory not found when UseAdmin=true"
exit 1
fi
if [ -d "src/frontend" ]; then
echo "✅ Frontend directory found"
else
echo "❌ Frontend directory not found when UseAdmin=true"
exit 1
fi
if [ -d "src/TestProject.Web/AppPermissions" ]; then
echo "✅ AppPermissions directory found"
else
echo "❌ AppPermissions directory not found when UseAdmin=true"
exit 1
fi
else
echo "Verifying Admin files are absent when UseAdmin=false"
if [ -d "src/TestProject.Domain/AggregatesModel/UserAggregate" ]; then
echo "❌ UserAggregate found when it should be excluded"
exit 1
else
echo "✅ UserAggregate correctly excluded"
fi
if [ -d "src/TestProject.Domain/AggregatesModel/RoleAggregate" ]; then
echo "❌ RoleAggregate found when it should be excluded"
exit 1
else
echo "✅ RoleAggregate correctly excluded"
fi
if [ -d "src/TestProject.Domain/AggregatesModel/DeptAggregate" ]; then
echo "❌ DeptAggregate found when it should be excluded"
exit 1
else
echo "✅ DeptAggregate correctly excluded"
fi
if [ -d "src/TestProject.Web/Endpoints/Identity/Admin" ]; then
echo "❌ Admin endpoints directory found when it should be excluded"
exit 1
else
echo "✅ Admin endpoints directory correctly excluded"
fi
if [ -d "src/frontend" ]; then
echo "❌ Frontend directory found when it should be excluded"
exit 1
else
echo "✅ Frontend directory correctly excluded"
fi
if [ -d "src/TestProject.Web/AppPermissions" ]; then
echo "❌ AppPermissions directory found when it should be excluded"
exit 1
else
echo "✅ AppPermissions directory correctly excluded"
fi
fi

- name: Verify solution file format
run: |
cd test-projects/${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}/TestProject
cd test-projects/${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}-admin-${{ matrix.use-admin }}/TestProject
echo "Solution file format verification for framework: ${{ matrix.framework }}"
if [ "${{ matrix.framework }}" == "net8.0" ]; then
# For net8.0, expect .sln file and no .slnx file
Expand Down Expand Up @@ -182,16 +260,16 @@ jobs:

- name: Verify Dockerfile template substitution
run: |
cd test-projects/${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}/TestProject
cd test-projects/${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}-admin-${{ matrix.use-admin }}/TestProject
echo "Dockerfile framework verification:"
grep -E "(aspnet|sdk):" src/TestProject.Web/Dockerfile

- name: Build Docker image for generated project
if: ${{ inputs.include-docker-build }}
run: |
cd test-projects/${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}/TestProject
cd test-projects/${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}-admin-${{ matrix.use-admin }}/TestProject
# Build Docker image - this must succeed for Docker tests
CONFIG_NAME="${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}"
CONFIG_NAME="${{ matrix.scenario.database }}-${{ matrix.scenario.messagequeue }}-${{ matrix.framework }}-aspire-${{ matrix.aspire }}-admin-${{ matrix.use-admin }}"
IMAGE_TAG="testproject-$(echo "$CONFIG_NAME" | tr '[:upper:]' '[:lower:]'):latest"
echo "Building Docker image with tag: $IMAGE_TAG"
if ! docker build -f src/TestProject.Web/Dockerfile -t "$IMAGE_TAG" .; then
Expand Down Expand Up @@ -438,4 +516,4 @@ jobs:

- name: Uninstall template
run: dotnet new uninstall .
if: always()
if: always()
12 changes: 10 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ x86/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
# Exception: allow frontend scripts bin directory
!template/src/frontend/scripts/**/bin/
[Oo]bj/
[Ll]og/
[Ll]ogs/
Expand Down Expand Up @@ -197,9 +199,10 @@ PublishScripts/
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# Only ignore NuGet packages folders at project root level, not frontend workspace packages
/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
!/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
Expand Down Expand Up @@ -387,3 +390,8 @@ FodyWeavers.xsd
.idea/
*.sln.iml
/.vs

# Internal packages build outputs (generated by unbuild --stub, contains absolute paths)
src/frontend/internal/**/dist/
src/frontend/packages/**/dist/
src/frontend/scripts/**/dist/
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ dotnet new list
| `--MessageQueue` | `-M` | 消息队列提供程序 | `RabbitMQ`, `Kafka`, `AzureServiceBus`, `AmazonSQS`, `NATS`, `RedisStreams`, `Pulsar` | `RabbitMQ` |
| `--UseAspire` | `-U` | 启用 Aspire Dashboard 支持 | `true`, `false` | `false` |
| `--IncludeCopilotInstructions` | `-I` | 是否包含 Copilot 指令文件 | `true`, `false` | `true` |
| `--UseAdmin` | | 是否包含 Admin 功能(用户、角色、部门管理、权限系统、前端) | `true`, `false` | `false` |

#### 使用示例

Expand Down Expand Up @@ -168,6 +169,19 @@ dotnet new netcorepal-web -n My.Project.Name -I false

> **提示:** 创建项目后,请根据选择的数据库和消息队列配置,使用对应的基础设施初始化脚本来启动所需的服务。详细说明请参考生成项目中的 `scripts/README.md` 文件。

### 关于 Admin 功能

当启用 `--UseAdmin` 选项时,模板会包含以下功能:

+ **用户管理**:用户的创建、更新、删除、查询等功能
+ **角色管理**:角色的创建、更新、删除、权限分配等功能
+ **部门管理**:部门的创建、更新、删除、树形结构管理等功能
+ **权限系统**:基于角色的权限控制(RBAC),支持权限码定义和验证
+ **JWT 认证**:完整的 JWT Token 认证和刷新 Token 机制
+ **前端界面**:基于 Vue 3 + Vben Admin 的管理后台界面

启用 Admin 功能后,系统会自动创建默认的管理员账户(用户名:`admin`,密码:`123456`)。

### 关于 Aspire Dashboard

当启用 `--UseAspire` 选项时,模板会生成以下额外的项目:
Expand Down
111 changes: 111 additions & 0 deletions scripts/gen-all-migrations.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Generate migration scripts for all database + dotnet version combinations
# Output to template/src/ABC.Template.Infrastructure/MigrationsAll/Database-Framework directories

$ErrorActionPreference = "Stop"
$TEMPLATE_ROOT = $PSScriptRoot | Split-Path -Parent
$INFRA_MIGRATIONS_PATH = Join-Path $TEMPLATE_ROOT "template\src\ABC.Template.Infrastructure\MigrationsAll"
$TMP_ROOT = Join-Path $env:TEMP "netcorepal-migrations-$(New-Guid)"

# Database types
$DATABASES = @("MySql", "SqlServer", "PostgreSQL", "Sqlite", "GaussDB", "DMDB")
# Dotnet versions - check which SDKs are installed
$ALL_FRAMEWORKS = @("net8.0", "net9.0", "net10.0")
$INSTALLED_SDKS = dotnet --list-sdks | ForEach-Object { if ($_ -match '(\d+\.\d+\.\d+)') { $matches[1] } }
$FRAMEWORKS = @()
foreach ($fw in $ALL_FRAMEWORKS) {
$sdkVersion = if ($fw -eq "net8.0") { "8.0" } elseif ($fw -eq "net9.0") { "9.0" } else { "10.0" }
$hasSdk = $INSTALLED_SDKS | Where-Object { $_.StartsWith($sdkVersion) }
if ($hasSdk) {
$FRAMEWORKS += $fw
Write-Host "Found SDK for $fw, will generate migrations"
} else {
Write-Host "Warning: SDK for $fw not found, skipping"
}
}
if ($FRAMEWORKS.Count -eq 0) {
Write-Host "Error: No compatible SDKs found. Please install .NET 8.0, 9.0, or 10.0 SDK."
exit 1
}

# 1. Clear MigrationsAll directory before generation
Write-Host "==> Clearing $INFRA_MIGRATIONS_PATH ..."
if (Test-Path $INFRA_MIGRATIONS_PATH) {
Remove-Item -Recurse -Force $INFRA_MIGRATIONS_PATH
}
New-Item -ItemType Directory -Path $INFRA_MIGRATIONS_PATH -Force | Out-Null

$MIGRATION_NAME = "Init"

# Generate migrations for both UseAdmin=true and UseAdmin=false
$USE_ADMIN_VALUES = @($false, $true)

foreach ($db in $DATABASES) {
foreach ($fw in $FRAMEWORKS) {
foreach ($useAdmin in $USE_ADMIN_VALUES) {
$adminSuffix = if ($useAdmin) { "-admin" } else { "" }
$PRJ_DIR = Join-Path $TMP_ROOT "${db}-${fw}${adminSuffix}"
$OUTDIR = Join-Path $INFRA_MIGRATIONS_PATH "${db}-${fw}${adminSuffix}"

Write-Host "==> Cleaning $PRJ_DIR ..."
if (Test-Path $PRJ_DIR) {
Remove-Item -Recurse -Force $PRJ_DIR
}

$adminParam = if ($useAdmin) { "--UseAdmin true" } else { "" }
Write-Host "==> Generating $db $fw project with UseAdmin=$useAdmin..."
if ($useAdmin) {
dotnet new netcorepal-web -n ABC.Template -F $fw -D $db -M RabbitMQ --UseAdmin true --output $PRJ_DIR
} else {
dotnet new netcorepal-web -n ABC.Template -F $fw -D $db -M RabbitMQ --output $PRJ_DIR
}

$INFRA_DIR = Join-Path $PRJ_DIR "src\ABC.Template.Infrastructure"

# Recursively clean the Migrations directory generated by dotnet new to avoid template pollution
$MIGRATIONS_DIR = Join-Path $INFRA_DIR "Migrations"
if (Test-Path $MIGRATIONS_DIR) {
Remove-Item -Recurse -Force $MIGRATIONS_DIR
}

Write-Host "==> Running dotnet restore..."
Push-Location $PRJ_DIR
try {
dotnet restore --ignore-failed-sources
} finally {
Pop-Location
}

Write-Host "==> Running dotnet build..."
Push-Location $PRJ_DIR
try {
dotnet build --no-restore
} finally {
Pop-Location
}

Write-Host "==> Cleaning target migration directory..."
if (Test-Path $OUTDIR) {
Remove-Item -Recurse -Force $OUTDIR
}

Write-Host "==> Generating migration $MIGRATION_NAME..."
Push-Location $INFRA_DIR
try {
dotnet ef migrations add $MIGRATION_NAME --output-dir Migrations
} finally {
Pop-Location
}

New-Item -ItemType Directory -Path $OUTDIR -Force | Out-Null
$GENERATED_MIGRATIONS = Join-Path $INFRA_DIR "Migrations"
Copy-Item -Path "$GENERATED_MIGRATIONS\*" -Destination $OUTDIR -Recurse -Force
Write-Host "==> $db $fw UseAdmin=$useAdmin migration copied to $OUTDIR"
}
}
}

Write-Host "==> Cleaning temporary directory..."
if (Test-Path $TMP_ROOT) {
Remove-Item -Recurse -Force $TMP_ROOT
}
Write-Host "All migrations generated successfully!"
Loading
Loading