Enable PowerShell Core support in Docker Executor on Linux
Description
The Docker Executor currently supports running commands from bash
and sh
(sources: here and here). Microsoft has been doing a whole lot of work over the past few years and have built the current version of PowerShell to run not only on Windows, but various Linux distributions and macOS, as well. However, when a Linux Docker image with PowerShell as the default shell is specified for a CI job, GitLab Runner forcefully uses bash
or sh
to run the commands specified in the job's script
, e.g. Write-Output $PSVersionTable
. There are workarounds, including a) wrapping each PowerShell command so that PowerShell will run it, e.g. pwsh -Command { Write-Output $PSVersionTable }
and b) writing your job as a .ps1 script and executing the script using PowerShell, e.g. pwsh -File ./gitlab-ci-job.ps1
(this approach has caveats that now the source code must be checked out for the job to run and the PowerShell script has to internally manage the exit code return (usually done by GitLab)).
My specific use case is trying to deploy build artifacts from previous jobs to a Windows machine. I've built a container (yes, it's a bit undocumented and quick/dirty)(shawmanz32na/ssh-powershell-client) that uses PowerShell by default (launching the container drops you in a PowerShell prompt). A sample CI job to use this container is:
deploy_qa:
stage: deploy
dependencies:
- build
image: shawmanz32na/ssh-powershell-client
script:
- $remoteSession = New-PSSession -HostName "the.qa.machine" -UserName "theDeploymentUser"
- Copy-Item -Path path/to/build/job.artifact -Destination C:/Users/theDeploymentUser/Local/Temp -ToSession $remoteSession
- Remove-PSSession -Session $remoteSession
This script explodes with syntax errors and/or reporting that New-PSSession isn't a valid command/script/executable.
A simpler reproducible case is:
sample_job:
image: shawmanz32na/ssh-powershell-client
script:
- Write-Output $PSVersionTable
This script will also fail with messages that Write-Output isn't a command/script/executable. Were it to succeed, it would print out the running PowerShell edition and version.
Proposal
- Have
docker
executor choose betweenpwsh
andbash
depending on the userconfig.toml
. We need to remove any assumptions we have that we are using abash
shell. - Update the linux helper image to have pwsh installed. There are several consider things to consider:
- Powershell Core 7 does not support all the platforms that the gitlab-runner-helper supports, namely
arm64
, alpinearm
, ors390x
. - How much of size increase there would be by having pwsh installed since this container is used multiple times.
- Based on the 2 points above, it might be worth having a separate image just for
pwsh
and then have the executor chooses the right image based on the shell requested.- Update
ci/build_helper_docker
to create an additional Alpine Linux amd64 image (based on the regular one) that includes Powershell Core 7 installed (e.g.dockerfiles/runner-helper/Dockerfile.pwsh.x86_64
. - Only address x86_64 for now and leave other platforms for future iterations, based on demand.
- Update
- Powershell Core 7 does not support all the platforms that the gitlab-runner-helper supports, namely
- Somehow update gitlab-runner-build or the usage of it to support both bash and
pwsh
so it doesn't mess up helper image commands.
Links to related issues and merge requests / references
- PoC !1855 (closed)
- Investigation issue #3291 (closed)