Offline / Air-Gapped Builds
EfcptOfflineMode lets you build in environments that have no outbound network access -
air-gapped CI agents, locked-down secure build environments, or any pipeline where a build
should never silently reach out to the internet.
What it does
When EfcptOfflineMode is true (or the EFCPT_OFFLINE environment variable is set to a
truthy value - see Enabling offline mode below for the exact accepted
values), the RunEfcpt task refuses to spawn any of the three network-dependent code
paths it would otherwise use to resolve or restore the efcpt CLI:
- dnx execution - on .NET 10+ projects, the task would normally run
dotnet dnx <package> --yes -- ...to fetch and execute the tool on demand. This is skipped entirely offline. - Tool-manifest restore -
dotnet tool restoreagainst a discovered.config/dotnet-tools.jsonmanifest. Skipped offline. - Global tool update -
dotnet tool update --global <package>. Skipped offline.
It also disables the SDK update-check target (EfcptCheckForUpdates), which otherwise makes an
outbound call to check for a newer JD.Efcpt.Sdk version.
What you need to provide
Because none of the network-dependent paths run, the efcpt tool must already be available through one of three network-free routes:
A local tool manifest that has already been restored before the offline build runs:
dotnet new tool-manifest dotnet tool install ErikEJ.EFCorePowerTools.Cli --version 10.*Restore this once, on a machine with network access (or in an earlier CI stage that does have access), then carry the restored
.config/dotnet-tools.json(and the NuGet tool cache) into the offline environment.A global tool install, performed ahead of time on the build agent image:
dotnet tool install --global ErikEJ.EFCorePowerTools.Cli --version 10.*An explicit, pre-provisioned executable, via
EfcptToolPath:<PropertyGroup> <EfcptOfflineMode>true</EfcptOfflineMode> <EfcptToolPath>C:\tools\efcpt\efcpt.exe</EfcptToolPath> </PropertyGroup>
If none of these are available, the build fails fast with error JD0026 instead of hanging or
failing obscurely against a missing tool - see error-codes.md.
Enabling offline mode
MSBuild property (recommended, per-project or via Directory.Build.props):
<PropertyGroup>
<EfcptOfflineMode>true</EfcptOfflineMode>
</PropertyGroup>
Or via the EFCPT_OFFLINE environment variable (useful for CI pipelines that shouldn't need to
touch every consuming project's file):
set EFCPT_OFFLINE=true
dotnet build
Either is sufficient; they are OR-ed together at two levels:
- MSBuild property default.
EfcptOfflineMode's own default (applied only when the property is not explicitly set by the project/Directory.Build.props) checks$(EFCPT_OFFLINE)- MSBuild exposes process environment variables as ordinary properties, so this needs no special plumbing. If$(EFCPT_OFFLINE)is one of the truthy tokens below,EfcptOfflineModedefaults totrue; this is what makes the update-check target (_EfcptCheckForUpdates, which reads$(EfcptOfflineMode)directly) also skip when only the env var is set. - Task-level OR. Independently, the
RunEfcpttask itself also readsEnvironment.GetEnvironmentVariable("EFCPT_OFFLINE")at execution time and OR's it with theEfcptOfflineModetask property, so offline behavior holds even if something explicitly setEfcptOfflineMode=falseat the MSBuild property level whileEFCPT_OFFLINEis set in the process environment.
Accepted truthy values for EFCPT_OFFLINE (case-insensitive): true, yes, on, 1,
enable, enabled, y. Any other value - including false, 0, no, off, or an empty/unset
variable - does not enable offline mode via the environment variable.
What still runs
Offline mode only gates the three network-dependent tool resolution/restore branches and the update-check target. It does not change DACPAC building, schema fingerprinting, or model generation itself - those are already local operations that don't touch the network.
Network-backed connection-string sources
Offline mode also gates network-backed connection-string sources:
if EfcptConnectionStringSource is set to azure-keyvault or aws-secrets, the build fails
closed with JD0032 before any request is attempted, rather than hanging or failing
unpredictably against an unreachable endpoint.
For air-gapped builds that need a connection string resolved from something other than a local
file, use the env source instead - it never touches the network, so it works identically
offline or online:
<PropertyGroup>
<EfcptOfflineMode>true</EfcptOfflineMode>
<EfcptConnectionStringSource>env</EfcptConnectionStringSource>
</PropertyGroup>
Pre-provision the connection string into the configured environment variable (default
EFCPT_CONNECTION_STRING) before the offline build runs.