From d6f8d77d15965732c747bc5c1ede0523b63de0f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20Felix=20=C5=A0ulc?= Date: Sun, 27 Sep 2026 16:23:08 +0000 Subject: [PATCH 1/6] Docker: move PHP 8.3-8.5 and Node 24 to Alpine 3.24, add Node 26 PHP 8.5 leaves Alpine edge for the stable 3.24 branch. Node 24 uses the LTS nodejs package from Alpine 3.24 main. Node 26 is new and uses nodejs-current from Alpine 3.24. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01VSKw7jY45nUJWQxWpvjm82 --- .claude/commands/versions.md | 2 +- .github/workflows/docker.yml | 1 + .scripts/versions.sh | 2 +- Makefile | 1 + README.md | 12 +++++++----- node22/Dockerfile | 2 +- node24/Dockerfile | 8 ++++---- node26/Dockerfile | 14 ++++++++++++++ php83/Dockerfile | 4 ++-- php84/Dockerfile | 4 ++-- php85/Dockerfile | 4 ++-- 11 files changed, 36 insertions(+), 18 deletions(-) create mode 100644 node26/Dockerfile diff --git a/.claude/commands/versions.md b/.claude/commands/versions.md index 4584615..702027d 100644 --- a/.claude/commands/versions.md +++ b/.claude/commands/versions.md @@ -13,4 +13,4 @@ Steps: 6. For versions without data (N/A), keep them with dash placeholders (e.g., `NodeJS 14 | Alpine v3.12 | node14 | - | - | -`) 7. Show a summary of what was updated -Important: Only update versions 15-24 in the table, leave versions 10-14 as they are with dashes. +Important: Only update versions 15-26 in the table, leave versions 10-14 as they are with dashes. diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 02d49de..3273609 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -58,6 +58,7 @@ jobs: - item: node22 - item: node23 - item: node24 + - item: node26 # PHP - item: php56 - item: php70 diff --git a/.scripts/versions.sh b/.scripts/versions.sh index c4932a4..2701708 100755 --- a/.scripts/versions.sh +++ b/.scripts/versions.sh @@ -27,7 +27,7 @@ while [[ $# -gt 0 ]]; do done # Array of node versions to check -NODE_VERSIONS=(15 16 17 18 19 20 21 22 23 24) +NODE_VERSIONS=(15 16 17 18 19 20 21 22 23 24 26) # Detect platform PLATFORM=$(uname -m) diff --git a/Makefile b/Makefile index 700e94c..5f2c34d 100644 --- a/Makefile +++ b/Makefile @@ -56,5 +56,6 @@ build-node21: _docker-build-node21 build-node22: _docker-build-node22 build-node23: _docker-build-node23 build-node24: _docker-build-node24 +build-node26: _docker-build-node26 build-ansitest: _docker-build-ansitest diff --git a/README.md b/README.md index a26536d..03b01d8 100644 --- a/README.md +++ b/README.md @@ -25,9 +25,9 @@ | PHP | OS | Tag | Dockerfile | |----------|--------------|--------|----------------------------------------------------------------------------| -| PHP 8.5 | Alpine edge | php85 | [Dockerfile](https://github.com/dockette/ci/blob/master/php85/Dockerfile) | -| PHP 8.4 | Alpine v3.22 | php84 | [Dockerfile](https://github.com/dockette/ci/blob/master/php84/Dockerfile) | -| PHP 8.3 | Alpine v3.22 | php83 | [Dockerfile](https://github.com/dockette/ci/blob/master/php83/Dockerfile) | +| PHP 8.5 | Alpine v3.24 | php85 | [Dockerfile](https://github.com/dockette/ci/blob/master/php85/Dockerfile) | +| PHP 8.4 | Alpine v3.24 | php84 | [Dockerfile](https://github.com/dockette/ci/blob/master/php84/Dockerfile) | +| PHP 8.3 | Alpine v3.24 | php83 | [Dockerfile](https://github.com/dockette/ci/blob/master/php83/Dockerfile) | | PHP 8.2 | Alpine v3.22 | php82 | [Dockerfile](https://github.com/dockette/ci/blob/master/php82/Dockerfile) | | PHP 8.1 | Alpine v3.19 | php81 | [Dockerfile](https://github.com/dockette/ci/blob/master/php81/Dockerfile) | | PHP 8.0 | Alpine v3.15 | php80 | [Dockerfile](https://github.com/dockette/ci/blob/master/php80/Dockerfile) | @@ -70,9 +70,10 @@ docker run -it --rm -v $(pwd):/srv dockette/ci:php56 | NodeJS | OS | Tag | Node Version | npm Version | pnpm Version | Dockerfile | |----------------------|--------------|--------|--------------|-------------|--------------|----------------------------------------------------------------------------| -| NodeJS 24 (v24.15.0) | Alpine v3.23 | node24 | v24.15.0 | 11.11.0 | 10.33.4 | [Dockerfile](https://github.com/dockette/ci/blob/master/node24/Dockerfile) | +| NodeJS 26 (v26.5.1) | Alpine v3.24 | node26 | v26.5.1 | 11.12.1 | 11.20.0 | [Dockerfile](https://github.com/dockette/ci/blob/master/node26/Dockerfile) | +| NodeJS 24 (v24.18.1) | Alpine v3.24 | node24 | v24.18.1 | 11.12.1 | 11.20.0 | [Dockerfile](https://github.com/dockette/ci/blob/master/node24/Dockerfile) | | NodeJS 23 (v23.11.1) | Alpine v3.22 | node23 | v23.11.1 | 11.4.2 | 10.9.0 | [Dockerfile](https://github.com/dockette/ci/blob/master/node23/Dockerfile) | -| NodeJS 22 (v22.15.1) | Alpine v3.21 | node22 | v22.15.1 | 10.9.1 | 9.15.9 | [Dockerfile](https://github.com/dockette/ci/blob/master/node22/Dockerfile) | +| NodeJS 22 (v22.23.2) | Alpine v3.21 | node22 | v22.23.2 | 10.9.1 | 9.15.9 | [Dockerfile](https://github.com/dockette/ci/blob/master/node22/Dockerfile) | | NodeJS 21 (v21.7.3) | Alpine v3.20 | node21 | v21.7.3 | 10.9.1 | 10.22.0 | [Dockerfile](https://github.com/dockette/ci/blob/master/node21/Dockerfile) | | NodeJS 20 (v20.8.1) | Alpine v3.18 | node20 | v20.8.1 | 9.6.6 | 10.22.0 | [Dockerfile](https://github.com/dockette/ci/blob/master/node20/Dockerfile) | | NodeJS 19 (v19.7.0) | Alpine v3.17 | node19 | v19.7.0 | 9.1.2 | 10.22.0 | [Dockerfile](https://github.com/dockette/ci/blob/master/node19/Dockerfile) | @@ -106,6 +107,7 @@ All Nodejs images have a few preinstalled packages: **Terminal** ``` +docker run -it --rm -v $(pwd):/srv dockette/ci:node26 docker run -it --rm -v $(pwd):/srv dockette/ci:node24 docker run -it --rm -v $(pwd):/srv dockette/ci:node23 docker run -it --rm -v $(pwd):/srv dockette/ci:node22 diff --git a/node22/Dockerfile b/node22/Dockerfile index 49e2c03..feae7bc 100644 --- a/node22/Dockerfile +++ b/node22/Dockerfile @@ -1,6 +1,6 @@ FROM dockette/alpine:3.21 -ENV NODEJS_VERSION=22.15.1 +ENV NODEJS_VERSION=22.23.2 RUN echo '@community http://dl-cdn.alpinelinux.org/alpine/v3.21/community' >> /etc/apk/repositories && \ apk update && apk upgrade && \ diff --git a/node24/Dockerfile b/node24/Dockerfile index aa4f4d8..3ff7916 100644 --- a/node24/Dockerfile +++ b/node24/Dockerfile @@ -1,13 +1,13 @@ -FROM dockette/alpine:3.23 +FROM dockette/alpine:3.24 -ENV NODEJS_VERSION=24.15.0 +ENV NODEJS_VERSION=24.18.1 -RUN echo '@community http://dl-cdn.alpinelinux.org/alpine/v3.23/community' >> /etc/apk/repositories && \ +RUN echo '@community http://dl-cdn.alpinelinux.org/alpine/v3.24/community' >> /etc/apk/repositories && \ apk update && apk upgrade && \ # DEPENDENCIES ############################################################# apk add --update bash git ca-certificates curl openssh tzdata make direnv && \ # NODEJS ################################################################### - apk add --update nodejs-current@community npm@community pnpm@community && \ + apk add --update nodejs npm@community pnpm@community && \ # CLEAN UP ################################################################# rm -rf /var/cache/apk/* diff --git a/node26/Dockerfile b/node26/Dockerfile new file mode 100644 index 0000000..8ff9e15 --- /dev/null +++ b/node26/Dockerfile @@ -0,0 +1,14 @@ +FROM dockette/alpine:3.24 + +ENV NODEJS_VERSION=26.5.1 + +RUN echo '@community http://dl-cdn.alpinelinux.org/alpine/v3.24/community' >> /etc/apk/repositories && \ + apk update && apk upgrade && \ + # DEPENDENCIES ############################################################# + apk add --update bash git ca-certificates curl openssh tzdata make direnv && \ + # NODEJS ################################################################### + apk add --update nodejs-current@community npm@community pnpm@community && \ + # CLEAN UP ################################################################# + rm -rf /var/cache/apk/* + +CMD ["node"] diff --git a/php83/Dockerfile b/php83/Dockerfile index bd9d522..4e375df 100644 --- a/php83/Dockerfile +++ b/php83/Dockerfile @@ -1,4 +1,4 @@ -FROM dockette/alpine:3.22 +FROM dockette/alpine:3.24 LABEL maintainer="Milan Sulc " @@ -13,7 +13,7 @@ ENV COMPOSER_BIN=$COMPOSER_DIR/composer ENV TZ=Europe/Prague ENV LD_PRELOAD="/usr/lib/preloadable_libiconv.so php" -RUN echo '@community http://dl-cdn.alpinelinux.org/alpine/v3.22/community/' >> /etc/apk/repositories && \ +RUN echo '@community http://dl-cdn.alpinelinux.org/alpine/v3.24/community/' >> /etc/apk/repositories && \ # DEPENDENCIES ############################################################# apk update && \ apk upgrade && \ diff --git a/php84/Dockerfile b/php84/Dockerfile index 080e37f..6396fe4 100644 --- a/php84/Dockerfile +++ b/php84/Dockerfile @@ -1,4 +1,4 @@ -FROM dockette/alpine:3.22 +FROM dockette/alpine:3.24 LABEL maintainer="Milan Sulc " @@ -13,7 +13,7 @@ ENV COMPOSER_BIN=$COMPOSER_DIR/composer ENV TZ=Europe/Prague ENV LD_PRELOAD="/usr/lib/preloadable_libiconv.so php" -RUN echo '@community http://dl-cdn.alpinelinux.org/alpine/v3.22/community/' >> /etc/apk/repositories && \ +RUN echo '@community http://dl-cdn.alpinelinux.org/alpine/v3.24/community/' >> /etc/apk/repositories && \ # DEPENDENCIES ############################################################# apk update && \ apk upgrade && \ diff --git a/php85/Dockerfile b/php85/Dockerfile index ef7ae68..d6d8532 100644 --- a/php85/Dockerfile +++ b/php85/Dockerfile @@ -1,4 +1,4 @@ -FROM dockette/alpine:edge +FROM dockette/alpine:3.24 LABEL maintainer="Milan Sulc " @@ -13,7 +13,7 @@ ENV COMPOSER_BIN=$COMPOSER_DIR/composer ENV TZ=Europe/Prague ENV LD_PRELOAD="/usr/lib/preloadable_libiconv.so php" -RUN echo '@community http://dl-cdn.alpinelinux.org/alpine/edge/community/' >> /etc/apk/repositories && \ +RUN echo '@community http://dl-cdn.alpinelinux.org/alpine/v3.24/community/' >> /etc/apk/repositories && \ # DEPENDENCIES ############################################################# apk update && \ apk upgrade && \ From bdc67ce62865471a0013d84584301963c301c7c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20Felix=20=C5=A0ulc?= Date: Tue, 29 Sep 2026 16:55:56 +0000 Subject: [PATCH 2/6] Docker: move ansitest to Debian 12 bookworm Debian 11 bullseye is EOL. Its security packages are gone from deb.debian.org, so apt install fails with 404. Bookworm still ships vagrant. Docker repo uses a signed-by keyring, Ansible comes from Debian instead of the old trusty PPA, and pip3 uses --break-system-packages (PEP 668). Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01VSKw7jY45nUJWQxWpvjm82 --- README.md | 2 +- ansitest/Dockerfile | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 03b01d8..7d11349 100644 --- a/README.md +++ b/README.md @@ -133,7 +133,7 @@ docker run -it --rm -v $(pwd):/srv dockette/ci:node6 | Tools | OS | Tag | Dockerfile | |--------------------------------|--------------|---------------|----------------------------------------------------------------------------| -| Ansible, Vagrant, Docker | Debian 11 | ansitest | [Dockerfile](https://github.com/dockette/ci/blob/master/ansitest/Dockerfile) | +| Ansible, Vagrant, Docker | Debian 12 | ansitest | [Dockerfile](https://github.com/dockette/ci/blob/master/ansitest/Dockerfile) | ----- diff --git a/ansitest/Dockerfile b/ansitest/Dockerfile index b069ecb..8943bfc 100644 --- a/ansitest/Dockerfile +++ b/ansitest/Dockerfile @@ -1,4 +1,4 @@ -FROM debian:bullseye-slim +FROM debian:bookworm-slim ARG TARGETARCH @@ -20,16 +20,14 @@ RUN apt update && \ vagrant \ wget && \ # DOCKER ################################################################### - curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - && \ - add-apt-repository "deb [arch=${TARGETARCH}] https://download.docker.com/linux/debian bullseye stable" && \ + install -m 0755 -d /etc/apt/keyrings && \ + curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc && \ + echo "deb [arch=${TARGETARCH} signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian bookworm stable" > /etc/apt/sources.list.d/docker.list && \ apt update && \ apt install --no-install-recommends -y docker-ce docker-ce-cli containerd.io && \ # ANSIBLE ################################################################## - echo "deb http://ppa.launchpad.net/ansible/ansible/ubuntu trusty main" >> /etc/apt/sources.list.d/ansible.list && \ - apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 93C4A3FD7BB9C367 && \ - apt update && \ apt install -y ansible && \ - pip3 install ansible-lint yamllint molecule molecule-plugins[docker] && \ + pip3 install --break-system-packages ansible-lint yamllint molecule molecule-plugins[docker] && \ ansible-galaxy collection install --collections-path /usr/lib/python3/dist-packages/ansible_collections -U \ ansible.utils \ ansible.posix \ From 2f42eee55632884251ed29b962b7a64863d3bcee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20Felix=20=C5=A0ulc?= Date: Tue, 29 Sep 2026 17:02:46 +0000 Subject: [PATCH 3/6] Docker: force php symlink on Alpine 3.24 On Alpine 3.24 php85 is the default PHP and ships /usr/bin/php, so "ln -s" fails in php85. php83 had no symlink and composer failed with "php: not found". Use "ln -sf" in php83, php84 and php85. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01VSKw7jY45nUJWQxWpvjm82 --- php83/Dockerfile | 1 + php84/Dockerfile | 2 +- php85/Dockerfile | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/php83/Dockerfile b/php83/Dockerfile index 4e375df..2521a3b 100644 --- a/php83/Dockerfile +++ b/php83/Dockerfile @@ -82,6 +82,7 @@ RUN echo '@community http://dl-cdn.alpinelinux.org/alpine/v3.24/community/' >> / sed -i -- 's/zend/;zend/g' /etc/php83/conf.d/50_xdebug.ini && \ echo "php -dzend_extension=xdebug.so \$@" >> $PHPXD_BIN && \ chmod +x $PHPXD_BIN && \ + ln -sf $PHP8_BIN $PHP_BIN && \ # COMPOSER ################################################################# curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer --2 && \ # CLEAN UP ################################################################# diff --git a/php84/Dockerfile b/php84/Dockerfile index 6396fe4..ae6d602 100644 --- a/php84/Dockerfile +++ b/php84/Dockerfile @@ -82,7 +82,7 @@ RUN echo '@community http://dl-cdn.alpinelinux.org/alpine/v3.24/community/' >> / sed -i -- 's/zend/;zend/g' /etc/php84/conf.d/50_xdebug.ini && \ echo "php -dzend_extension=xdebug.so \$@" >> $PHPXD_BIN && \ chmod +x $PHPXD_BIN && \ - ln -s $PHP8_BIN $PHP_BIN && \ + ln -sf $PHP8_BIN $PHP_BIN && \ # COMPOSER ################################################################# curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer --2 && \ # CLEAN UP ################################################################# diff --git a/php85/Dockerfile b/php85/Dockerfile index d6d8532..9cf8cea 100644 --- a/php85/Dockerfile +++ b/php85/Dockerfile @@ -82,7 +82,7 @@ RUN echo '@community http://dl-cdn.alpinelinux.org/alpine/v3.24/community/' >> / sed -i -- 's/zend/;zend/g' /etc/php85/conf.d/50_xdebug.ini && \ echo "php -dzend_extension=xdebug.so \$@" >> $PHPXD_BIN && \ chmod +x $PHPXD_BIN && \ - ln -s $PHP8_BIN $PHP_BIN && \ + ln -sf $PHP8_BIN $PHP_BIN && \ # COMPOSER ################################################################# curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer --2 && \ # CLEAN UP ################################################################# From 825bb8264741275534cc6a00e5beb66639bf5ac8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20Felix=20=C5=A0ulc?= Date: Tue, 29 Sep 2026 20:23:00 +0000 Subject: [PATCH 4/6] CI: smoke test every image before the push .scripts/test.sh checks one image: - PHP: version, clean startup (no extension warnings), main extensions, phpxd with Xdebug, composer. - Node.js: major version, npm, pnpm (node18+). - ansitest: ansible, ansible-lint, yamllint, molecule, docker and the community.docker collection. - All: bash, git, curl, make. The build matrix runs the script through the new "test" input of the shared Docker workflow, so every image and not only three is tested. The Makefile "test" target uses the same script. The tests found defects in the published images, fixed here: - node8 had Node 9 and no npm. Use nodejs-npm (Node 8) from Alpine 3.8. - node12 had Node 14. On Alpine 3.12 "nodejs" is Node 12. - node18 to node21: "pnpm@latest" (pnpm 11) crashes on these Node versions. Pin pnpm 8.15.9 for node18 (Node 18.9) and pnpm 10.34.6 for node19 to node21. The shared workflow ref points to the dockette/.github branch with the "test" input. Change it back to @master when that PR is merged. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01VSKw7jY45nUJWQxWpvjm82 --- .github/workflows/docker.yml | 17 +------ .scripts/test.sh | 92 ++++++++++++++++++++++++++++++++++++ AGENTS.md | 14 ++++++ Makefile | 8 ++-- README.md | 8 ++-- node12/Dockerfile | 2 +- node18/Dockerfile | 2 +- node19/Dockerfile | 2 +- node20/Dockerfile | 2 +- node21/Dockerfile | 2 +- node8/Dockerfile | 2 +- 11 files changed, 121 insertions(+), 30 deletions(-) create mode 100755 .scripts/test.sh diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 3273609..00efe19 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -12,29 +12,16 @@ permissions: contents: read jobs: - test: - name: "Test" - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v6 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v4 - - - name: Test representative images - run: make test - build: name: "Build" - needs: test - uses: dockette/.github/.github/workflows/docker.yml@master + uses: dockette/.github/.github/workflows/docker.yml@claude/exciting-feynman-p0jaf4 secrets: inherit with: image: "dockette/ci" tag: "${{ matrix.item }}" context: "${{ matrix.item }}" push: ${{ github.ref == 'refs/heads/master' }} + test: .scripts/test.sh ${{ matrix.item }} "$IMAGE" strategy: matrix: include: diff --git a/.scripts/test.sh b/.scripts/test.sh new file mode 100755 index 0000000..e08cef0 --- /dev/null +++ b/.scripts/test.sh @@ -0,0 +1,92 @@ +#!/usr/bin/env bash +# +# Smoke test for one dockette/ci image. +# +# Usage: .scripts/test.sh [image] +# item directory name, for example php84, node24 or ansitest +# image image to test (default: dockette/ci:) +# +set -uo pipefail + +ITEM="${1:?Usage: $0 [image]}" +IMAGE="${2:-dockette/ci:${ITEM}}" +FAILED=0 + +# Run a shell command in the image and print its output. +run() { + docker run --rm "${IMAGE}" sh -c "$1" 2>&1 +} + +# check : the command must exit with 0. +check() { + local out + if out="$(run "$2")"; then + echo "ok $1: $(echo "${out}" | head -n 1)" + else + echo "FAIL $1" + echo "${out}" | sed 's/^/ /' + FAILED=1 + fi +} + +# expect : the command output must be equal to the value. +expect() { + local out + out="$(run "$2")" + if [ "${out}" = "$3" ]; then + echo "ok $1: ${out}" + else + echo "FAIL $1: expected '$3', got:" + echo "${out}" | sed 's/^/ /' + FAILED=1 + fi +} + +test_common() { + check "tools" "for t in bash git curl make; do command -v \$t >/dev/null || { echo \"missing \$t\"; exit 1; }; done" +} + +test_php() { + local version="${ITEM#php}" + + expect "php version" "php -r 'echo PHP_MAJOR_VERSION . PHP_MINOR_VERSION;'" "${version}" + # A broken extension prints a startup warning, but php still exits with 0. + check "php startup" "out=\$(php -v 2>&1) && echo \"\$out\" | head -n 1 && ! echo \"\$out\" | grep -iE 'warning|error|unable to load|failed loading'" + check "php extensions" "m=\$(php -m) && for e in ctype curl gd iconv intl openssl pdo_mysql pdo_pgsql pdo_sqlite zip; do echo \"\$m\" | grep -qix \$e || { echo \"missing \$e\"; exit 1; }; done && echo all" + check "phpxd" "phpxd -v | grep -i xdebug" + check "composer" "composer --version" + test_common +} + +test_node() { + local version="${ITEM#node}" + + check "node" "node --version" + expect "node major version" "node -p 'process.versions.node.split(\".\")[0]'" "${version}" + check "npm" "npm --version" + if [ "${version}" -ge 18 ]; then + check "pnpm" "pnpm --version" + fi + test_common +} + +test_ansitest() { + check "ansible" "ansible --version" + check "ansible-lint" "ansible-lint --version" + check "yamllint" "yamllint --version" + check "molecule" "molecule --version" + check "docker" "docker --version" + check "collections" "ansible-galaxy collection list community.docker" + test_common +} + +echo "Testing ${IMAGE}" + +case "${ITEM}" in + php*) test_php ;; + node*) test_node ;; + ansitest) test_ansitest ;; + *) echo "No tests for ${ITEM}"; exit 1 ;; +esac + +exit "${FAILED}" diff --git a/AGENTS.md b/AGENTS.md index c5eb634..c623162 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -59,6 +59,20 @@ For quick local testing, you can use `--load` with your native platform: docker buildx build --load -t dockette/ci:node24 ./node24 ``` +## Testing + +`.scripts/test.sh` runs smoke tests for one image. It checks the PHP or Node.js +version, the main tools (composer, phpxd, npm, pnpm, ansible and more) and that +PHP starts without warnings. + +```bash +docker buildx build --load -t dockette/ci:node24 ./node24 +.scripts/test.sh node24 +``` + +CI runs the same script for every image before the push, through the `test` +input of the shared `dockette/.github` Docker workflow. + ## Platform Detection To check your current platform: diff --git a/Makefile b/Makefile index 5f2c34d..9e02790 100644 --- a/Makefile +++ b/Makefile @@ -18,11 +18,9 @@ _docker-build-%: build: build-php-8.4 build-node24 build-ansitest test: build - docker run --rm ${DOCKER_IMAGE}:${PHP_TEST_TAG} php -v - docker run --rm ${DOCKER_IMAGE}:${PHP_TEST_TAG} composer --version - docker run --rm ${DOCKER_IMAGE}:${NODE_TEST_TAG} node --version - docker run --rm ${DOCKER_IMAGE}:${NODE_TEST_TAG} npm --version - docker run --rm ${DOCKER_IMAGE}:${ANSIBLE_TEST_TAG} ansible --version + .scripts/test.sh ${PHP_TEST_TAG} ${DOCKER_IMAGE}:${PHP_TEST_TAG} + .scripts/test.sh ${NODE_TEST_TAG} ${DOCKER_IMAGE}:${NODE_TEST_TAG} + .scripts/test.sh ${ANSIBLE_TEST_TAG} ${DOCKER_IMAGE}:${ANSIBLE_TEST_TAG} run: docker run -it --rm -v $$(pwd):/srv ${DOCKER_IMAGE}:${PHP_TEST_TAG} diff --git a/README.md b/README.md index 7d11349..dbbb7c1 100644 --- a/README.md +++ b/README.md @@ -74,10 +74,10 @@ docker run -it --rm -v $(pwd):/srv dockette/ci:php56 | NodeJS 24 (v24.18.1) | Alpine v3.24 | node24 | v24.18.1 | 11.12.1 | 11.20.0 | [Dockerfile](https://github.com/dockette/ci/blob/master/node24/Dockerfile) | | NodeJS 23 (v23.11.1) | Alpine v3.22 | node23 | v23.11.1 | 11.4.2 | 10.9.0 | [Dockerfile](https://github.com/dockette/ci/blob/master/node23/Dockerfile) | | NodeJS 22 (v22.23.2) | Alpine v3.21 | node22 | v22.23.2 | 10.9.1 | 9.15.9 | [Dockerfile](https://github.com/dockette/ci/blob/master/node22/Dockerfile) | -| NodeJS 21 (v21.7.3) | Alpine v3.20 | node21 | v21.7.3 | 10.9.1 | 10.22.0 | [Dockerfile](https://github.com/dockette/ci/blob/master/node21/Dockerfile) | -| NodeJS 20 (v20.8.1) | Alpine v3.18 | node20 | v20.8.1 | 9.6.6 | 10.22.0 | [Dockerfile](https://github.com/dockette/ci/blob/master/node20/Dockerfile) | -| NodeJS 19 (v19.7.0) | Alpine v3.17 | node19 | v19.7.0 | 9.1.2 | 10.22.0 | [Dockerfile](https://github.com/dockette/ci/blob/master/node19/Dockerfile) | -| NodeJS 18 (v18.9.1) | Alpine v3.16 | node18 | v18.9.1 | 8.10.0 | N/A | [Dockerfile](https://github.com/dockette/ci/blob/master/node18/Dockerfile) | +| NodeJS 21 (v21.7.3) | Alpine v3.20 | node21 | v21.7.3 | 10.9.1 | 10.34.6 | [Dockerfile](https://github.com/dockette/ci/blob/master/node21/Dockerfile) | +| NodeJS 20 (v20.8.1) | Alpine v3.18 | node20 | v20.8.1 | 9.6.6 | 10.34.6 | [Dockerfile](https://github.com/dockette/ci/blob/master/node20/Dockerfile) | +| NodeJS 19 (v19.7.0) | Alpine v3.17 | node19 | v19.7.0 | 9.1.2 | 10.34.6 | [Dockerfile](https://github.com/dockette/ci/blob/master/node19/Dockerfile) | +| NodeJS 18 (v18.9.1) | Alpine v3.16 | node18 | v18.9.1 | 8.10.0 | 8.15.9 | [Dockerfile](https://github.com/dockette/ci/blob/master/node18/Dockerfile) | | NodeJS 17 (v17.9.0) | Alpine v3.15 | node17 | v17.9.0 | 8.1.3 | N/A | [Dockerfile](https://github.com/dockette/ci/blob/master/node17/Dockerfile) | | NodeJS 16 (v16.11.1) | Alpine v3.14 | node16 | v16.11.1 | 7.17.0 | N/A | [Dockerfile](https://github.com/dockette/ci/blob/master/node16/Dockerfile) | | NodeJS 15 (v15.10.0) | Alpine v3.13 | node15 | v15.10.0 | 6.14.17 | N/A | [Dockerfile](https://github.com/dockette/ci/blob/master/node15/Dockerfile) | diff --git a/node12/Dockerfile b/node12/Dockerfile index d376bc0..10d0204 100644 --- a/node12/Dockerfile +++ b/node12/Dockerfile @@ -8,7 +8,7 @@ RUN echo '@community http://dl-cdn.alpinelinux.org/alpine/v3.12/community' >> /e # DEPENDENCIES ############################################################# apk add --update bash git ca-certificates curl openssh tzdata make direnv@v314 && \ # NODEJS ################################################################### - apk add --update nodejs-current npm && \ + apk add --update nodejs npm && \ # CLEAN UP ################################################################# rm -rf /var/cache/apk/* diff --git a/node18/Dockerfile b/node18/Dockerfile index b137edd..f164d17 100644 --- a/node18/Dockerfile +++ b/node18/Dockerfile @@ -8,7 +8,7 @@ RUN echo '@community http://dl-cdn.alpinelinux.org/alpine/v3.16/community' >> /e apk add --update bash git ca-certificates curl openssh tzdata make direnv && \ # NODEJS ################################################################### apk add --update nodejs-current@community npm@community && \ - corepack enable && corepack prepare pnpm@latest --activate && \ + corepack enable && corepack prepare pnpm@8.15.9 --activate && \ # CLEAN UP ################################################################# rm -rf /var/cache/apk/* diff --git a/node19/Dockerfile b/node19/Dockerfile index 77fa900..c909f8d 100644 --- a/node19/Dockerfile +++ b/node19/Dockerfile @@ -8,7 +8,7 @@ RUN echo '@community http://dl-cdn.alpinelinux.org/alpine/v3.17/community' >> /e apk add --update bash git ca-certificates curl openssh tzdata make direnv && \ # NODEJS ################################################################### apk add --update nodejs-current@community npm@community && \ - corepack enable && corepack prepare pnpm@latest --activate && \ + corepack enable && corepack prepare pnpm@10.34.6 --activate && \ # CLEAN UP ################################################################# rm -rf /var/cache/apk/* diff --git a/node20/Dockerfile b/node20/Dockerfile index 3f95b72..7b7985e 100644 --- a/node20/Dockerfile +++ b/node20/Dockerfile @@ -8,7 +8,7 @@ RUN echo '@community http://dl-cdn.alpinelinux.org/alpine/v3.18/community' >> /e apk add --update bash git ca-certificates curl openssh tzdata make direnv && \ # NODEJS ################################################################### apk add --update nodejs-current@community npm@community && \ - corepack enable && corepack prepare pnpm@latest --activate && \ + corepack enable && corepack prepare pnpm@10.34.6 --activate && \ # CLEAN UP ################################################################# rm -rf /var/cache/apk/* diff --git a/node21/Dockerfile b/node21/Dockerfile index 64b0922..70a1e8f 100644 --- a/node21/Dockerfile +++ b/node21/Dockerfile @@ -8,7 +8,7 @@ RUN echo '@community http://dl-cdn.alpinelinux.org/alpine/v3.20/community' >> /e apk add --update bash git ca-certificates curl openssh tzdata make direnv && \ # NODEJS ################################################################### apk add --update nodejs-current@community npm@community && \ - corepack enable && corepack prepare pnpm@latest --activate && \ + corepack enable && corepack prepare pnpm@10.34.6 --activate && \ # CLEAN UP ################################################################# rm -rf /var/cache/apk/* diff --git a/node8/Dockerfile b/node8/Dockerfile index aeb0394..f43c079 100644 --- a/node8/Dockerfile +++ b/node8/Dockerfile @@ -8,7 +8,7 @@ RUN echo '@main http://dl-cdn.alpinelinux.org/alpine/v3.8/main' >> /etc/apk/repo # DEPENDENCIES ############################################################# apk add --update bash git ca-certificates curl openssh tzdata make direnv@v314 && \ # NODEJS ################################################################### - apk add --update nodejs-current@main && \ + apk add --update nodejs-npm@main && \ # CLEAN UP ################################################################# rm -rf /var/cache/apk/* From 3a25d26e1a47efffa30d7a582643e96a3d134253 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20Felix=20=C5=A0ulc?= Date: Wed, 30 Sep 2026 20:29:43 +0000 Subject: [PATCH 5/6] CI: run smoke tests in a Test job, not in the shared workflow The "test" input of the shared dockette/.github workflow is not planned (dockette/.github#5 is closed). Run the tests in this repo: the Test job builds each image for linux/amd64, loads it and runs .scripts/test.sh. The Build job uses the shared workflow from @master again and pushes only after all tests pass. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01VSKw7jY45nUJWQxWpvjm82 --- .github/workflows/docker.yml | 67 ++++++++++++++++++++++++++++++++++-- AGENTS.md | 4 +-- 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 00efe19..067a2b7 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -12,16 +12,79 @@ permissions: contents: read jobs: + test: + name: "Test" + runs-on: ubuntu-latest + strategy: + matrix: + include: + # Node + - item: node6 + - item: node7 + - item: node8 + - item: node9 + - item: node10 + - item: node11 + - item: node12 + - item: node13 + - item: node14 + - item: node15 + - item: node16 + - item: node17 + - item: node18 + - item: node19 + - item: node20 + - item: node21 + - item: node22 + - item: node23 + - item: node24 + - item: node26 + # PHP + - item: php56 + - item: php70 + - item: php71 + - item: php72 + - item: php73 + - item: php74 + - item: php80 + - item: php81 + - item: php82 + - item: php83 + - item: php84 + - item: php85 + # Ansitest + - item: ansitest + + fail-fast: false + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + + - name: Build image + uses: docker/build-push-action@v7 + with: + context: ${{ matrix.item }} + tags: dockette/ci:${{ matrix.item }} + platforms: linux/amd64 + load: true + cache-from: type=gha + + - name: Test image + run: .scripts/test.sh ${{ matrix.item }} + build: name: "Build" - uses: dockette/.github/.github/workflows/docker.yml@claude/exciting-feynman-p0jaf4 + needs: test + uses: dockette/.github/.github/workflows/docker.yml@master secrets: inherit with: image: "dockette/ci" tag: "${{ matrix.item }}" context: "${{ matrix.item }}" push: ${{ github.ref == 'refs/heads/master' }} - test: .scripts/test.sh ${{ matrix.item }} "$IMAGE" strategy: matrix: include: diff --git a/AGENTS.md b/AGENTS.md index c623162..cfc8592 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -70,8 +70,8 @@ docker buildx build --load -t dockette/ci:node24 ./node24 .scripts/test.sh node24 ``` -CI runs the same script for every image before the push, through the `test` -input of the shared `dockette/.github` Docker workflow. +CI runs the same script for every image in the `Test` job. The `Build` job +builds and pushes the images only after all tests pass. ## Platform Detection From d72592d69b965b9b2403a56da448657ee2cf81d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20Felix=20=C5=A0ulc?= Date: Thu, 1 Oct 2026 19:02:09 +0200 Subject: [PATCH 6/6] AGENTS: explain how to run the smoke tests --- AGENTS.md | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index cfc8592..34f5997 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -61,17 +61,34 @@ docker buildx build --load -t dockette/ci:node24 ./node24 ## Testing -`.scripts/test.sh` runs smoke tests for one image. It checks the PHP or Node.js -version, the main tools (composer, phpxd, npm, pnpm, ansible and more) and that -PHP starts without warnings. +Each image has a smoke test in `.scripts/test.sh`. To test an image, build it +first, then run the script with the image directory name: ```bash +# 1. Build the image and load it into the local Docker docker buildx build --load -t dockette/ci:node24 ./node24 + +# 2. Run the smoke test .scripts/test.sh node24 ``` -CI runs the same script for every image in the `Test` job. The `Build` job -builds and pushes the images only after all tests pass. +The script starts the image and prints `ok` or `FAIL` for each check. It exits +with 1 if any check fails. + +To test an image with a different tag, pass the tag as the second argument: + +```bash +.scripts/test.sh php84 my-local/ci:php84 +``` + +What the script checks: + +- `phpXX`: PHP version, PHP starts without warnings, main extensions, `phpxd`, `composer` +- `nodeXX`: Node.js version, `npm`, `pnpm` (node18 and newer) +- `ansitest`: `ansible`, `ansible-lint`, `yamllint`, `molecule`, `docker`, `community.docker` collection +- all images: `bash`, `git`, `curl`, `make` + +`make test` builds and tests `php84`, `node24` and `ansitest` in one step. ## Platform Detection