Most of today’s automation is done on Linux systems but you may still have some code in Production that can only run on Windows. So how do you automate its lifecycle with a tool like GitLab?
In this article, we’ll use some .NET Framework 4.x code and a Windows Virtual Machine (VM) to demonstrate how we can create a pipeline in GitLab to achieve Continuous Integration (CI) and Continuous Delivery!
- .NET 4.8 code base: devpro/ecorp-legacy-demo
- GitLab account & project: gitlab.com/devpro-labs
- Windows VM that meets the criteria:
- Have access to and be accessible from GitLab
- OS version compatible with GitLab supported versions (Windows Server 2019 Datacenter / 1809 as of October 2022)
GitLab is an Application Lifecycle Management (ALM) tool. It provides many features, one of the most important ones being running pipelines.
Pipelines are defined in a YAML file, by default at the root of the repository and named .gitlab-ci.yml.
The file devpro/ecorp-legacy-demo/.gitlab-ci.yml provides a working example with two jobs:
- CI: validate the quality of the code
- PKG: create a container image and push it to a repository if this change is made on main branch
In order to work, this pipeline require two things:
- Variables defined in the GitLab project (sensitive information must not be store in a git repository)
- A runner assigned to the GitLab project and satisfying the tags defined in the YAML file
Pipelines are a set of command lines that are executed on systems thanks to GitLab Runners.
GitLab Runner is an application that works with GitLab CI/CD to run jobs in a pipeline (docs.gitlab.com)
Windows Server VM must be configured to be able to run successfully the pipeline:
- Install Docker Engine (see learn.microsoft.com)
Invoke-WebRequest -UseBasicParsing "https://raw.githubusercontent.com/microsoft/Windows-Containers/Main/helpful_tools/Install-DockerCE/install-docker-ce.ps1" -o install-docker-ce.ps1 .\install-docker-ce.ps1
- Download GitLab Runner binary and copy/rename it as
- Copy the value of GitLab token (from GitLab Projet Settings > CI/CD > Runners) and register GitLab Runner (docs.gitlab.com)
cd C:\GitLab-Runner .\gitlab-runner.exe register REM select docker-windows as the executor
- Review & edit GitLab Runner configuration (C:\GitLab-Runner\config.toml)
concurrent = 1 check_interval = 0 [session_server] session_timeout = 1800 [[runners]] name = "xxxxxx" url = "https://gitlab.com/" id = xxxx token = "xxxxxxxxx" token_obtained_at = 2022-10-20T07:51:16Z token_expires_at = 0001-01-01T00:00:00Z executor = "docker-windows" shell = "powershell" [runners.custom_build_dir] [runners.cache] [runners.cache.s3] [runners.cache.gcs] [runners.cache.azure] [runners.docker] tls_verify = false image = "mcr.microsoft.com/windows/servercore:1809" privileged = false disable_entrypoint_overwrite = false oom_kill_disable = false disable_cache = false volumes = ["C:\\Cache", "\\\\.\\pipe\\docker_engine:\\\\.\\pipe\\docker_engine"] shm_size = 0
- Download and extract PsExec in C:\PSTools from sysinternals/downloads/psexec
- Run a terminal as a service account
psexec -i -s cmd.exe
- In this new terminal, install and start GitLab Runner
cd C:\GitLab-Runner .\gitlab-runner.exe install .\gitlab-runner.exe start
GitLab Project Settings
Finally, we need to put all pieces together.
Select Settings > CI/CD in the GitLab project menu:
- Expand Runners, in Available specific runners (under Specific runners) make sure your runner is available, with the right tags
- Expand Variables, enter the variables that are needed by the pipeline
And voila, you can do the full continuous integration and delivery of your code on Windows system!
- This pipeline can also work fine with GitLab Windows Shared Runners (just update the tags) but you may face issues with long pipeline duration (more than 1 hour) because of .NET SDK large container image size (12 Go…) and GitLab restrictions with free accounts. I came over this runners thanks to this solution.
- There are no Docker-in-Docker (DIND) container image for Windows systems. I was able to figure out a solution thanks to this comment in issue#49 and issue #4295. There are multiple tickets opened in GitLab (like issue #28121) but they stay open.
- Install Rancher on Azure Kubernetes Service (AKS) - September 25, 2023
- Automate NeuVector installation and management with Fleet – The GitOps way - August 25, 2023
- AKS startup error: Token refresh failed with invalid client secret error - August 22, 2023