From 8835355ee5c5918ee9536c5918a0864b2459f22f Mon Sep 17 00:00:00 2001 From: Lee Rowlands Date: Tue, 30 Jun 2026 13:38:58 +1000 Subject: [PATCH 01/12] Add node 26 --- .github/workflows/build-pr.yml | 13 ++++++++++++- .github/workflows/build-push.yml | 13 ++++++++++++- .github/workflows/security-scan.yml | 2 ++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index ebed3bd..ab4042e 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -13,7 +13,17 @@ jobs: strategy: fail-fast: false matrix: - node: [ '20', '22', '24' ] + node: [ '20', '22', '24', '26' ] + alpine: [ '3.21', '3.24'] + exclude: + - node: '20' + alpine: '3.24' + - node: '22' + alpine: '3.24' + - node: '24' + alpine: '3.24' + - node: '26' + alpine: '3.21' steps: - name: Checkout repository @@ -26,6 +36,7 @@ jobs: uses: docker/bake-action@v6 env: NODE_VERSION: ${{ matrix.node }} + ALPINE_VERSION: ${{ matrix.alpine }} STREAM: ${{ env.stream }} with: source: . diff --git a/.github/workflows/build-push.yml b/.github/workflows/build-push.yml index 15d3978..7b05821 100644 --- a/.github/workflows/build-push.yml +++ b/.github/workflows/build-push.yml @@ -38,7 +38,17 @@ jobs: strategy: fail-fast: false matrix: - node: [ '20', '22', '24' ] + node: [ '20', '22', '24', '26' ] + alpine: [ '3.21', '3.24'] + exclude: + - node: '20' + alpine: '3.24' + - node: '22' + alpine: '3.24' + - node: '24' + alpine: '3.24' + - node: '26' + alpine: '3.21' steps: - name: 📥 Checkout repository @@ -66,6 +76,7 @@ jobs: uses: docker/bake-action@v6 env: NODE_VERSION: ${{ matrix.node }} + ALPINE_VERSION: ${{ matrix.alpine }} STREAM: ${{ inputs.stream }} with: source: . diff --git a/.github/workflows/security-scan.yml b/.github/workflows/security-scan.yml index 492ddf4..054166b 100644 --- a/.github/workflows/security-scan.yml +++ b/.github/workflows/security-scan.yml @@ -18,6 +18,8 @@ jobs: fail-fast: false matrix: image_ref: + - ghcr.io/skpr/node:26-v3-latest + - ghcr.io/skpr/node:dev-26-v3-latest - ghcr.io/skpr/node:24-v3-latest - ghcr.io/skpr/node:dev-24-v3-latest - ghcr.io/skpr/node:22-v3-latest From d71a1290f92db0e695ff8646a8160ab163284dec Mon Sep 17 00:00:00 2001 From: Lee Rowlands Date: Tue, 30 Jun 2026 13:49:19 +1000 Subject: [PATCH 02/12] Empty commit From 688ae0e149645b992ca74567cee5565b70c59d74 Mon Sep 17 00:00:00 2001 From: Kim Pepper Date: Tue, 30 Jun 2026 15:01:05 +1000 Subject: [PATCH 03/12] Install yarn globally --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 662c285..1a5043a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -42,6 +42,7 @@ RUN mkdir /data && chown skpr:skpr /data WORKDIR /data # Replace npm with a wrapper script to enforce security. +RUN npm install -g yarn RUN mv /usr/local/bin/npm /usr/local/bin/npm-unsafe ADD --chown=skpr:skpr bin/npm-wrapper /usr/local/bin/npm RUN chmod +x /usr/local/bin/npm From 76b01212d197e1e7a169aad555196e4966b2f6ca Mon Sep 17 00:00:00 2001 From: Kim Pepper Date: Tue, 30 Jun 2026 15:04:24 +1000 Subject: [PATCH 04/12] Force install --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 1a5043a..3694287 100644 --- a/Dockerfile +++ b/Dockerfile @@ -42,7 +42,7 @@ RUN mkdir /data && chown skpr:skpr /data WORKDIR /data # Replace npm with a wrapper script to enforce security. -RUN npm install -g yarn +RUN npm install -g yarn --force RUN mv /usr/local/bin/npm /usr/local/bin/npm-unsafe ADD --chown=skpr:skpr bin/npm-wrapper /usr/local/bin/npm RUN chmod +x /usr/local/bin/npm From b8825807828c3ea936d853ec996fd24f361c334f Mon Sep 17 00:00:00 2001 From: Kim Pepper Date: Tue, 30 Jun 2026 15:11:01 +1000 Subject: [PATCH 05/12] Bump action versions. Remove node 20 --- .github/workflows/build-pr.yml | 10 ++++------ .github/workflows/build-push.yml | 14 ++++++-------- .github/workflows/security-scan.yml | 2 +- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index ab4042e..52981cd 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -13,11 +13,9 @@ jobs: strategy: fail-fast: false matrix: - node: [ '20', '22', '24', '26' ] + node: [ '22', '24', '26' ] alpine: [ '3.21', '3.24'] exclude: - - node: '20' - alpine: '3.24' - node: '22' alpine: '3.24' - node: '24' @@ -27,13 +25,13 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: 🐋 Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 - name: 🏗️ Build Docker image - uses: docker/bake-action@v6 + uses: docker/bake-action@v7 env: NODE_VERSION: ${{ matrix.node }} ALPINE_VERSION: ${{ matrix.alpine }} diff --git a/.github/workflows/build-push.yml b/.github/workflows/build-push.yml index 7b05821..758b426 100644 --- a/.github/workflows/build-push.yml +++ b/.github/workflows/build-push.yml @@ -38,11 +38,9 @@ jobs: strategy: fail-fast: false matrix: - node: [ '20', '22', '24', '26' ] + node: [ '22', '24', '26' ] alpine: [ '3.21', '3.24'] exclude: - - node: '20' - alpine: '3.24' - node: '22' alpine: '3.24' - node: '24' @@ -52,28 +50,28 @@ jobs: steps: - name: 📥 Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@v7 with: ref: ${{ inputs.branch }} - name: 🔑 Login to Docker Hub - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: 🔑 Log in to the GitHub Container Registry - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: 🐋 Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 - name: 🏗️ Build and push Docker image - uses: docker/bake-action@v6 + uses: docker/bake-action@v7 env: NODE_VERSION: ${{ matrix.node }} ALPINE_VERSION: ${{ matrix.alpine }} diff --git a/.github/workflows/security-scan.yml b/.github/workflows/security-scan.yml index 054166b..ab1ed8a 100644 --- a/.github/workflows/security-scan.yml +++ b/.github/workflows/security-scan.yml @@ -29,7 +29,7 @@ jobs: steps: - name: 🔑 Log in to the GitHub Container Registry - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: registry: ghcr.io username: ${{ github.actor }} From 9a5c69716ea7c80df6a55206baf38d1a94548b9c Mon Sep 17 00:00:00 2001 From: Kim Pepper Date: Tue, 30 Jun 2026 15:13:45 +1000 Subject: [PATCH 06/12] Switch to include matrix --- .github/workflows/build-pr.yml | 10 ++++------ .github/workflows/build-push.yml | 10 ++++------ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index 52981cd..713cd75 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -13,15 +13,13 @@ jobs: strategy: fail-fast: false matrix: - node: [ '22', '24', '26' ] - alpine: [ '3.21', '3.24'] - exclude: + include: - node: '22' - alpine: '3.24' + alpine: '3.21' - node: '24' - alpine: '3.24' - - node: '26' alpine: '3.21' + - node: '26' + alpine: '3.24' steps: - name: Checkout repository diff --git a/.github/workflows/build-push.yml b/.github/workflows/build-push.yml index 758b426..176501a 100644 --- a/.github/workflows/build-push.yml +++ b/.github/workflows/build-push.yml @@ -38,15 +38,13 @@ jobs: strategy: fail-fast: false matrix: - node: [ '22', '24', '26' ] - alpine: [ '3.21', '3.24'] - exclude: + include: - node: '22' - alpine: '3.24' + alpine: '3.21' - node: '24' - alpine: '3.24' - - node: '26' alpine: '3.21' + - node: '26' + alpine: '3.24' steps: - name: 📥 Checkout repository From 7bd9d31ed5f740792afbc593c711353c20020079 Mon Sep 17 00:00:00 2001 From: Kim Pepper Date: Tue, 30 Jun 2026 15:17:20 +1000 Subject: [PATCH 07/12] Use alpine 3.24 for node 24 --- .github/workflows/build-pr.yml | 2 +- .github/workflows/build-push.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index 713cd75..fde8d35 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -17,7 +17,7 @@ jobs: - node: '22' alpine: '3.21' - node: '24' - alpine: '3.21' + alpine: '3.24' - node: '26' alpine: '3.24' diff --git a/.github/workflows/build-push.yml b/.github/workflows/build-push.yml index 176501a..c953e80 100644 --- a/.github/workflows/build-push.yml +++ b/.github/workflows/build-push.yml @@ -42,7 +42,7 @@ jobs: - node: '22' alpine: '3.21' - node: '24' - alpine: '3.21' + alpine: '3.24' - node: '26' alpine: '3.24' From 1983812996b1d7fe9caa102b4b3bd0849c65b9e2 Mon Sep 17 00:00:00 2001 From: Kim Pepper Date: Tue, 30 Jun 2026 15:20:13 +1000 Subject: [PATCH 08/12] ci: review fixes - yarn install ordering, drop node 20 from scan, fix typo --- .github/workflows/build-pr.yml | 2 +- .github/workflows/security-scan.yml | 2 -- Dockerfile | 4 +++- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index fde8d35..e9a1d30 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -28,7 +28,7 @@ jobs: - name: 🐋 Set up Docker Buildx uses: docker/setup-buildx-action@v4 - - name: 🏗️ Build Docker image + - name: 🏗️ Build Docker image uses: docker/bake-action@v7 env: NODE_VERSION: ${{ matrix.node }} diff --git a/.github/workflows/security-scan.yml b/.github/workflows/security-scan.yml index ab1ed8a..e2ca02e 100644 --- a/.github/workflows/security-scan.yml +++ b/.github/workflows/security-scan.yml @@ -24,8 +24,6 @@ jobs: - ghcr.io/skpr/node:dev-24-v3-latest - ghcr.io/skpr/node:22-v3-latest - ghcr.io/skpr/node:dev-22-v3-latest - - ghcr.io/skpr/node:20-v3-latest - - ghcr.io/skpr/node:dev-20-v3-latest steps: - name: 🔑 Log in to the GitHub Container Registry diff --git a/Dockerfile b/Dockerfile index 3694287..2f4b87a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -41,8 +41,10 @@ RUN mkdir /data && chown skpr:skpr /data WORKDIR /data +# Ensure yarn is available before wrapping (Node 26+ no longer ships yarn). +RUN npm install -g yarn + # Replace npm with a wrapper script to enforce security. -RUN npm install -g yarn --force RUN mv /usr/local/bin/npm /usr/local/bin/npm-unsafe ADD --chown=skpr:skpr bin/npm-wrapper /usr/local/bin/npm RUN chmod +x /usr/local/bin/npm From 7e36f5da45ef21679cf2339b50e59fd583370852 Mon Sep 17 00:00:00 2001 From: Kim Pepper Date: Tue, 30 Jun 2026 15:23:19 +1000 Subject: [PATCH 09/12] re-add force --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 2f4b87a..a2dee9b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -42,7 +42,7 @@ RUN mkdir /data && chown skpr:skpr /data WORKDIR /data # Ensure yarn is available before wrapping (Node 26+ no longer ships yarn). -RUN npm install -g yarn +RUN npm install -g yarn --force # Replace npm with a wrapper script to enforce security. RUN mv /usr/local/bin/npm /usr/local/bin/npm-unsafe From ebb2030fbea160ac5d631cd58c2e1d8f1ffe0069 Mon Sep 17 00:00:00 2001 From: Kim Pepper Date: Tue, 30 Jun 2026 16:08:00 +1000 Subject: [PATCH 10/12] ci: simplify matrix - all versions use alpine 3.24 --- .github/workflows/build-pr.yml | 10 ++-------- .github/workflows/build-push.yml | 10 ++-------- docker-bake.hcl | 2 +- 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index e9a1d30..8568092 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -13,13 +13,7 @@ jobs: strategy: fail-fast: false matrix: - include: - - node: '22' - alpine: '3.21' - - node: '24' - alpine: '3.24' - - node: '26' - alpine: '3.24' + node: [ '22', '24', '26' ] steps: - name: Checkout repository @@ -32,7 +26,7 @@ jobs: uses: docker/bake-action@v7 env: NODE_VERSION: ${{ matrix.node }} - ALPINE_VERSION: ${{ matrix.alpine }} + ALPINE_VERSION: '3.24' STREAM: ${{ env.stream }} with: source: . diff --git a/.github/workflows/build-push.yml b/.github/workflows/build-push.yml index c953e80..c84fc48 100644 --- a/.github/workflows/build-push.yml +++ b/.github/workflows/build-push.yml @@ -38,13 +38,7 @@ jobs: strategy: fail-fast: false matrix: - include: - - node: '22' - alpine: '3.21' - - node: '24' - alpine: '3.24' - - node: '26' - alpine: '3.24' + node: [ '22', '24', '26' ] steps: - name: 📥 Checkout repository @@ -72,7 +66,7 @@ jobs: uses: docker/bake-action@v7 env: NODE_VERSION: ${{ matrix.node }} - ALPINE_VERSION: ${{ matrix.alpine }} + ALPINE_VERSION: '3.24' STREAM: ${{ inputs.stream }} with: source: . diff --git a/docker-bake.hcl b/docker-bake.hcl index 7975dd2..051562e 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -3,7 +3,7 @@ variable "NODE_VERSION" { } variable "ALPINE_VERSION" { - default = "3.21" + default = "3.24" } variable "STREAM" { From 8efe3ef3ba814744ea910982fa150b84094b4852 Mon Sep 17 00:00:00 2001 From: Kim Pepper Date: Tue, 30 Jun 2026 16:09:00 +1000 Subject: [PATCH 11/12] ci: remove redundant ALPINE_VERSION env var, bake default handles it --- .github/workflows/build-pr.yml | 1 - .github/workflows/build-push.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index 8568092..e0b4882 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -26,7 +26,6 @@ jobs: uses: docker/bake-action@v7 env: NODE_VERSION: ${{ matrix.node }} - ALPINE_VERSION: '3.24' STREAM: ${{ env.stream }} with: source: . diff --git a/.github/workflows/build-push.yml b/.github/workflows/build-push.yml index c84fc48..3576aad 100644 --- a/.github/workflows/build-push.yml +++ b/.github/workflows/build-push.yml @@ -66,7 +66,6 @@ jobs: uses: docker/bake-action@v7 env: NODE_VERSION: ${{ matrix.node }} - ALPINE_VERSION: '3.24' STREAM: ${{ inputs.stream }} with: source: . From 07b26697695a5dd9aa58a5fede8cead1950d062a Mon Sep 17 00:00:00 2001 From: Kim Pepper Date: Tue, 30 Jun 2026 16:19:44 +1000 Subject: [PATCH 12/12] ci: stable builds use alpine 3.21 with node 22/24 only --- .github/workflows/build-push-stable.yml | 2 ++ .github/workflows/build-push.yml | 11 ++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-push-stable.yml b/.github/workflows/build-push-stable.yml index b4bcdfa..0ad56fd 100644 --- a/.github/workflows/build-push-stable.yml +++ b/.github/workflows/build-push-stable.yml @@ -15,4 +15,6 @@ jobs: stream: stable push: true branch: releases + node_versions: '["22","24"]' + alpine_version: '3.21' secrets: inherit diff --git a/.github/workflows/build-push.yml b/.github/workflows/build-push.yml index 3576aad..5845819 100644 --- a/.github/workflows/build-push.yml +++ b/.github/workflows/build-push.yml @@ -19,6 +19,14 @@ on: type: string default: main description: Branch name to build from. + node_versions: + type: string + default: '["22","24","26"]' + description: JSON array of Node.js versions to build. + alpine_version: + type: string + default: '3.24' + description: Alpine Linux version to build against. secrets: DOCKERHUB_USERNAME: @@ -38,7 +46,7 @@ jobs: strategy: fail-fast: false matrix: - node: [ '22', '24', '26' ] + node: ${{ fromJson(inputs.node_versions) }} steps: - name: 📥 Checkout repository @@ -66,6 +74,7 @@ jobs: uses: docker/bake-action@v7 env: NODE_VERSION: ${{ matrix.node }} + ALPINE_VERSION: ${{ inputs.alpine_version }} STREAM: ${{ inputs.stream }} with: source: .