-
Notifications
You must be signed in to change notification settings - Fork 2k
Add Official Support for Windows Docker Images #2136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 6 commits
d5e9215
c77f154
880fca8
788df2f
47843c9
537bc56
0547704
b98f859
48e25c2
d5532b8
a8724fb
dbe54a6
e3485a7
79bf2fe
41d4d9f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
name: build-test-windows | ||
|
||
on: | ||
push: | ||
paths: | ||
- "**/windows-2019/**" | ||
- "**/windows-2022/**" | ||
- ".github/workflows/build-test-windows.yml" | ||
|
||
pull_request: | ||
paths: | ||
- "**/windows-2019/**" | ||
- "**/windows-2022/**" | ||
- ".github/workflows/build-test-windows.yml" | ||
|
||
jobs: | ||
build-windows-2019: | ||
name: build-windows-2019 | ||
runs-on: windows-2019 | ||
timeout-minutes: 60 | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
version: [ "22.8.0" ] | ||
variant: [ "windows-2019" ] | ||
|
||
steps: | ||
- name: Get short node version | ||
uses: actions/github-script@v7 | ||
id: short-version | ||
with: | ||
result-encoding: string | ||
script: return "${{ matrix.version }}".split('.')[0] | ||
|
||
- name: Checkout | ||
uses: actions/checkout@v4 | ||
|
||
# We cannot use docker/build-push-action here because it requires buildx, which is not available on Windows | ||
- name: Build image | ||
run: | | ||
docker build --tag node:${{ matrix.version }}-${{ matrix.variant }} ./${{ steps.short-version.outputs.result }}/${{ matrix.variant }} | ||
|
||
- name: Test for node version | ||
shell: pwsh | ||
run: | | ||
$image_node_version = (docker run --rm node:${{ matrix.version }}-${{ matrix.variant }} node --print "process.versions.node").Trim() | ||
Write-Host "Expected: '${{ matrix.version }}', Got: '$image_node_version'" | ||
if ($image_node_version -ne "${{ matrix.version }}") { | ||
exit 1 | ||
} | ||
|
||
- name: Verify entrypoint runs regular, non-executable files with node | ||
shell: pwsh | ||
run: | | ||
$tempDir = New-Item -ItemType Directory -Path $env:TEMP -Name "tempNodeApp" | ||
$tmp_file = Join-Path $tempDir "index.js" | ||
"console.log('success')" | Out-File -FilePath $tmp_file -Encoding utf8 | ||
$output = (docker run --rm -w /app --mount "type=bind,src=$tempDir,target=c:\app" node:${{ matrix.version }}-${{ matrix.variant }} C:/app/index.js) | ||
if ($output -ne 'success') { | ||
Write-Host "Invalid" | ||
} | ||
|
||
- name: Test for npm | ||
run: docker run --rm node:${{ matrix.version }}-${{ matrix.variant }} npm --version | ||
|
||
build-windows-2022: | ||
name: build-windows-2022 | ||
runs-on: windows-2022 | ||
timeout-minutes: 60 | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
version: [ "22.8.0" ] | ||
variant: [ "windows-2022" ] | ||
|
||
steps: | ||
- name: Get short node version | ||
uses: actions/github-script@v7 | ||
id: short-version | ||
with: | ||
result-encoding: string | ||
script: return "${{ matrix.version }}".split('.')[0] | ||
|
||
- name: Checkout | ||
uses: actions/checkout@v4 | ||
|
||
# We cannot use docker/build-push-action here because it requires buildx, which is not available on Windows | ||
- name: Build image | ||
run: | | ||
docker build --tag node:${{ matrix.version }}-${{ matrix.variant }} ./${{ steps.short-version.outputs.result }}/${{ matrix.variant }} | ||
|
||
- name: Test for node version | ||
shell: pwsh | ||
run: | | ||
$image_node_version = (docker run --rm node:${{ matrix.version }}-${{ matrix.variant }} node --print "process.versions.node").Trim() | ||
Write-Host "Expected: '${{ matrix.version }}', Got: '$image_node_version'" | ||
if ($image_node_version -ne "${{ matrix.version }}") { | ||
exit 1 | ||
} | ||
|
||
- name: Verify entrypoint runs regular, non-executable files with node | ||
shell: pwsh | ||
run: | | ||
$tempDir = New-Item -ItemType Directory -Path $env:TEMP -Name "tempNodeApp" | ||
$tmp_file = Join-Path $tempDir "index.js" | ||
"console.log('success')" | Out-File -FilePath $tmp_file -Encoding utf8 | ||
$output = (docker run --rm -w /app --mount "type=bind,src=$tempDir,target=c:\app" node:${{ matrix.version }}-${{ matrix.variant }} C:/app/index.js) | ||
if ($output -ne 'success') { | ||
Write-Host "Invalid" | ||
} | ||
|
||
- name: Test for npm | ||
run: docker run --rm node:${{ matrix.version }}-${{ matrix.variant }} npm --version |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
FROM mcr.microsoft.com/windows/servercore:ltsc2019 as installer | ||
|
||
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] | ||
|
||
# PATH isn't actually set in the Docker image, so we have to set it from within the container | ||
RUN $newPath = ('C:\Program Files (x86)\GnuPG\bin;{0}' -f $env:PATH); \ | ||
Write-Host ('Updating PATH: {0}' -f $newPath); \ | ||
[Environment]::SetEnvironmentVariable('PATH', $newPath, [EnvironmentVariableTarget]::Machine) | ||
# doing this first to share cache across versions more aggressively | ||
|
||
ENV NODE_VERSION 22.8.0 | ||
ENV NODE_CHECKSUM d6e1c4fca93997224cac0bec09b4201aa018f50171d38c6b85abe483012839c9 | ||
|
||
# Version and checksum of the GPG installer (Source: https://www.gnupg.org/download/integrity_check.html) | ||
ENV GPG_VERSION 2.4.5_20240307 | ||
ENV GPG_CHECKSUM d2ac821ceacf9409ebcdb42ae330087ada30c732981f00b356f9c2f08fac4dc1 | ||
|
||
RUN Invoke-WebRequest $('https://www.gnupg.org/ftp/gcrypt/binary/gnupg-w32-{0}.exe' -f $env:GPG_VERSION) -OutFile 'gpg-installer.exe'; \ | ||
if ((Get-FileHash gpg-installer.exe -Algorithm sha256).Hash -ne $env:GPG_CHECKSUM) { Write-Error 'GPG checksum mismatch' }; \ | ||
Start-Process -FilePath 'gpg-installer.exe' -ArgumentList '/S' -Wait; \ | ||
gpg --version; | ||
|
||
RUN @( \ | ||
'4ED778F539E3634C779C87C6D7062848A1AB005C', \ | ||
'141F07595B7B3FFE74309A937405533BE57C7D57', \ | ||
'74F12602B6F1C4E913FAA37AD3A89613643B6201', \ | ||
'DD792F5973C6DE52C432CBDAC77ABFA00DDBF2B7', \ | ||
'61FC681DFB92A079F1685E77973F295594EC4689', \ | ||
'8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600', \ | ||
'C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8', \ | ||
'890C08DB8579162FEE0DF9DB8BEAB4DFCF555EF4', \ | ||
'C82FA3AE1CBEDC6BE46B9360C43CEC45C17AB93C', \ | ||
'108F52B48DB57BB0CC439B2997B01419BD92F80A', \ | ||
'A363A499291CBBC940DD62E41F10027AF002F8B0', \ | ||
'CC68F5A3106FF448322E48ED27F5E38D5B0A215F' \ | ||
) | foreach { \ | ||
gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys $_ ; \ | ||
if (-not $?) { \ | ||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys $_ ; \ | ||
} \ | ||
} ; \ | ||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; \ | ||
Invoke-WebRequest $('https://nodejs.org/dist/v{0}/SHASUMS256.txt.asc' -f $env:NODE_VERSION) -OutFile 'SHASUMS256.txt.asc' -UseBasicParsing ; \ | ||
gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc ; \ | ||
Invoke-WebRequest $('https://nodejs.org/dist/v{0}/node-v{0}-win-x64.zip' -f $env:NODE_VERSION) -OutFile 'node.zip' -UseBasicParsing ; \ | ||
$sum = $(cat SHASUMS256.txt.asc | sls $(' node-v{0}-win-x64.zip' -f $env:NODE_VERSION)) -Split ' ' ; \ | ||
if ((Get-FileHash node.zip -Algorithm sha256).Hash -ne $sum[0]) { Write-Error 'SHA256 mismatch' } ; \ | ||
Expand-Archive node.zip -DestinationPath C:\ ; \ | ||
Rename-Item -Path $('C:\node-v{0}-win-x64' -f $env:NODE_VERSION) -NewName 'C:\nodejs' | ||
|
||
FROM mcr.microsoft.com/windows/servercore:ltsc2019 as runner | ||
|
||
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] | ||
|
||
RUN $newPath = ('C:\nodejs;{0}' -f $env:PATH); \ | ||
Write-Host ('Updating PATH: {0}' -f $newPath); \ | ||
[Environment]::SetEnvironmentVariable('PATH', $newPath, [EnvironmentVariableTarget]::Machine) | ||
|
||
COPY --from=installer C:/nodejs C:/nodejs | ||
|
||
COPY docker-entrypoint.ps1 C:/docker-entrypoint.ps1 | ||
ENTRYPOINT [ "powershell.exe" , "C:/docker-entrypoint.ps1" ] | ||
|
||
# Smoke test | ||
RUN node --version; \ | ||
npm --version; | ||
|
||
CMD [ "node.exe" ] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# Ensure script stops on any error | ||
$ErrorActionPreference = 'Stop' | ||
|
||
# Check if the first argument: | ||
# 1. Contains a "-" | ||
# 2. Is NOT a recognized command | ||
# 3. Is a file that's NOT executable | ||
if (($args[0] -like '*-') -or | ||
(!(Get-Command $args[0] -ErrorAction SilentlyContinue)) -or | ||
(((Test-Path $args[0] -PathType Leaf)) -and -not ((Get-Item $args[0]).Attributes -band 'ReadOnly'))) { | ||
# Prepend 'node' to the argument list | ||
$args = @('node') + $args | ||
} | ||
|
||
# Execute the (potentially modified) command | ||
& $args[0] $args[1..($args.Length-1)] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
FROM mcr.microsoft.com/windows/servercore:ltsc2022 as installer | ||
|
||
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] | ||
|
||
# PATH isn't actually set in the Docker image, so we have to set it from within the container | ||
RUN $newPath = ('C:\Program Files (x86)\GnuPG\bin;{0}' -f $env:PATH); \ | ||
Write-Host ('Updating PATH: {0}' -f $newPath); \ | ||
[Environment]::SetEnvironmentVariable('PATH', $newPath, [EnvironmentVariableTarget]::Machine) | ||
# doing this first to share cache across versions more aggressively | ||
|
||
ENV NODE_VERSION 22.8.0 | ||
ENV NODE_CHECKSUM d6e1c4fca93997224cac0bec09b4201aa018f50171d38c6b85abe483012839c9 | ||
|
||
# Version and checksum of the GPG installer (Source: https://www.gnupg.org/download/integrity_check.html) | ||
ENV GPG_VERSION 2.4.5_20240307 | ||
ENV GPG_CHECKSUM d2ac821ceacf9409ebcdb42ae330087ada30c732981f00b356f9c2f08fac4dc1 | ||
|
||
RUN Invoke-WebRequest $('https://www.gnupg.org/ftp/gcrypt/binary/gnupg-w32-{0}.exe' -f $env:GPG_VERSION) -OutFile 'gpg-installer.exe'; \ | ||
if ((Get-FileHash gpg-installer.exe -Algorithm sha256).Hash -ne $env:GPG_CHECKSUM) { Write-Error 'GPG checksum mismatch' }; \ | ||
Start-Process -FilePath 'gpg-installer.exe' -ArgumentList '/S' -Wait; \ | ||
gpg --version; | ||
|
||
RUN @( \ | ||
'4ED778F539E3634C779C87C6D7062848A1AB005C', \ | ||
'141F07595B7B3FFE74309A937405533BE57C7D57', \ | ||
'74F12602B6F1C4E913FAA37AD3A89613643B6201', \ | ||
'DD792F5973C6DE52C432CBDAC77ABFA00DDBF2B7', \ | ||
'61FC681DFB92A079F1685E77973F295594EC4689', \ | ||
'8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600', \ | ||
'C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8', \ | ||
'890C08DB8579162FEE0DF9DB8BEAB4DFCF555EF4', \ | ||
'C82FA3AE1CBEDC6BE46B9360C43CEC45C17AB93C', \ | ||
'108F52B48DB57BB0CC439B2997B01419BD92F80A', \ | ||
'A363A499291CBBC940DD62E41F10027AF002F8B0', \ | ||
'CC68F5A3106FF448322E48ED27F5E38D5B0A215F' \ | ||
) | foreach { \ | ||
gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys $_ ; \ | ||
if (-not $?) { \ | ||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys $_ ; \ | ||
} \ | ||
} ; \ | ||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; \ | ||
Invoke-WebRequest $('https://nodejs.org/dist/v{0}/SHASUMS256.txt.asc' -f $env:NODE_VERSION) -OutFile 'SHASUMS256.txt.asc' -UseBasicParsing ; \ | ||
gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc ; \ | ||
Invoke-WebRequest $('https://nodejs.org/dist/v{0}/node-v{0}-win-x64.zip' -f $env:NODE_VERSION) -OutFile 'node.zip' -UseBasicParsing ; \ | ||
$sum = $(cat SHASUMS256.txt.asc | sls $(' node-v{0}-win-x64.zip' -f $env:NODE_VERSION)) -Split ' ' ; \ | ||
if ((Get-FileHash node.zip -Algorithm sha256).Hash -ne $sum[0]) { Write-Error 'SHA256 mismatch' } ; \ | ||
Expand-Archive node.zip -DestinationPath C:\ ; \ | ||
Rename-Item -Path $('C:\node-v{0}-win-x64' -f $env:NODE_VERSION) -NewName 'C:\nodejs' | ||
|
||
FROM mcr.microsoft.com/windows/servercore:ltsc2022 as runner | ||
|
||
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] | ||
|
||
RUN $newPath = ('C:\nodejs;{0}' -f $env:PATH); \ | ||
Write-Host ('Updating PATH: {0}' -f $newPath); \ | ||
[Environment]::SetEnvironmentVariable('PATH', $newPath, [EnvironmentVariableTarget]::Machine) | ||
|
||
COPY --from=installer C:/nodejs C:/nodejs | ||
|
||
COPY docker-entrypoint.ps1 C:/docker-entrypoint.ps1 | ||
ENTRYPOINT [ "powershell.exe" , "C:/docker-entrypoint.ps1" ] | ||
|
||
# Smoke test | ||
RUN node --version; \ | ||
npm --version; | ||
|
||
CMD [ "node.exe" ] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# Ensure script stops on any error | ||
$ErrorActionPreference = 'Stop' | ||
|
||
# Check if the first argument: | ||
# 1. Contains a "-" | ||
# 2. Is NOT a recognized command | ||
# 3. Is a file that's NOT executable | ||
if (($args[0] -like '*-') -or | ||
(!(Get-Command $args[0] -ErrorAction SilentlyContinue)) -or | ||
(((Test-Path $args[0] -PathType Leaf)) -and -not ((Get-Item $args[0]).Attributes -band 'ReadOnly'))) { | ||
# Prepend 'node' to the argument list | ||
$args = @('node') + $args | ||
} | ||
|
||
# Execute the (potentially modified) command | ||
& $args[0] $args[1..($args.Length-1)] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
FROM mcr.microsoft.com/windows/servercore:version as installer | ||
|
||
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] | ||
|
||
# PATH isn't actually set in the Docker image, so we have to set it from within the container | ||
RUN $newPath = ('C:\Program Files (x86)\GnuPG\bin;{0}' -f $env:PATH); \ | ||
Write-Host ('Updating PATH: {0}' -f $newPath); \ | ||
[Environment]::SetEnvironmentVariable('PATH', $newPath, [EnvironmentVariableTarget]::Machine) | ||
# doing this first to share cache across versions more aggressively | ||
|
||
ENV NODE_VERSION 0.0.0 | ||
ENV NODE_CHECKSUM CHECKSUM_x64 | ||
|
||
# Version and checksum of the GPG installer (Source: https://www.gnupg.org/download/integrity_check.html) | ||
ENV GPG_VERSION 2.4.5_20240307 | ||
ENV GPG_CHECKSUM d2ac821ceacf9409ebcdb42ae330087ada30c732981f00b356f9c2f08fac4dc1 | ||
|
||
RUN Invoke-WebRequest $('https://www.gnupg.org/ftp/gcrypt/binary/gnupg-w32-{0}.exe' -f $env:GPG_VERSION) -OutFile 'gpg-installer.exe'; \ | ||
if ((Get-FileHash gpg-installer.exe -Algorithm sha256).Hash -ne $env:GPG_CHECKSUM) { Write-Error 'GPG checksum mismatch' }; \ | ||
Start-Process -FilePath 'gpg-installer.exe' -ArgumentList '/S' -Wait; \ | ||
zZHorizonZz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
gpg --version; | ||
|
||
RUN @( \ | ||
"${NODE_KEYS[@]}" | ||
) | foreach { \ | ||
gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys $_ ; \ | ||
if (-not $?) { \ | ||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys $_ ; \ | ||
} \ | ||
} ; \ | ||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; \ | ||
Invoke-WebRequest $('https://nodejs.org/dist/v{0}/SHASUMS256.txt.asc' -f $env:NODE_VERSION) -OutFile 'SHASUMS256.txt.asc' -UseBasicParsing ; \ | ||
gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc ; \ | ||
Invoke-WebRequest $('https://nodejs.org/dist/v{0}/node-v{0}-win-x64.zip' -f $env:NODE_VERSION) -OutFile 'node.zip' -UseBasicParsing ; \ | ||
$sum = $(cat SHASUMS256.txt.asc | sls $(' node-v{0}-win-x64.zip' -f $env:NODE_VERSION)) -Split ' ' ; \ | ||
if ((Get-FileHash node.zip -Algorithm sha256).Hash -ne $sum[0]) { Write-Error 'SHA256 mismatch' } ; \ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @zZHorizonZz to meet what @tianon said, I think you could change these 2 line to be
The reason why this is better is that the images get rebuilt when the base image changes so if the server was compromised, the key would be changed at the same time as the archive. This means that the arcgive can't change or rebuilds would fail. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @LaurentGoderre It's not really just about changing these two lines. If we check the checksum, we don't really need GPG or multistage, which makes it simpler. So, what I'll do is remove the GPG installation and SHA256 download and replace it with verification through the NODE_CHECKSUM variable. I'll also remove the multistage as that's not necessary if we're going this way. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Aren't these two different checks though? One checks it wasn't modified, the other checks it came from the release team There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm starting to get a little bit confused here. If we change these two lines:
To this:
We validate the checksum against the supplied checksum There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah yeah, my bad. We might be good to just have the hardcoded checksum and no gpg |
||
Expand-Archive node.zip -DestinationPath C:\ ; \ | ||
Rename-Item -Path $('C:\node-v{0}-win-x64' -f $env:NODE_VERSION) -NewName 'C:\nodejs' | ||
|
||
FROM mcr.microsoft.com/windows/servercore:version as runner | ||
|
||
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] | ||
|
||
RUN $newPath = ('C:\nodejs;{0}' -f $env:PATH); \ | ||
Write-Host ('Updating PATH: {0}' -f $newPath); \ | ||
[Environment]::SetEnvironmentVariable('PATH', $newPath, [EnvironmentVariableTarget]::Machine) | ||
|
||
COPY --from=installer C:/nodejs C:/nodejs | ||
|
||
COPY docker-entrypoint.ps1 C:/docker-entrypoint.ps1 | ||
ENTRYPOINT [ "powershell.exe" , "C:/docker-entrypoint.ps1" ] | ||
LaurentGoderre marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
# Smoke test | ||
RUN node --version; \ | ||
npm --version; | ||
zZHorizonZz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
CMD [ "node.exe" ] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,8 @@ | ||
bashbrew-arch variants | ||
amd64 alpine3.19,alpine3.20,bookworm,bookworm-slim,bullseye,bullseye-slim | ||
amd64 alpine3.19,alpine3.20,bookworm,bookworm-slim,bullseye,bullseye-slim,windows-2019,windows-2022 | ||
arm32v6 alpine3.19,alpine3.20 | ||
arm32v7 alpine3.19,alpine3.20,bookworm,bookworm-slim,bullseye,bullseye-slim | ||
arm64v8 alpine3.19,alpine3.20,bookworm,bookworm-slim,bullseye,bullseye-slim | ||
i386 alpine3.19,alpine3.20 | ||
ppc64le alpine3.19,alpine3.20,bookworm,bookworm-slim,bullseye,bullseye-slim | ||
s390x alpine3.19,alpine3.20,bookworm,bookworm-slim,bullseye,bullseye-slim | ||
s390x alpine3.19,alpine3.20,bookworm,bookworm-slim,bullseye,bullseye-slim |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# Ensure script stops on any error | ||
$ErrorActionPreference = 'Stop' | ||
|
||
# Check if the first argument: | ||
# 1. Contains a "-" | ||
# 2. Is NOT a recognized command | ||
# 3. Is a file that's NOT executable | ||
if (($args[0] -like '*-') -or | ||
(!(Get-Command $args[0] -ErrorAction SilentlyContinue)) -or | ||
(((Test-Path $args[0] -PathType Leaf)) -and -not ((Get-Item $args[0]).Attributes -band 'ReadOnly'))) { | ||
# Prepend 'node' to the argument list | ||
$args = @('node') + $args | ||
} | ||
|
||
# Execute the (potentially modified) command | ||
& $args[0] $args[1..($args.Length-1)] |
Uh oh!
There was an error while loading. Please reload this page.