GitLab CI Windows Runner Integration and Deployment

The deployment of continuous integration and continuous delivery (CI/CD) pipelines on Windows environments requires a nuanced understanding of how the GitLab Runner interacts with the Windows operating system. While Linux-based runners are the industry standard, the requirement for Windows-specific binaries, .NET Framework legacy support, and specialized GUI testing necessitates a robust implementation of the GitLab Runner on Windows. This architecture allows developers to execute build, test, and deploy stages directly on Windows Server or Windows 10/11 environments, ensuring that the software is validated in the actual environment where it will reside. The integration process involves not only the binary installation but also the careful configuration of service accounts, shell executors, and environment variables to overcome the inherent limitations of the Windows service model, such as the lack of interactive desktop sessions.

Infrastructure Requirements and Environmental Prerequisites

Before initiating the installation of a GitLab Runner on a Windows machine, several critical prerequisites must be met to ensure system stability and avoid character encoding or permission-based failures.

The hardware or virtualized environment can be flexible. A Windows server is required, which can be a physical machine or a virtual machine. For instance, Windows Server 2022 is a highly compatible and recommended choice for on-premises environments, though older versions of Windows Server or even desktop versions can be repurposed as script servers.

The software prerequisites include the following:

  • Git: This is a fundamental requirement for the runner to clone repositories and manage version control. It must be installed from the official Git website.
  • User Account Credentials: A password for the user account is mandatory if the intention is to run the service under a specific user identity rather than the Built-in System Account.
  • System Locale: The system locale must be set specifically to English (United States). This is a critical requirement to prevent character encoding issues that have been documented in issue 38702.

The availability of the runner depends on the GitLab tier and offering. The Windows Runner is compatible across Free, Premium, and Ultimate tiers, and is supported on GitLab.com, GitLab Self-Managed, and GitLab Dedicated instances.

Installation Procedures for Local Windows Runners

The installation of the GitLab Runner on Windows is a manual process involving the placement of a binary and the configuration of a system service.

The first step involves the creation of a dedicated directory to house the runner. A common practice is to create a folder at C:\GitLab-Runner. This centralizes the executable and any associated configuration files.

The binary must then be downloaded based on the specific architecture of the host machine. GitLab provides binaries for the following architectures:

  • x86 64-bit
  • ARM 64-bit
  • x86 32-bit

After downloading, the binary should be renamed to gitlab-runner.exe for ease of command execution. A critical security step during this phase is the restriction of Write permissions on the C:\GitLab-Runner directory and the gitlab-runner.exe file itself. Failing to restrict these permissions allows regular users to replace the executable with malicious code, which would then be executed with elevated privileges when the service starts.

To finalize the installation as a service, an elevated command prompt must be used. The runner can be installed using the Built-in System Account, which is the recommended approach for most headless CI/CD tasks, or a specific user account.

Advanced Service User Configuration and Rights

When scripts require the ability to impersonate a user or access network resources that the local system account cannot reach, the runner must be installed with a specific service user.

To implement this, the installation command must be modified to include the user and password flags:

.\gitlab-runner.exe install --user $user --password $password

In this command, $user and $password are replaced with the actual credentials of the service account. However, simply running this command is insufficient for the service to start. The specified user must be granted the Log on as a service right within the Windows Local Security Policy. Without this grant, the Windows Service Control Manager will fail to start the process, leading to a service start-up error.

The Registration Process

Once the binary is installed and the service is created, the runner must be linked to a specific GitLab instance through a registration process.

The registration is triggered by executing the following command in PowerShell:

gitlab-runner.exe register

This command initiates an interactive sequence where the administrator must provide:

  • The URL of the GitLab server.
  • A registration token.

The registration token is located within the GitLab admin portal. The navigation path is Settings -> CI/CD -> Runners. By clicking the three dots in the Runners menu, the user can select "Show runner installation and registration instructions," which provides the exact commands and tokens needed for the specific instance.

Hosted Windows Runners and SaaS Specifications

For users who do not wish to manage their own infrastructure, GitLab provides hosted runners on Windows. These are currently in beta and offer a managed environment for executing jobs.

The hosted Windows runners use a specific machine type. The specifications for the available medium AMD64 runner are as follows:

Runner Tag vCPUs Memory Storage
saas-windows-medium-amd64 2 7.5 GB 75 GB

The supported operating system for these hosted runners is Windows 2022, which is currently in General Availability (GA).

A significant characteristic of hosted runners is the provisioning time. Because a new Windows virtual machine must be spun up for the job, the average provisioning time is approximately five minutes. This results in a noticeable delay in the start time of builds compared to Linux runners.

Shell Execution and .gitlab-ci.yml Configuration

Hosted Windows runners are configured to use PowerShell as the default shell. This means that any commands written in the script section of the .gitlab-ci.yml file must be valid PowerShell syntax.

The following table outlines the requirements for job configuration on hosted Windows runners:

Requirement Specification
Tag Must use saas-windows-medium-amd64
Shell PowerShell
YAML Syntax PowerShell commands in script and before_script

An example of a functional .gitlab-ci.yml for a hosted Windows job is provided below:

```yaml
.windowsjob:
tags:
- saas-windows-medium-amd64
before
script:
- Set-Variable -Name "time" -Value (date -Format "%H:%m")
- echo ${time}
- echo "started by ${GITLABUSERNAME} / @${GITLABUSERLOGIN}"

build:
extends:
- .windows_job
stage: build
script:
- echo "running scripts in the build job"

test:
extends:
- .windows_job
stage: test
script:
- echo "running scripts in the test job"
```

Solving GUI Testing and Interactive Session Limitations

A primary limitation of the GitLab Runner on Windows is that when it runs as a service, it operates in a non-interactive session (Session 0). This means it has no access to the visible desktop, which is a requirement for GUI testing tools such as Ranorex or various desktop automation frameworks.

If a job is run as a service, GUI tests will either fail immediately or hang indefinitely because there is no window station to render the graphical interface.

To bypass this limitation and enable GUI testing, the following strategy must be employed:

  • Executor Selection: Use the shell executor. Docker and Kubernetes executors on Windows are incapable of providing an interactive desktop session.
  • Session Management: A user must manually sign in to Windows to create an interactive session.
  • Process Execution: Instead of running the runner as a service, it must be started as a foreground process within that active user session using the following commands:

powershell cd C:\GitLab-Runner .\gitlab-runner.exe run

  • Job Targeting: To ensure only GUI tests are sent to this specific interactive runner, use unique tags in the .gitlab-ci.yml file:

yaml gui_tests: stage: test tags: - windows-gui script: - .\run-gui-tests.ps1

It is important to note that autoscaled or ephemeral Windows runners cannot support GUI tests because they provision a fresh VM for each job without a logged-in user, meaning no visible desktop ever exists.

Troubleshooting Common Windows Runner Issues

Windows environments present specific challenges regarding file paths and script execution that require targeted workarounds.

PathTooLongException and Git Configurations

Users frequently encounter the PathTooLongException, particularly when using tools like npm that create deeply nested directory structures exceeding the 260-character limit. To resolve this, core.longpaths must be enabled in Git.

If the GitLab Runner version has regressions affecting this, the following workarounds are suggested:

  1. Using the pre_get_sources_script to unset Git_CONFIG_NOSYSTEM, which re-enables system-level Git settings:

yaml build: hooks: pre_get_sources_script: - $env:GIT_CONFIG_NOSYSTEM=''

  1. Building a custom gitlab-runner-helper image with the environment variable set:

dockerfile FROM registry.gitlab.com/gitlab-org/gitlab-runner/gitlab-runner-helper:x86_64-v17.8.3-servercore21H2 ENV GIT_CONFIG_NOSYSTEM=

Batch Script Execution Errors

When executing Windows batch files, users may encounter the error: "The system cannot find the batch label specified." This is typically caused by how the runner invokes the script. To fix this, the call command must be prepended to the batch file path in the .gitlab-ci.yml file:

yaml before_script: - call C:\path\to\test.bat

Web Terminal Color Output

To achieve colored output in the GitLab CI web terminal, the program must output ANSI color codes. The GitLab web interface emulates a UNIX ANSI terminal. Therefore, as long as the output contains these codes, the web interface will honor them. Note that Windows command prompts prior to version 1511 do not support ANSI color codes.

Software Management on Shared Runners

When using shared Windows runners on GitLab.com, users often face questions regarding pre-installed software and the ability to install new tools.

Pre-installed software for Windows containers on GitLab.com is maintained in a public repository. Users can find the complete list by navigating to the cookbooks for pre-installed software in the gitlab-org/ci-cd/shared-runners/images/gcp/windows-containers repository.

To install additional software such as Python, Ruby, or Perl on a shared runner, users must utilize PowerShell scripts. Many Windows installers, such as the Python installer, support headless installation and customization via command-line arguments, which allows them to be installed during the job's before_script phase even without explicit administrator privileges.

Conclusion

The implementation of a GitLab CI Windows Runner requires a strategic approach to bridge the gap between the Linux-centric design of GitLab CI and the specific operational requirements of the Windows operating system. By carefully managing the installation of the binary in a secure directory, configuring the runner as a service with appropriate "log-on-as-service" rights, and utilizing PowerShell for script execution, organizations can achieve a stable automation pipeline. The distinction between the Built-in System Account and a service user is pivotal for network access, while the transition from a service-based runner to a foreground-process runner is the only viable path for executing GUI-based automation. Furthermore, addressing the PathTooLongException through Git configuration and ensuring correct batch file invocation with the call command are essential steps for maintaining a failure-free build environment. Whether utilizing self-managed on-premises servers or the beta hosted runners on GitLab.com, the key to success lies in the precise alignment of the runner's execution context with the requirements of the software being tested.

Sources

  1. Windows GitLab Runner Setup - randriksen.net
  2. Install GitLab Runner on Windows - GitLab Docs
  3. Hosted Runners on Windows - GitLab Docs
  4. GitLab CI Windows Runner Discussion - GitLab Forum

Related Posts