Regression: GitLab Runner v17.8 on Windows no longer uses git system-level settings, resulting in e.g. "core.autocrlf" being disabled

Summary

Since GitLab Runner v17.8 on Windows the git system-level settings are no longer using when cloning a repository. This includes core.autocrlf which transforms line endings to Windows style.

Having your files checked out with LF line endings can cause scripts etc. to fail because Windows style CRLF endings are expected / required. This might cause different failures on scripts.

Steps to reproduce

Run a simple job on a docker-windows executor and check the file endings after checkout. Before GitLab Runner v17.8 they always were transformed to CRLF, now they use the line endings present in the git repository.

In particular we have the following (simplified) job which no longer can be executed and just throws a lot of errors.

.gitlab-ci.yml
test:
  stage: test
  needs: []
  image: mcr.microsoft.com/powershell:latest
  tags:
    - docker-windows
  script:
    - ./tests.bat
tests.bat (make sure it has LF endings in git)
@echo on

echo Tests vorbereiten

mkdir vuetifyViews
mkdir vuetifyViews\css
mkdir vuetifyViews\fonts
mkdir vuetifyViews\js

echo Tests ausführen...
echo Tests abgeschlossen

EXIT %errorlevel%

Actual behavior

Since GitLab Runner v17.8 the system-level git settings are no longer being used by the gitlab-runner-helper when cloning a git repository. This effects settings like core.longpaths (see #38540 (closed) and #38587 (closed)) but also core.autocrlf.

This can be easily checked by just running the gitlab-runner-helper image with v17.6.1 and comparing it to v17.8.3:

  • GitLab Runner v17.6.1 includes the system-level settings

image

  • GitLab Runner v17.8.3 does not include the system-level settings

image

While this change affects a range of settings, we were primarily impacted by the core.autocrlf setting no longer being available.

Expected behavior

The gitlab-runner-helper on Windows should enable core.autocrlf, which is the default configuration for Git on Windows. This can be done by re-enabling the system-level settings.

Relevant logs and/or screenshots

Job log
$ ./tests.bat
C:\builds\my-group\my-project>echo Tests vorbereiten 
Tests vorbereiten
C:\builds\my-group\my-project>mkdir vuetifyViews 
C:\builds\my-group\my-project>kdir vuetifyViews\css 
'kdir' is not recognized as an internal or external command,
operable program or batch file.
C:\builds\my-group\my-project>kdir vuetifyViews\fonts 
'kdir' is not recognized as an internal or external command,
operable program or batch file.
C:\builds\my-group\my-project>kdir vuetifyViews\js 
'kdir' is not recognized as an internal or external command,
operable program or batch file.
C:\builds\my-group\my-project>echo Tests ausführen... 
Tests ausführen...
C:\builds\my-group\my-project>echo Tests abgeschlossen 
Tests abgeschlossen
C:\builds\my-group\my-project>EXIT 9009 
Cleaning up project directory and file based variables
ERROR: Job failed: exit code 9009

Environment description

config.toml contents
listen_address = ":9252"
concurrent = 3
check_interval = 0
connection_max_age = "15m0s"
shutdown_timeout = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "windows-runner-001"
  output_limit = 409600
  url = "https://git.company.local"
  id = 21720
  token = "[REDACTED]"
  token_obtained_at = 2025-02-26T10:58:04Z
  token_expires_at = 0001-01-01T00:00:00Z
  executor = "docker-windows"
  builds_dir = "C:\\builds"
  shell = "powershell"
  [runners.custom_build_dir]
    enabled = true
  [runners.cache]
    Type = "s3"
    Shared = true
    MaxUploadedArchiveSize = 0
    [runners.cache.s3]
      ServerAddress = "cache.company.local"
      AccessKey = "[REDACTED]"
      SecretKey = "[REDACTED]"
      BucketName = "gitlab-runner"
      AuthenticationType = "access-key"
    [runners.cache.gcs]
    [runners.cache.azure]
  [runners.feature_flags]
    FF_USE_IMPROVED_URL_MASKING = true
  [runners.docker]
    tls_verify = false
    image = "mcr.microsoft.com/windows/servercore:ltsc2022"
    privileged = false
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["c:\\cache"]
    pull_policy = ["always"]
    shm_size = 0
    network_mtu = 0

Used GitLab Runner version

Version:      17.8.3
Git revision: 690ce25c
Git branch:   17-8-stable
GO version:   go1.23.2 X:cacheprog
Built:        unknown
OS/Arch:      windows/amd64

Possible fixes

The git system-level settings are no longer being processed because the GIT_CONFIG_NOSYSTEM variable is being set: https://gitlab.com/gitlab-org/ci-cd/runner-tools/base-images/-/blob/ec090a5bab5e9171875bb417ab11801355b2057d/dockerfiles/runner-helper/Dockerfile.x86_64#L33

Docs: https://git-scm.com/docs/git (GIT_CONFIG_NOSYSTEM)

This flag has been enabled in the GitLab Runner codebase for about 4 years, before the refactoring it was enabled here: https://gitlab.com/gitlab-org/gitlab-runner/-/blob/v17.6.1/dockerfiles/runner-helper/Dockerfile.x86_64_servercore#L48-53

Apparently that did not have any effect, because running an older container and checking the environment variables did not show it - which is why git applied the system-level settings like core.autocrlf and core.longpaths. As a workaround one can unset the variable as part of pre_get_sources_script, but that solution does not scale very well.