Build Pipeline¶
DGT-ALM-060 — This is the canonical order of steps for building a Dataverse project at DIGITALL, independent
of whether the orchestrator is Azure DevOps, GitHub Actions, or a script run by Power Platform
Pipelines' extensibility hooks. Individual platform chapters
(Azure DevOps, GitHub Actions,
Power Platform Pipelines) show how to wire these steps into
that platform's syntax; this page is the thing to point at when reviewing whether a pipeline
is missing a step.
Step order¶
-
Resolve the build version. Compute the SemVer for this build from Git history (see Versioning). Everything downstream is stamped with this single version.
-
Restore & build client-side projects. For web resources:
pnpm install, Biome lint, webpack production bundle (pnpm run build:prod); PCF controls use theirpac-scaffoldednpmbuild. Output goes to the folder referenced by the solution's web resource mapping. See TypeScript Web Resources. -
Regenerate early-bound models — before compiling server-side code. Run
dgtp codegenerationagainst the build environment so that.cs/.tsmodels reflect the current Dataverse schema. This must happen before step 4, since server-side projects reference the generated model. See Early-Bound Models. -
Bump the solution version in the build environment.
dgtp maintenance solution-version <solution> --build(or--revisionfor a hotfix). This step and codegeneration (step 3) don't depend on each other and can run in either order — but both must complete before the solution export in step 7. -
Build & package server-side projects. Compile plugin/Custom API projects, producing the plugin package
.nupkg(see Plugin Packages). The assembly version stamped here is the same SemVer resolved in step 1. -
Push server-side artifacts to the build environment.
dgtp push <package>.nupkg --solution <name> --publishregisters/updates thePluginPackage,PluginAssembly, plugin types, steps, and step images — see Pre- & Post-Deployment Tasks for what this does under the hood. Push web resources the same way:dgtp push ./WebResources --solution <name> --publish. -
Export & pack the solution.
pac solution export(or sync an already-checked-out unpacked solution viapac solution sync) followed bypac solution pack, producing the managed/unmanaged solution.zipthat becomes the pipeline artifact. -
Run the Solution Checker.
pac solution checkagainst the packed solution as a quality gate — see Solution Checker. A failing high-severity result stops the pipeline here. -
Run automated tests. Server-side unit tests against
Digitall.Dataverse.Testing(no live environment needed), plus any client-side tests. See Testing & Quality. -
Publish the build artifact. The packed solution
.zip, plus any deployment settings / data files needed for config & reference data migration, become the artifact that later release stages deploy — via Power Platform Pipelines, a release pipeline, or a follow-up Actions job.
flowchart TD
A["1 - Resolve build version"] --> B["2 - Build client-side (TS/PCF)"]
A --> C["3 - dgtp codegeneration"]
C --> D["5 - Build server-side, produce .nupkg"]
B --> G["7 - Export and pack solution"]
D --> G
A --> E["4 - dgtp maintenance solution-version"]
E --> G
D --> F["6 - dgtp push (.nupkg, web resources)"]
F --> G
G --> H["8 - Solution Checker"]
H --> I["9 - Automated tests"]
I --> J["10 - Publish artifact"]
Why this order matters¶
The two steps most often placed wrong:
- Codegeneration before server-side build, not after. If you build the plugin project against a stale generated model, the build succeeds but the plugin silently uses outdated field names at runtime — a much worse failure mode than a build error.
- Solution version bump before export, not after.
pac solution exportbakes whatever version is currently on the environment intosolution.xml. Bumping after export has no effect on the artifact you're about to ship.
CI credentials¶
DGT-ALM-070 — Use token-based (--msal, service principal / client secret) dgtp profiles for CI — never
store a personal account's credentials in a pipeline. Two equivalent wirings satisfy this:
create a token-based profile in the pipeline from a secret (dgtp profile create build "..."
--msal, as the Azure DevOps and
GitHub Actions examples do), or skip the profile
entirely and set the dgtp:xrm:connection environment variable from the secret (see
dgtp CLI → Connecting). Either
way, the credential is a service principal held in the pipeline's secret store.
Local builds (developer workstation)¶
A developer running the same steps locally during a feature loop does not need the version bump (step 4) or the tag-creation that follows a successful pipeline run — only CI should bump solution and Git versions. Steps 2, 3, 5, and 6 are exactly what a developer runs locally against their own dev environment; see Repository Bootstrap for the equivalent local commands.