No pod logs on kubernetes executor with powershell

Summary

When running with powershell & with the kubernetes executor, the output of the build is not exposed to stdout/stderr, but only to the logfile. Therefore, logs are not visible to kubernetes itself, and things like kubectl logs ... and any log processing pulling the logs via the k8s API won't work.

For all other shells the output is forwarded to the log file and to stdout.

Note: The logs still are pushed to gitlab, and show up there. But they are not exposed to stdout, for kubernetes to pick them up.

Steps to reproduce

.gitlab-ci.yml
test:
  stage: test
  image: registry.gitlab.com/gitlab-org/gitlab-runner/gitlab-runner-helper:x86_64-latest-servercore1809
  script:
    - |
      echo "hello"

Actual behavior

When running a powershell job that produces output, that output is does not show up when e.g. using kubectl tail ... or any other means to pull logs via the k8s API.

Expected behavior

A job running with powershell should also, in addition to forwarding logs to the log file, dump them on stdout. All other shells do that.

Environment description

config.toml contents

To run powershell, we need a k8s cluster with windows nodes. powershell, as opposed to pwsh, won't run on linux.

listen_address = ":9252"
concurrent = 4
check_interval = 0
connection_max_age = "15m0s"
shutdown_timeout = 0
[session_server]
  session_timeout = 1800
[[runners]]
  name = "gke-win-0"
  url = "https://gitlab.com/"
  id = 0
  token = "glrt-NopeNopeNope"
  token_obtained_at = 0001-01-01T00:00:00Z
  token_expires_at = 0001-01-01T00:00:00Z
  executor = "kubernetes"
  shell = "powershell"
  environment = ["FF_USE_POWERSHELL_PATH_RESOLVER=true"]
  [runners.kubernetes]
    poll_timeout = 1200
    pull_policy = "always"
  [runners.kubernetes.node_selector]
    "kubernetes.io/arch" = "amd64"
    "kubernetes.io/os" = "windows"
    "node.kubernetes.io/windows-build" = "10.0.17763"

Used GitLab Runner version

11989094

Possible fixes

There is specific code for only pwoershell in the k8s executor, which makes it behave differently than any other shell: https://gitlab.com/gitlab-org/gitlab-runner/-/blob/main/executors/kubernetes/kubernetes.go?ref_type=heads#L1134 . On a first glance, we are "just" missing a tee/Tee-Object, however the Tee-Object before PowerShell 7.2 does not support the -Encoding parameter, which would then break the json termination parsing. And as long as we support win 1809 we have to support that still.

In Fix powershell native command error output with... (!4474 - merged) we've introduced ForEach-Object/%{} to convert to strings. We could leverage that and in addition to converting to string also dump out the log with Write-Host, e.g. something like:

-                 return fmt.Sprintf("2>&1 | %%{ \"$_\" } | Out-File -Append -Encoding UTF8 %s", s.logFile())
+                 return fmt.Sprintf("2>&1 | %%{ \"$_\" ; Write-Host $_ } | Out-File -Append -Encoding UTF8 %s", s.logFile())