Skip to content

Configuration Reference

Stable Build Reviewed 2026-09-27 purview-dev/build build-pipeline cd ci composite-action csharp devops dogfooding dotnet github-actions modular-pipelines nuget reusable-workflow

Configuration is optional in a consuming repository; defaults are baked into the tool. Add purview-build.json at the repository root to override them.

Command line > environment variables > purview-build.json > baked-in defaults (appsettings.json) > code-level defaults.

  • Environment variables use __ for nesting, for example Release__Mode=NuGet.
  • Command-line overrides use configuration syntax, for example --Build:RunPack=false.
  • Secrets must not be committed; they are supplied at runtime through env vars / CI secrets. See Secrets and Environment Variables.
OptionBehaviour
-v, --versionPrint the tool version and exit without running the pipeline.
-h, --help, -?Print usage, options, and configuration keys, then exit.

Failures are reported the way a CLI build tool reports them: the tool prints the failing module and that module’s output, then exits with code 1. Set PURVIEW_BUILD_STACKTRACE=1 to add stack traces when diagnosing the tool itself.

KeyDefaultPurpose
LogLevelInformationTrace/Debug/Information/Warning/Error/Critical/None; applied to the pipeline logger. Information reports every module’s command output, progress, and completion; Warning keeps CI logs quiet
ProjectTypeDotNetDotNet (dotnet restore/build/test/pack) or Web (Bun commands from the root package.json scripts)
Solutionsrc/Product.slnxSolution, project, or directory passed to restore/build/pack (dotnet only)
ConfigurationRelease.NET configuration
ArtifactsFolderartifactsPackage output directory
CleanArtifactstrueDelete and recreate ArtifactsFolder before the run produces anything, so validation, publishing, and release uploads only see the current run’s packages. Ignored when RunPack is false
RunTeststrueEnable discovered tests
TestRootsrc/testsTest discovery root (relative to the repository root)
TestPatterns*Tests.csprojComma-separated project search patterns applied under TestRoot
TestProjects*Comma-separated project names/globs to run; * runs all discovered
TestFrameworkTUnitTUnit (tree-node filter) or xUnit (VSTest filter)
TestFilter/*/*/*/*/TUnit tree-node filter or xUnit --filter; empty disables it
RunLinttrueRestore local tools and run CSharpier check (dotnet) or format:check + lint scripts (Web)
RunPacktrueEnable packing
ValidatePacktrueEnable pack validation (dotnet only; always skipped for Web)
WebInstallCommandbun installInstall command for ProjectType=Web
WebBuildCommandbun run buildBuild command for ProjectType=Web; when left at the default the module first runs a data:sync script if one is declared
WebLintCommandbun run lintLint command for ProjectType=Web
WebFormatCheckCommandbun run format:checkFormat-check command for ProjectType=Web
WebTestCommandbun run testTest command for ProjectType=Web
WebBuildOutputsrc/distDirectory zipped into ArtifactsFolder by the Web pack step
KeyDefaultPurpose
RequireSymbolPackagetrueEvery .nupkg must have a matching .snupkg and vice versa, except analyzer-only packages that embed their PDBs under analyzers/dotnet/
RequireSymbolFilestrueEvery .snupkg must contain at least one .pdb
RequireSourceLinkfalseEvery .dll/.exe must have a matching portable PDB containing a Source Link record
RequireDeterministicfalseEvery .dll/.exe must be built deterministically (the PE carries the Reproducible debug directory entry)
RequiredCompilerFlags[]Compiler-flag key=value entries that must appear in each assembly’s PDB compiler-flags record (e.g. optimization=release)
RequiredContent{}Package-id glob → entry-path globs that must be present in the .nupkg ("*" matches every package). Entries may use the $(TFM) target-framework partial token, e.g. lib/$(TFM)/Foo.dll
ForbiddenContent{}Package-id glob → entry-path globs that must not be present in the .nupkg ("*" matches every package). Also supports the $(TFM) partial token
RequireExplicitContentfalseMakes RequiredContent exhaustive: every generated package must match a rule, and every non-metadata entry must match a declared glob; undeclared packages/entries are errors

Content entry paths and package-id keys are matched as globs (case-insensitive), e.g. tools/**/Foo.dll or **/*.pdb. Entries may also contain the $(TFM) partial token (e.g. lib/$(TFM)/Foo.dll), which expands to one entry per target framework the package actually ships (short folder name, discovered from the package’s own content groups); each expanded entry is checked independently. Required content is satisfied when any package entry matches; forbidden content fails when any entry matches. When RequireExplicitContent is true, RequiredContent becomes exhaustive: every generated package must match a rule, and every non-metadata entry in a matched package must match a declared (and $(TFM)-expanded) glob — undeclared packages or entries are errors. PDBs are normally delivered through .snupkg, but analyzer-only packages may embed them under analyzers/dotnet/ in the .nupkg; those packages do not require a sibling .snupkg. The assembly checks (RequireSourceLink, RequireDeterministic, RequiredCompilerFlags) inspect each .dll/.exe in the .nupkg (PE header) and its sibling portable PDB in the .snupkg or analyzer-slot PDB in the .nupkg; they only apply to assemblies the package ships symbols for. Determinism is detected via the PE’s Reproducible debug directory entry, source link via the PDB’s Source Link record, and compiler flags via the PDB’s key/value compiler-flags record (matched case-insensitively, e.g. optimization=release).

Tool defaults vs code defaults. The shipped appsettings.json sets RequireSourceLink: false, RequireDeterministic: false, and RequiredCompilerFlags: []. The C# property initializers in PackValidationSettings default those to true/true/["optimization=release"], but because appsettings.json always loads and wins over code defaults, the effective shipped defaults are the false/false/[] values shown above.

KeyDefaultPurpose
FeedUrlnuget.org v3Remote package source
TrustedPublishingfalsePush without an API key (NuGet Trusted Publishing / OIDC)
APIKeyunsetSecret; use NUGET_APIKEY or NuGet__ApiKey
EnvAPIKeyunsetBinds NuGet__NUGET_APIKEY; also falls back to process env NUGET_APIKEY/NUGET_API_KEY
KeyDefaultPurpose
LocalFeedPathunsetAbsolute local package source
EnvLocalFeedPathunsetBinds PublishLocalNuGet__LOCAL_NUGET_FEED_PATH; also falls back to process env LOCAL_NUGET_FEED_PATH
OverwriteExistingPackagestrueOverwrite packages already in the local feed
ShutdownDotnetBuilderServertrueShut down the dotnet build server after publishing
ClearPackageCachetrueClear the local NuGet package caches for the published packages
KeyDefaultPurpose
AccessTokenunsetSecret; use GITHUB_TOKEN
EnvAccessTokenunsetBinds GitHub__GITHUB_TOKEN; also falls back to process env GITHUB_TOKEN
ProductHeaderPurview.Build.PipelineGitHub API product header
KeyDefaultPurpose
ModeNoneNone, LocalNuGet, NuGet, or GitHubRelease
UploadArtifactsfalseUpload every file in Build:ArtifactsFolder as GitHub release assets
MarkPrereleasetrueCreate the GitHub release as a prerelease when the package version is a prerelease (for example 2.0.0-prerelease.25). Affects GitHub release metadata only — NuGet publication is unaffected
{
"Build": {
"Solution": "src/MyProduct.slnx",
"TestRoot": "src/tests",
"TestPatterns": "*Tests.csproj",
"TestFilter": "/*/*/*/*[Category=Unit]"
},
"PackValidation": {
"RequireSymbolPackage": true,
"RequireSourceLink": true,
"RequireDeterministic": true,
"RequiredCompilerFlags": ["optimization=release"],
"RequiredContent": {
"my.product": ["lib/netstandard2.0/My.Product.dll"]
}
},
"Release": { "Mode": "None" }
}