Skip to main content
Back to blog
Tutorial · · 3 min read · G.D.G. Software

Automate Installer Builds with CI/CD

Shipping software reliably means automating everything you can, and installer builds are no exception. Paquet Builder’s console compiler (pbcompiler.exe) is purpose-built for unattended, scriptable builds — making it a natural fit for CI/CD pipelines.

This guide shows you how to set up automated installer builds using GitHub Actions, Azure DevOps, and generic build servers.

Why Automate Installer Builds?

Manual builds are error-prone. A developer might forget to update the version number, skip code signing, or compile against the wrong file set. Automating the process ensures that every installer is:

  • Reproducible: The same commit always produces the same output.
  • Versioned: Build numbers are injected automatically from your VCS.
  • Signed: Code signing happens on every build, not just release builds.
  • Auditable: Build logs and artifacts are stored alongside your source code.

The Console Compiler

The console compiler accepts a Paquet Builder project file (.pbp) and produces a compiled installer. Key features include:

  • JSON output mode (/json) for machine-readable build results.
  • Directive overrides (/D:VariableName=Value) to inject version numbers, output paths, and signing credentials at build time.
  • Standardized exit codes: 0 for success, 1 for warnings, 2 for errors.

A basic build command looks like this:

pbcompiler.exe MyProject.pbp /json /D:AppVersion=2.5.0 /D:OutputDir=.\dist

GitHub Actions Example

Create a workflow file at .github/workflows/build-installer.yml:

name: Build Installer
on:
push:
tags:
- "v*"
jobs:
build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- name: Install Paquet Builder
run: choco install paquetbuilder --no-progress
- name: Build installer
run: |
pbcompiler.exe MyApp.pbp /json `
/D:AppVersion=${{ github.ref_name }} `
/D:OutputDir=.\artifacts
shell: pwsh
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: installer
path: artifacts/*.exe

When you push a tag like v2.5.0, the workflow checks out your code, installs Paquet Builder via Chocolatey, compiles the installer with the tag as the version number, and uploads the resulting executable as a build artifact.

Azure DevOps Example

Add a step to your azure-pipelines.yml:

steps:
- task: PowerShell@2
displayName: "Build Installer"
inputs:
targetType: inline
script: |
pbcompiler.exe MyApp.pbp /json `
/D:AppVersion=$(Build.BuildNumber) `
/D:OutputDir=$(Build.ArtifactStagingDirectory)
- task: PublishBuildArtifacts@1
displayName: "Publish Installer"
inputs:
pathToPublish: $(Build.ArtifactStagingDirectory)
artifactName: installer

Handling Code Signing in CI/CD

You should never store signing credentials in your project file or source repository. Instead, pass them as environment variables or directive overrides:

pbcompiler.exe MyApp.pbp /sign /json ^
/D:SignMethod=AzureTrustedSigning ^
/D:ATS_TenantId=%ATS_TENANT_ID% ^
/D:ATS_ClientId=%ATS_CLIENT_ID% ^
/D:ATS_ClientSecret=%ATS_CLIENT_SECRET%

Store the actual values in your CI/CD platform’s secret management system (GitHub Secrets, Azure DevOps Variable Groups, etc.).

Parsing Build Results

When you pass the /json flag, the console compiler writes a JSON summary to stdout:

{
"success": true,
"version": "2.5.0",
"outputFile": "C:\\artifacts\\MyApp-Setup.exe",
"outputSize": 15728640,
"warnings": [],
"signed": true,
"signatureThumbprint": "A1B2C3D4..."
}

You can parse this output in your pipeline to make decisions — for example, failing the build if signed is false, or attaching the file size to a release note.

Best Practices

  1. Pin your Paquet Builder version. Use a specific version in your CI/CD environment to avoid surprises when a new release ships.
  2. Use directives for everything that changes. Version numbers, output paths, signing credentials, and feature flags should all be injected at build time, not hard-coded in the project.
  3. Archive build logs. Redirect the compiler’s JSON output to a file and store it alongside your artifacts for auditing.
  4. Test your installer. Consider adding a post-build step that runs the installer silently (/SILENT) in a clean VM or container to verify it completes without errors.
  5. Tag releases in your VCS. Tie each installer build to a specific commit so you can always trace a shipped binary back to its source.

Summary

The Paquet Builder console compiler makes it straightforward to integrate installer builds into any CI/CD pipeline. Combined with directive-based configuration and JSON output, you get reproducible, auditable builds with minimal setup. Check out the console compiler documentation for the full reference.