JD.Efcpt.Build is designed to work seamlessly in continuous integration and deployment pipelines. This guide covers integration with popular CI/CD platforms.
The package requires no special configuration for CI/CD. Models are generated deterministically from your database project or connection, ensuring consistent results across environments.
Ensure your CI/CD environment has:
- .NET SDK 8.0 or later
- EF Core Power Tools CLI (not required for .NET 10+)
- For DACPAC mode: SQL Server Data Tools components
No tool installation required - the CLI is executed via dnx:
name: Build
on: [push, pull_request]
jobs:
build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --configuration Release --no-restore
- name: Test
run: dotnet test --configuration Release --no-buildRequires tool installation:
name: Build
on: [push, pull_request]
jobs:
build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
- name: Restore tools
run: dotnet tool restore
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --configuration Release --no-restore
- name: Test
run: dotnet test --configuration Release --no-buildSpeed up builds by caching the efcpt intermediate directory:
name: Build with Cache
on: [push, pull_request]
jobs:
build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
- name: Cache efcpt outputs
uses: actions/cache@v4
with:
path: |
**/obj/efcpt/
key: efcpt-${{ runner.os }}-${{ hashFiles('**/*.sqlproj', '**/efcpt-config.json') }}
restore-keys: |
efcpt-${{ runner.os }}-
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --configuration Release --no-restore
- name: Test
run: dotnet test --configuration Release --no-buildtrigger:
- main
pool:
vmImage: 'windows-latest'
steps:
- task: UseDotNet@2
displayName: 'Setup .NET SDK'
inputs:
version: '10.0.x'
- task: DotNetCoreCLI@2
displayName: 'Restore'
inputs:
command: 'restore'
- task: DotNetCoreCLI@2
displayName: 'Build'
inputs:
command: 'build'
arguments: '--configuration Release --no-restore'
- task: DotNetCoreCLI@2
displayName: 'Test'
inputs:
command: 'test'
arguments: '--configuration Release --no-build'trigger:
- main
pool:
vmImage: 'windows-latest'
steps:
- task: UseDotNet@2
displayName: 'Setup .NET SDK'
inputs:
version: '8.0.x'
- task: DotNetCoreCLI@2
displayName: 'Restore tools'
inputs:
command: 'custom'
custom: 'tool'
arguments: 'restore'
- task: DotNetCoreCLI@2
displayName: 'Restore'
inputs:
command: 'restore'
- task: DotNetCoreCLI@2
displayName: 'Build'
inputs:
command: 'build'
arguments: '--configuration Release --no-restore'
- task: DotNetCoreCLI@2
displayName: 'Test'
inputs:
command: 'test'
arguments: '--configuration Release --no-build'trigger:
- main
pool:
vmImage: 'windows-latest'
variables:
NUGET_PACKAGES: $(Pipeline.Workspace)/.nuget/packages
steps:
- task: Cache@2
displayName: 'Cache NuGet packages'
inputs:
key: 'nuget | "$(Agent.OS)" | **/packages.lock.json'
restoreKeys: |
nuget | "$(Agent.OS)"
path: $(NUGET_PACKAGES)
- task: Cache@2
displayName: 'Cache efcpt outputs'
inputs:
key: 'efcpt | "$(Agent.OS)" | **/*.sqlproj | **/efcpt-config.json'
restoreKeys: |
efcpt | "$(Agent.OS)"
path: '**/obj/efcpt'
- task: UseDotNet@2
inputs:
version: '10.0.x'
- task: DotNetCoreCLI@2
displayName: 'Restore'
inputs:
command: 'restore'
- task: DotNetCoreCLI@2
displayName: 'Build'
inputs:
command: 'build'
arguments: '--configuration Release --no-restore'# Build stage
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src
# Copy solution and project files
COPY *.sln .
COPY src/**/*.csproj ./src/
COPY database/**/*.sqlproj ./database/
# Restore dependencies
RUN dotnet restore
# Copy everything else
COPY . .
# Build
RUN dotnet build --configuration Release --no-restore
# Publish
RUN dotnet publish src/MyApp/MyApp.csproj --configuration Release --no-build -o /app/publish
# Runtime stage
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS runtime
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "MyApp.dll"]FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
# Copy tool manifest and restore tools
COPY .config/dotnet-tools.json .config/
RUN dotnet tool restore
# Copy and restore
COPY *.sln .
COPY src/**/*.csproj ./src/
COPY database/**/*.sqlproj ./database/
RUN dotnet restore
# Copy everything and build
COPY . .
RUN dotnet build --configuration Release --no-restore
# Publish
RUN dotnet publish src/MyApp/MyApp.csproj --configuration Release --no-build -o /app/publish
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "MyApp.dll"]stages:
- build
- test
variables:
DOTNET_VERSION: "10.0"
build:
stage: build
image: mcr.microsoft.com/dotnet/sdk:10.0
script:
- dotnet restore
- dotnet build --configuration Release --no-restore
artifacts:
paths:
- "**/bin/"
- "**/obj/"
expire_in: 1 hour
test:
stage: test
image: mcr.microsoft.com/dotnet/sdk:10.0
dependencies:
- build
script:
- dotnet test --configuration Release --no-buildpipeline {
agent {
docker {
image 'mcr.microsoft.com/dotnet/sdk:10.0'
}
}
stages {
stage('Restore') {
steps {
sh 'dotnet restore'
}
}
stage('Build') {
steps {
sh 'dotnet build --configuration Release --no-restore'
}
}
stage('Test') {
steps {
sh 'dotnet test --configuration Release --no-build'
}
}
}
}When using connection string mode, you'll need a database available during build.
# GitHub Actions
env:
DB_CONNECTION_STRING: ${{ secrets.DB_CONNECTION_STRING }}
steps:
- name: Build
run: dotnet build --configuration Release<!-- .csproj -->
<PropertyGroup>
<EfcptConnectionString>$(DB_CONNECTION_STRING)</EfcptConnectionString>
</PropertyGroup># GitHub Actions with SQL Server container
services:
sqlserver:
image: mcr.microsoft.com/mssql/server:2022-latest
env:
ACCEPT_EULA: Y
SA_PASSWORD: YourStrong!Passw0rd
ports:
- 1433:1433
options: >-
--health-cmd "/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P YourStrong!Passw0rd -Q 'SELECT 1'"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: Setup database
run: |
sqlcmd -S localhost -U sa -P YourStrong!Passw0rd -i scripts/setup.sql
- name: Build
env:
EfcptConnectionString: "Server=localhost;Database=MyDb;User Id=sa;Password=YourStrong!Passw0rd;TrustServerCertificate=True;"
run: dotnet build --configuration ReleaseModern SDK-style SQL Projects (Microsoft.Build.Sql or MSBuild.Sdk.SqlProj) build cross-platform:
# GitHub Actions - Linux works with modern SQL SDKs
jobs:
build:
runs-on: ubuntu-latest # Works with Microsoft.Build.Sql and MSBuild.Sdk.SqlProjTraditional SQL Projects (legacy .sqlproj format) require Windows with SQL Server Data Tools:
# GitHub Actions - Windows required for traditional .sqlproj
jobs:
build:
runs-on: windows-latestConnection string mode works on both Windows and Linux:
# GitHub Actions - Any platform works
jobs:
build:
runs-on: ubuntu-latestFor .NET 8-9, ensure tool restore runs before build:
- name: Restore tools
run: dotnet tool restoreFor traditional SQL Projects, use Windows with SQL Server Data Tools:
pool:
vmImage: 'windows-latest'For modern SDK-style projects (Microsoft.Build.Sql or MSBuild.Sdk.SqlProj), Linux works fine - verify your project SDK is configured correctly.
Clear the cache to force regeneration:
- name: Clear efcpt cache
run: rm -rf **/obj/efcptEnable caching for the efcpt intermediate directory to skip regeneration when schema hasn't changed.
- Use .NET 10+ when possible to eliminate tool installation steps
- Use local tool manifests (.NET 8-9) for version consistency
- Cache intermediate directories to speed up incremental builds
- Use modern SQL SDKs (
Microsoft.Build.SqlorMSBuild.Sdk.SqlProj) for cross-platform DACPAC builds - Use environment variables for connection strings
- Never commit credentials to source control
The Provider Compatibility workflow runs the task unit suite on .NET 8, 9, and 10 on Windows, Linux, and macOS. Each of its nine jobs checks passing connection and schema-reader tests for SQL Server, PostgreSQL, MySQL, Oracle, Snowflake, Firebird, and SQLite, covering 63 provider/runtime/OS combinations. TRX reports are uploaded as artifacts; missing or skipped provider cases fail verification.
This matrix exercises driver loading, connection construction, and schema-reader logic. Live database tests remain in the Linux integration suite; Snowflake live tests require an account. The separate upstream-tool workflow below tests actual efcpt execution.
To reproduce one runtime locally:
dotnet test tests/JD.Efcpt.Build.Tests/JD.Efcpt.Build.Tests.csproj -c Release -p:EfcptTestFramework=net8.0 --filter "Category!=Integration"Install the .NET 8/9/10 SDKs first. EfcptTestFramework selects the task test host and its fixture; the default remains net10.0.
The efcpt CLI is an external tool whose release lines track EF Core versions, so an upstream release can change scaffolding behavior. A scheduled workflow guards against this by weekly rebuilding a sample against the latest efcpt per supported EF Core line. See efcpt Compatibility for the supported version matrix and how the guard works.
- efcpt Compatibility - Supported efcpt versions and the weekly compat guard
- Troubleshooting - Solve common problems
- Configuration - Complete configuration reference
- Advanced Topics - Complex scenarios