From d5e9215a067ad921dab856ef11f3f029e30d30b4 Mon Sep 17 00:00:00 2001 From: Daniel Fiala Date: Thu, 29 Aug 2024 07:59:19 +0200 Subject: [PATCH] Squash commits --- .github/workflows/build-test-windows.yml | 113 +++++++++++++++++++++++ 22/windows-2019/Dockerfile | 62 +++++++++++++ 22/windows-2019/docker-entrypoint.ps1 | 16 ++++ 22/windows-2022/Dockerfile | 62 +++++++++++++ 22/windows-2022/docker-entrypoint.ps1 | 16 ++++ Dockerfile-windows.template | 51 ++++++++++ architectures | 4 +- docker-entrypoint.ps1 | 16 ++++ functions.sh | 10 ++ genMatrix.js | 13 ++- update.sh | 62 ++++++++++--- 11 files changed, 405 insertions(+), 20 deletions(-) create mode 100644 .github/workflows/build-test-windows.yml create mode 100644 22/windows-2019/Dockerfile create mode 100644 22/windows-2019/docker-entrypoint.ps1 create mode 100644 22/windows-2022/Dockerfile create mode 100644 22/windows-2022/docker-entrypoint.ps1 create mode 100644 Dockerfile-windows.template create mode 100644 docker-entrypoint.ps1 diff --git a/.github/workflows/build-test-windows.yml b/.github/workflows/build-test-windows.yml new file mode 100644 index 000000000..b0d23dbbb --- /dev/null +++ b/.github/workflows/build-test-windows.yml @@ -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.7.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.7.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 \ No newline at end of file diff --git a/22/windows-2019/Dockerfile b/22/windows-2019/Dockerfile new file mode 100644 index 000000000..ac88ae888 --- /dev/null +++ b/22/windows-2019/Dockerfile @@ -0,0 +1,62 @@ +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.7.0 +ENV NODE_CHECKSUM 3fc638727974262b4f65a6b1b43c22fb2d80671cdcb50e1237e0b05d1330aaf7 + +ENV GPG_VERSION 2.4.5_20240307 + +RUN Invoke-WebRequest $('https://www.gnupg.org/ftp/gcrypt/binary/gnupg-w32-{0}.exe' -f $env:GPG_VERSION) -OutFile 'gpg-installer.exe'; \ + 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 --keyserver hkps://keys.openpgp.org --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" ] \ No newline at end of file diff --git a/22/windows-2019/docker-entrypoint.ps1 b/22/windows-2019/docker-entrypoint.ps1 new file mode 100644 index 000000000..87cbc8b77 --- /dev/null +++ b/22/windows-2019/docker-entrypoint.ps1 @@ -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)] \ No newline at end of file diff --git a/22/windows-2022/Dockerfile b/22/windows-2022/Dockerfile new file mode 100644 index 000000000..380f332b2 --- /dev/null +++ b/22/windows-2022/Dockerfile @@ -0,0 +1,62 @@ +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.7.0 +ENV NODE_CHECKSUM 3fc638727974262b4f65a6b1b43c22fb2d80671cdcb50e1237e0b05d1330aaf7 + +ENV GPG_VERSION 2.4.5_20240307 + +RUN Invoke-WebRequest $('https://www.gnupg.org/ftp/gcrypt/binary/gnupg-w32-{0}.exe' -f $env:GPG_VERSION) -OutFile 'gpg-installer.exe'; \ + 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 --keyserver hkps://keys.openpgp.org --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" ] \ No newline at end of file diff --git a/22/windows-2022/docker-entrypoint.ps1 b/22/windows-2022/docker-entrypoint.ps1 new file mode 100644 index 000000000..87cbc8b77 --- /dev/null +++ b/22/windows-2022/docker-entrypoint.ps1 @@ -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)] \ No newline at end of file diff --git a/Dockerfile-windows.template b/Dockerfile-windows.template new file mode 100644 index 000000000..1dc92248b --- /dev/null +++ b/Dockerfile-windows.template @@ -0,0 +1,51 @@ +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 + +ENV GPG_VERSION 2.4.5_20240307 + +RUN Invoke-WebRequest $('https://www.gnupg.org/ftp/gcrypt/binary/gnupg-w32-{0}.exe' -f $env:GPG_VERSION) -OutFile 'gpg-installer.exe'; \ + Start-Process -FilePath 'gpg-installer.exe' -ArgumentList '/S' -Wait; \ + gpg --version; + +RUN @( \ + "${NODE_KEYS[@]}" + ) | foreach { \ + gpg --keyserver hkps://keys.openpgp.org --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: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" ] + +# Smoke test +RUN node --version; \ + npm --version; + +CMD [ "node.exe" ] \ No newline at end of file diff --git a/architectures b/architectures index 1cb4bf352..ad889beb8 100644 --- a/architectures +++ b/architectures @@ -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 \ No newline at end of file diff --git a/docker-entrypoint.ps1 b/docker-entrypoint.ps1 new file mode 100644 index 000000000..87cbc8b77 --- /dev/null +++ b/docker-entrypoint.ps1 @@ -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)] \ No newline at end of file diff --git a/functions.sh b/functions.sh index bee3dafe0..c2e861b20 100755 --- a/functions.sh +++ b/functions.sh @@ -193,6 +193,16 @@ function is_debian_slim() { return 1 } +function is_windows() { + local variant + variant=$1 + shift + + if [ "${variant}" = "${variant#windows}" ]; then + return 1 + fi +} + function get_fork_name() { local version version=$1 diff --git a/genMatrix.js b/genMatrix.js index 9f57ea509..fd90954ac 100644 --- a/genMatrix.js +++ b/genMatrix.js @@ -8,23 +8,25 @@ const testFiles = [ ]; const nodeDirRegex = /^\d+$/; +// Directories starting with 'windows-' are excluded from the matrix windows-2019 are excluded for example +const windowsDirRegex = /^windows-/; const areTestFilesChanged = (changedFiles) => changedFiles .some((file) => testFiles.includes(file)); -// Returns a list of the child directories in the given path +// Returns a list of the child directories in the given path, excluding those starting with 'windows-' const getChildDirectories = (parent) => fs.readdirSync(parent, { withFileTypes: true }) - .filter((dirent) => dirent.isDirectory()) + .filter((directory) => directory.isDirectory()) .map(({ name }) => path.resolve(parent, name)); -const getNodeVerionDirs = (base) => getChildDirectories(base) +const getNodeVersionDirs = (base) => getChildDirectories(base) .filter((childPath) => nodeDirRegex.test(path.basename(childPath))); // Returns the paths of Dockerfiles that are at: base/*/Dockerfile const getDockerfilesInChildDirs = (base) => getChildDirectories(base) .map((childDir) => path.resolve(childDir, 'Dockerfile')); -const getAllDockerfiles = (base) => getNodeVerionDirs(base).flatMap(getDockerfilesInChildDirs); +const getAllDockerfiles = (base) => getNodeVersionDirs(base).flatMap(getDockerfilesInChildDirs); const getAffectedDockerfiles = (filesAdded, filesModified, filesRenamed) => { const files = [ @@ -69,7 +71,8 @@ const getDockerfileMatrixEntry = (file) => { const generateBuildMatrix = (filesAdded, filesModified, filesRenamed) => { const dockerfiles = [...new Set(getAffectedDockerfiles(filesAdded, filesModified, filesRenamed))]; - const entries = dockerfiles.map(getDockerfileMatrixEntry); + let entries = dockerfiles.map(getDockerfileMatrixEntry); + entries = entries.filter((entry) => !windowsDirRegex.test(entry.variant)); // Return null if there are no entries so we can skip the matrix step return entries.length diff --git a/update.sh b/update.sh index 0b6aaf69d..aba1caa73 100755 --- a/update.sh +++ b/update.sh @@ -5,22 +5,24 @@ set -ue function usage() { cat << EOF - Update the node docker images. + Update the node Docker images. Usage: - $0 [-s] [MAJOR_VERSION(S)] [VARIANT(S)] + $0 [-s] [-w] [MAJOR_VERSION(S)] [VARIANT(S)] Examples: - - update.sh # Update all images - - update.sh -s # Update all images, skip updating Alpine and Yarn - - update.sh 8,10 # Update all variants of version 8 and 10 - - update.sh -s 8 # Update version 8 and variants, skip updating Alpine and Yarn - - update.sh 8 alpine # Update only alpine's variants for version 8 - - update.sh -s 8 bullseye # Update only bullseye variant for version 8, skip updating Alpine and Yarn - - update.sh . alpine # Update the alpine variant for all versions + - update.sh # Update all images + - update.sh -s # Update all images, skip updating Alpine and Yarn + - update.sh -w # Update only Windows images + - update.sh 8,10 # Update all variants of version 8 and 10 + - update.sh -s 8 # Update version 8 and variants, skip updating Alpine and Yarn + - update.sh 8 alpine # Update only Alpine variants for version 8 + - update.sh -w 8 windows-2022 # Update only Windows 2022 variant for version 8 + - update.sh . alpine # Update the Alpine variant for all versions OPTIONS: - -s Security update; skip updating the yarn and alpine versions. + -s Security update; skip updating the Yarn and Alpine versions. + -w Windows images update only -b CI config update only -h Show this message @@ -28,12 +30,17 @@ EOF } SKIP=false -while getopts "sh" opt; do +WINDOWS_ONLY=false +while getopts "swh" opt; do case "${opt}" in s) SKIP=true shift ;; + w) + WINDOWS_ONLY=true + shift + ;; h) usage exit @@ -144,9 +151,18 @@ function update_node_version() { # Add GPG keys for key_type in "node" "yarn"; do + last_line=$(tail -n 1 "keys/${key_type}.keys") while read -r line; do pattern='"\$\{'$(echo "${key_type}" | tr '[:lower:]' '[:upper:]')'_KEYS\[@\]\}"' - sed -Ei -e "s/([ \\t]*)(${pattern})/\\1${line}${new_line}\\1\\2/" "${dockerfile}-tmp" + if is_windows "${variant}"; then + if [ "$line" = "$last_line" ]; then # Check if it's the last key + sed -Ei -e "s/([ \\t]*)(${pattern})/\\1'${line}'${new_line}\\1\\2/" "${dockerfile}-tmp" + else + sed -Ei -e "s/([ \\t]*)(${pattern})/\\1'${line}',${new_line}\\1\\2/" "${dockerfile}-tmp" + fi + else + sed -Ei -e "s/([ \\t]*)(${pattern})/\\1${line}${new_line}\\1\\2/" "${dockerfile}-tmp" + fi done < "keys/${key_type}.keys" sed -Ei -e "/${pattern}/d" "${dockerfile}-tmp" done @@ -167,6 +183,18 @@ function update_node_version() { sed -Ei -e "s/(buildpack-deps:)name/\\1${variant}/" "${dockerfile}-tmp" elif is_debian_slim "${variant}"; then sed -Ei -e "s/(debian:)name-slim/\\1${variant}/" "${dockerfile}-tmp" + elif is_windows "${variant}"; then + windows_version="${variant#*windows-}" + checksum=$( + curl -sSL --compressed "https://nodejs.org/dist/v${nodeVersion}/SHASUMS256.txt" | grep "node-v${nodeVersion}-win-x64.zip" | cut -d' ' -f1 + ) + if [ -z "$checksum" ]; then + rm -f "${dockerfile}-tmp" + fatal "Failed to fetch checksum for version ${nodeVersion}" + fi + sed -Ei -e "s/mcr\.microsoft\.com\/windows\/servercore:version/mcr\.microsoft\.com\/windows\/servercore:ltsc${windows_version}/" "${dockerfile}-tmp" + sed -Ei -e "s/mcr\.microsoft\.com\/windows\/nanoserver:version/mcr\.microsoft\.com\/windows\/nanoserver:ltsc${windows_version}/" "${dockerfile}-tmp" + sed -Ei -e 's/^(ENV NODE_CHECKSUM ).*/\1'"${checksum}"'/' "${dockerfile}-tmp" fi if diff -q "${dockerfile}-tmp" "${dockerfile}" > /dev/null; then @@ -223,9 +251,17 @@ for version in "${versions[@]}"; do template_file="${parentpath}/Dockerfile-slim.template" elif is_alpine "${variant}"; then template_file="${parentpath}/Dockerfile-alpine.template" + elif is_windows "${variant}"; then + template_file="${parentpath}/Dockerfile-windows.template" + fi + + # Copy .sh only if not is_windows + if ! is_windows "${variant}"; then + cp "${parentpath}/docker-entrypoint.sh" "${version}/${variant}/docker-entrypoint.sh" + elif is_windows "${variant}"; then + cp "${parentpath}/docker-entrypoint.ps1" "${version}/${variant}/docker-entrypoint.ps1" fi - cp "${parentpath}/docker-entrypoint.sh" "${version}/${variant}/docker-entrypoint.sh" if [ "${update_version}" -eq 0 ] && [ "${update_variant}" -eq 0 ]; then update_node_version "${baseuri}" "${versionnum}" "${template_file}" "${version}/${variant}/Dockerfile" "${variant}" & pids+=($!)