Skip to main content

GitLab CI/CD pipeline for Keil uVision

A practical guide to building Keil uVision projects in GitLab CI/CD with a Windows runner, PowerShell exit-code handling, and build artifacts.

GitLab CI/CD pipeline for Keil uVision

This is a practical setup I use to build Keil uVision projects automatically with GitLab CI/CD.
The goal is simple: every commit should produce a reproducible firmware build, with logs and binaries attached as artifacts.

If you work on embedded systems, this gives you fast feedback on broken builds and avoids “works on my machine” problems.

Prerequisites
#

Before creating the pipeline, ensure:

  • A Windows GitLab Runner is available and tagged (for example windows).
  • Keil MDK / uVision is installed on the runner.
  • The runner service account can access UV4.exe.
  • Your project can already build from uVision command line.

Keil command-line reference:
uVision command-line options

Why this pipeline layout
#

The original approach works, but repeating the same PowerShell logic across Debug and Release jobs becomes hard to maintain.

This version uses:

  • one reusable template job (.keil_build_template)
  • one variable (UVISION_TARGET) to switch target
  • explicit artifact collection
  • readable mapping of Keil exit codes

Example .gitlab-ci.yml
#

  YAML
stages:
  - build

variables:
  GIT_SUBMODULE_STRATEGY: recursive
  UV4_PATH: "C:\\Keil_v5\\UV4\\UV4.exe"
  UV_PROJ: ".\\projectname.uvprojx"
  BUILD_LOG: ".\\Objects\\build.log"

.keil_build_template:
  stage: build
  tags:
    - windows
  script:
    - |
      & "$env:UV4_PATH" -crb "$env:UV_PROJ" -t"$env:UVISION_TARGET" -o "$env:BUILD_LOG" -sg -j0 | Out-Null
      $code = $LASTEXITCODE

      switch ($code) {
        0  { Write-Host "No errors or warnings"; exit 0 }
        1  { Write-Host "Warnings only"; exit 0 }
        2  { Write-Host "Build errors"; exit 2 }
        3  { Write-Host "Fatal build errors"; exit 3 }
        11 { Write-Host "Cannot open project file for writing"; exit 11 }
        12 { Write-Host "Device not found in database"; exit 12 }
        13 { Write-Host "Error writing project file"; exit 13 }
        15 { Write-Host "Error reading import XML file"; exit 15 }
        20 { Write-Host "Project conversion error"; exit 20 }
        default {
          Write-Host "Unknown uVision exit code: $code"
          exit $code
        }
      }
  after_script:
    - if (Test-Path "$env:BUILD_LOG") { Get-Content "$env:BUILD_LOG" -Tail 20 }
  artifacts:
    when: always
    expire_in: 14 days
    paths:
      - Objects/*.hex
      - Objects/*.axf
      - Objects/*.htm
      - Objects/*.log
      - Listings/*.map

build_debug:
  extends: .keil_build_template
  variables:
    UVISION_TARGET: "Debug"

build_release:
  extends: .keil_build_template
  variables:
    UVISION_TARGET: "Release"

Notes on exit-code policy
#

In this setup, exit code 1 (“warnings only”) is treated as success.
That is intentional when warnings are acceptable in your process.

If you want a stricter gate, change:

  • 1 { Write-Host "Warnings only"; exit 0 }

to:

  • 1 { Write-Host "Warnings only"; exit 1 }

and the job will fail on warnings.

Common issues on self-hosted Windows runners
#

  • Runner cannot find UV4.exe: check installation path and permissions for the runner service account.
  • License or pack problems: verify the runner machine has a valid MDK setup and required device packs.
  • Project path issues: use quoted paths and avoid assumptions about current working directory.
  • Artifacts missing: confirm output folder names (Objects, Listings) match your project settings.

Suggested next improvements
#

Once the basic build is stable, useful extensions are:

  • add a test stage for host-side unit tests (if available)
  • publish firmware binaries with semantic version names
  • add a release job triggered by tags
  • archive build metadata (commit, toolchain version, timestamp)

This keeps the pipeline simple while making embedded firmware builds more traceable and repeatable.

Next entry

Extract timesheet from iCal