From c3e79e94835a20133c2bfaf77a869c19c3d13fe0 Mon Sep 17 00:00:00 2001 From: William Desportes Date: Mon, 2 Nov 2026 16:51:07 +0100 Subject: [PATCH] Build the release kit from the signed release tag Instead of downloading the release tarball, build the kit in a stage based on the official php:8.3-cli-trixie image, checking out the commit the signed release tag points at and verifying the signature against the release key. This locks the Composer dependencies for the PHP version of the image instead of the minimum supported one, and lets them be updated to fix vulnerabilities for the lifetime of the version. The tag commit is resolved by update.sh with the release tag format the daily-composer script documents, and recorded in the generated Dockerfiles. generate-stackbrew-library.sh had to learn about multi-stage Dockerfiles: it read the second word of every FROM and every COPY argument, so the new stage made it look for a repository named --platform=$BUILDPLATFORM and for files outside the repository. The kit is copied already extracted to avoid keeping the archive in its own layer, git verify-tag runs unpiped so a failed or revoked signature fails the build, and gd is installed in the build stage so the GIS tests run. Fixes https://github.com/phpmyadmin/docker/issues/472 Signed-off-by: William Desportes Co-Authored-By: DeepSeek --- CHANGELOG.md | 7 +++ Dockerfile-alpine.template | 102 ++++++++++++++++++++++++++------- Dockerfile-debian.template | 103 +++++++++++++++++++++++++++------- apache/Dockerfile | 103 +++++++++++++++++++++++++++------- fpm-alpine/Dockerfile | 102 ++++++++++++++++++++++++++------- fpm/Dockerfile | 103 +++++++++++++++++++++++++++------- generate-stackbrew-library.sh | 59 ++++++++++++++++--- update.sh | 92 +++++++++++++++++++++--------- 8 files changed, 538 insertions(+), 133 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 06dc09c8..d05268ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [Unreleased] + +- Build the release kit from the signed release tag instead of downloading + it, so that the Composer dependencies are locked for the PHP version of the + image and can be refreshed to fix vulnerabilities for the lifetime of the + version (#472) + ## [5.2.3.1] - 2025-10-08 - Remove leftover uploadprogress.tar.gz download after installation (#465) diff --git a/Dockerfile-alpine.template b/Dockerfile-alpine.template index 1611ca0b..0a1e7635 100644 --- a/Dockerfile-alpine.template +++ b/Dockerfile-alpine.template @@ -1,3 +1,81 @@ +# Build the release kit from the signed release tag instead of downloading it, so +# that the dependencies are locked for the PHP version of this image and can be +# updated to fix vulnerabilities for the lifetime of the version. +# See https://github.com/phpmyadmin/docker/issues/472 +FROM --platform=$BUILDPLATFORM php:%%PHP_VERSION%%-cli-trixie AS phpmyadmin-kit + +ENV PMA_VERSION="%%VERSION%%" \ + PMA_BRANCH="%%RELEASE_BRANCH%%" \ + PMA_TAG="%%TAG%%" \ + PMA_COMMIT="%%PMA_COMMIT%%" \ + PMA_GPG_KEY="%%GPG_KEY%%" \ + COREPACK_ENABLE_DOWNLOAD_PROMPT="0" + +# Official image, so no installer is downloaded from getcomposer.org +COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer + +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + gettext \ + git \ + gnupg \ + libfreetype6-dev \ + libjpeg62-turbo-dev \ + libpng-dev \ + libzip-dev \ + make \ + nodejs \ + python3-sphinx \ + xz-utils \ + ; \ + docker-php-ext-install gd mysqli zip; \ + corepack enable; \ + rm -rf /var/lib/apt/lists/*; \ + echo 'memory_limit = 512M' > "$PHP_INI_DIR/conf.d/zz-build.ini" + +# The release tag must be signed by the phpMyAdmin release key and point at the +# commit pinned in the generated Dockerfile +RUN set -eux; \ + git init /src; \ + cd /src; \ + git remote add origin https://github.com/phpmyadmin/phpmyadmin.git; \ + git fetch --depth 1 origin "refs/tags/${PMA_TAG}:refs/tags/${PMA_TAG}"; \ + test "$(git rev-parse "${PMA_TAG}^{commit}")" = "$PMA_COMMIT"; \ + export GNUPGHOME="$(mktemp -d)"; \ + gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$PMA_GPG_KEY" \ + || gpg --batch --keyserver pgp.mit.edu --recv-keys "$PMA_GPG_KEY" \ + || gpg --batch --keyserver keyserver.pgp.com --recv-keys "$PMA_GPG_KEY" \ + || gpg --batch --keyserver keys.openpgp.org --recv-keys "$PMA_GPG_KEY" \ + ; \ + gpg --batch --with-colons --list-keys "$PMA_GPG_KEY" | grep -q "^fpr:.*:${PMA_GPG_KEY}:"; \ + git verify-tag --raw "$PMA_TAG" > /tmp/verify-tag.log 2>&1; \ + ! grep -qE "REVKEYSIG|EXPKEYSIG|EXPSIG|BADSIG|ERRSIG" /tmp/verify-tag.log; \ + grep -qE "^\[GNUPG:\] VALIDSIG [0-9A-F]+ [0-9-]+ [0-9]+ .*${PMA_GPG_KEY}( |$)" /tmp/verify-tag.log; \ + git checkout -B "$PMA_BRANCH" "$PMA_COMMIT"; \ + gpgconf --kill all; \ + rm -r "$GNUPGHOME" + +# create-release.sh locks the dependencies for the minimum PHP version it +# parses out of composer.json, lock them for the one of this image instead +RUN set -eux; \ + cd /src; \ + php_version="$(php -r 'echo PHP_VERSION;')"; \ + sed -i "s|^PHP_REQ=.*|PHP_REQ=\"${php_version}\"|" scripts/create-release.sh; \ + grep -q "^PHP_REQ=\"${php_version}\"$" scripts/create-release.sh; \ + echo y | ./scripts/create-release.sh "$PMA_VERSION" "$PMA_BRANCH" \ + --kits all-languages --compressions txz --no-sign; \ + sha256sum "/src/release/phpMyAdmin-${PMA_VERSION}-all-languages.tar.xz" + +# Show the advisories left in the kit that actually ships +RUN set -eux; \ + mkdir -p /kit; \ + tar -xf "/src/release/phpMyAdmin-${PMA_VERSION}-all-languages.tar.xz" -C /kit --strip-components=1; \ + cd /kit; \ + composer --version; \ + composer audit --no-dev --format=table || true + FROM php:%%PHP_VERSION%%-%%VARIANT%% ENV UPLOAD_PROGRESS_EXT_URL="https://github.com/php/pecl-php-uploadprogress/archive/refs/tags/uploadprogress-2.0.2.tar.gz" @@ -6,8 +84,7 @@ ENV UPLOAD_PROGRESS_SHA256="fe3f6cdfcedad563c970c4fd1cda31e422cfc0df5cc9a217d8c8 # install and docker-entrypoint.sh dependencies RUN apk add --no-cache \ bash \ - tzdata \ - gnupg + tzdata # Install dependencies RUN set -ex; \ @@ -92,10 +169,8 @@ RUN set -ex; \ USER www-data:www-data -# Calculate download URL +# Version of phpMyAdmin built above ENV VERSION=%%VERSION%% -ENV SHA256=%%SHA256%% -ENV URL=https://files.phpmyadmin.net/phpMyAdmin/${VERSION}/phpMyAdmin-${VERSION}-all-languages.tar.xz LABEL org.opencontainers.image.title="Official phpMyAdmin Docker image" \ org.opencontainers.image.description="Run phpMyAdmin with Alpine, Apache and PHP FPM." \ @@ -107,23 +182,12 @@ LABEL org.opencontainers.image.title="Official phpMyAdmin Docker image" \ org.opencontainers.image.url="https://github.com/phpmyadmin/docker#readme" \ org.opencontainers.image.source="https://github.com/phpmyadmin/docker.git" -# Download tarball, verify it using gpg and extract +# Copy the kit built from the signed release tag +COPY --chown=www-data:www-data --from=phpmyadmin-kit /kit/ /var/www/html/ + RUN set -ex; \ \ - export GNUPGHOME="$(mktemp -d)"; \ - export GPGKEY="%%GPG_KEY%%"; \ - curl -fsSL -o phpMyAdmin.tar.xz $URL; \ - curl -fsSL -o phpMyAdmin.tar.xz.asc $URL.asc; \ - echo "$SHA256 *phpMyAdmin.tar.xz" | sha256sum -c -; \ - gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$GPGKEY" \ - || gpg --batch --keyserver pgp.mit.edu --recv-keys "$GPGKEY" \ - || gpg --batch --keyserver keyserver.pgp.com --recv-keys "$GPGKEY" \ - || gpg --batch --keyserver keys.openpgp.org --recv-keys "$GPGKEY"; \ - gpg --batch --verify phpMyAdmin.tar.xz.asc phpMyAdmin.tar.xz; \ - tar -xf phpMyAdmin.tar.xz -C /var/www/html --strip-components=1; \ mkdir -p /var/www/html/tmp; \ - gpgconf --kill all; \ - rm -r "$GNUPGHOME" phpMyAdmin.tar.xz phpMyAdmin.tar.xz.asc; \ rm -r -v /var/www/html/setup/ /var/www/html/examples/ /var/www/html/js/src/ /var/www/html/babel.config.json /var/www/html/doc/html/_sources/ /var/www/html/RELEASE-DATE-$VERSION /var/www/html/CONTRIBUTING.md; \ grep -q -F "'configFile' => ROOT_PATH . 'config.inc.php'," /var/www/html/libraries/vendor_config.php; \ sed -i "s@'configFile' => .*@'configFile' => '/etc/phpmyadmin/config.inc.php',@" /var/www/html/libraries/vendor_config.php; \ diff --git a/Dockerfile-debian.template b/Dockerfile-debian.template index f8b424b4..48c9fcad 100644 --- a/Dockerfile-debian.template +++ b/Dockerfile-debian.template @@ -1,3 +1,81 @@ +# Build the release kit from the signed release tag instead of downloading it, so +# that the dependencies are locked for the PHP version of this image and can be +# updated to fix vulnerabilities for the lifetime of the version. +# See https://github.com/phpmyadmin/docker/issues/472 +FROM --platform=$BUILDPLATFORM php:%%PHP_VERSION%%-cli-trixie AS phpmyadmin-kit + +ENV PMA_VERSION="%%VERSION%%" \ + PMA_BRANCH="%%RELEASE_BRANCH%%" \ + PMA_TAG="%%TAG%%" \ + PMA_COMMIT="%%PMA_COMMIT%%" \ + PMA_GPG_KEY="%%GPG_KEY%%" \ + COREPACK_ENABLE_DOWNLOAD_PROMPT="0" + +# Official image, so no installer is downloaded from getcomposer.org +COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer + +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + gettext \ + git \ + gnupg \ + libfreetype6-dev \ + libjpeg62-turbo-dev \ + libpng-dev \ + libzip-dev \ + make \ + nodejs \ + python3-sphinx \ + xz-utils \ + ; \ + docker-php-ext-install gd mysqli zip; \ + corepack enable; \ + rm -rf /var/lib/apt/lists/*; \ + echo 'memory_limit = 512M' > "$PHP_INI_DIR/conf.d/zz-build.ini" + +# The release tag must be signed by the phpMyAdmin release key and point at the +# commit pinned in the generated Dockerfile +RUN set -eux; \ + git init /src; \ + cd /src; \ + git remote add origin https://github.com/phpmyadmin/phpmyadmin.git; \ + git fetch --depth 1 origin "refs/tags/${PMA_TAG}:refs/tags/${PMA_TAG}"; \ + test "$(git rev-parse "${PMA_TAG}^{commit}")" = "$PMA_COMMIT"; \ + export GNUPGHOME="$(mktemp -d)"; \ + gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$PMA_GPG_KEY" \ + || gpg --batch --keyserver pgp.mit.edu --recv-keys "$PMA_GPG_KEY" \ + || gpg --batch --keyserver keyserver.pgp.com --recv-keys "$PMA_GPG_KEY" \ + || gpg --batch --keyserver keys.openpgp.org --recv-keys "$PMA_GPG_KEY" \ + ; \ + gpg --batch --with-colons --list-keys "$PMA_GPG_KEY" | grep -q "^fpr:.*:${PMA_GPG_KEY}:"; \ + git verify-tag --raw "$PMA_TAG" > /tmp/verify-tag.log 2>&1; \ + ! grep -qE "REVKEYSIG|EXPKEYSIG|EXPSIG|BADSIG|ERRSIG" /tmp/verify-tag.log; \ + grep -qE "^\[GNUPG:\] VALIDSIG [0-9A-F]+ [0-9-]+ [0-9]+ .*${PMA_GPG_KEY}( |$)" /tmp/verify-tag.log; \ + git checkout -B "$PMA_BRANCH" "$PMA_COMMIT"; \ + gpgconf --kill all; \ + rm -r "$GNUPGHOME" + +# create-release.sh locks the dependencies for the minimum PHP version it +# parses out of composer.json, lock them for the one of this image instead +RUN set -eux; \ + cd /src; \ + php_version="$(php -r 'echo PHP_VERSION;')"; \ + sed -i "s|^PHP_REQ=.*|PHP_REQ=\"${php_version}\"|" scripts/create-release.sh; \ + grep -q "^PHP_REQ=\"${php_version}\"$" scripts/create-release.sh; \ + echo y | ./scripts/create-release.sh "$PMA_VERSION" "$PMA_BRANCH" \ + --kits all-languages --compressions txz --no-sign; \ + sha256sum "/src/release/phpMyAdmin-${PMA_VERSION}-all-languages.tar.xz" + +# Show the advisories left in the kit that actually ships +RUN set -eux; \ + mkdir -p /kit; \ + tar -xf "/src/release/phpMyAdmin-${PMA_VERSION}-all-languages.tar.xz" -C /kit --strip-components=1; \ + cd /kit; \ + composer --version; \ + composer audit --no-dev --format=table || true + FROM php:%%PHP_VERSION%%-%%VARIANT%% ENV UPLOAD_PROGRESS_EXT_URL="https://github.com/php/pecl-php-uploadprogress/archive/refs/tags/uploadprogress-2.0.2.tar.gz" @@ -7,10 +85,6 @@ ENV UPLOAD_PROGRESS_SHA256="fe3f6cdfcedad563c970c4fd1cda31e422cfc0df5cc9a217d8c8 RUN set -ex; \ \ apt-get update; \ - apt-get install -y --no-install-recommends \ - gnupg \ - dirmngr \ - ; \ \ savedAptMark="$(apt-mark showmanual)"; \ \ @@ -107,10 +181,8 @@ RUN set -ex; \ USER www-data:www-data -# Calculate download URL +# Version of phpMyAdmin built above ENV VERSION=%%VERSION%% -ENV SHA256=%%SHA256%% -ENV URL=https://files.phpmyadmin.net/phpMyAdmin/${VERSION}/phpMyAdmin-${VERSION}-all-languages.tar.xz LABEL org.opencontainers.image.title="Official phpMyAdmin Docker image" \ org.opencontainers.image.description="Run phpMyAdmin with Alpine, Apache and PHP FPM." \ @@ -122,22 +194,11 @@ LABEL org.opencontainers.image.title="Official phpMyAdmin Docker image" \ org.opencontainers.image.url="https://github.com/phpmyadmin/docker#readme" \ org.opencontainers.image.source="https://github.com/phpmyadmin/docker.git" -# Download tarball, verify it using gpg and extract +# Copy the kit built from the signed release tag +COPY --chown=www-data:www-data --from=phpmyadmin-kit /kit/ /var/www/html/ + RUN set -ex; \ - export GNUPGHOME="$(mktemp -d)"; \ - export GPGKEY="%%GPG_KEY%%"; \ - curl -fsSL -o phpMyAdmin.tar.xz $URL; \ - curl -fsSL -o phpMyAdmin.tar.xz.asc $URL.asc; \ - echo "$SHA256 *phpMyAdmin.tar.xz" | sha256sum -c -; \ - gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$GPGKEY" \ - || gpg --batch --keyserver pgp.mit.edu --recv-keys "$GPGKEY" \ - || gpg --batch --keyserver keyserver.pgp.com --recv-keys "$GPGKEY" \ - || gpg --batch --keyserver keys.openpgp.org --recv-keys "$GPGKEY"; \ - gpg --batch --verify phpMyAdmin.tar.xz.asc phpMyAdmin.tar.xz; \ - tar -xf phpMyAdmin.tar.xz -C /var/www/html --strip-components=1; \ mkdir -p /var/www/html/tmp; \ - gpgconf --kill all; \ - rm -r "$GNUPGHOME" phpMyAdmin.tar.xz phpMyAdmin.tar.xz.asc; \ rm -r -v /var/www/html/setup/ /var/www/html/examples/ /var/www/html/js/src/ /var/www/html/babel.config.json /var/www/html/doc/html/_sources/ /var/www/html/RELEASE-DATE-$VERSION /var/www/html/CONTRIBUTING.md; \ grep -q -F "'configFile' => ROOT_PATH . 'config.inc.php'," /var/www/html/libraries/vendor_config.php; \ sed -i "s@'configFile' => .*@'configFile' => '/etc/phpmyadmin/config.inc.php',@" /var/www/html/libraries/vendor_config.php; \ diff --git a/apache/Dockerfile b/apache/Dockerfile index eaf234e4..811766bc 100644 --- a/apache/Dockerfile +++ b/apache/Dockerfile @@ -1,4 +1,82 @@ # DO NOT EDIT: created by update.sh from Dockerfile-debian.template +# Build the release kit from the signed release tag instead of downloading it, so +# that the dependencies are locked for the PHP version of this image and can be +# updated to fix vulnerabilities for the lifetime of the version. +# See https://github.com/phpmyadmin/docker/issues/472 +FROM --platform=$BUILDPLATFORM php:8.3-cli-trixie AS phpmyadmin-kit + +ENV PMA_VERSION="5.2.3" \ + PMA_BRANCH="QA_5_2" \ + PMA_TAG="RELEASE_5_2_3" \ + PMA_COMMIT="962857e4f63d42e38f11ff4d63f5e722018add76" \ + PMA_GPG_KEY="3D06A59ECE730EB71B511C17CE752F178259BD92" \ + COREPACK_ENABLE_DOWNLOAD_PROMPT="0" + +# Official image, so no installer is downloaded from getcomposer.org +COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer + +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + gettext \ + git \ + gnupg \ + libfreetype6-dev \ + libjpeg62-turbo-dev \ + libpng-dev \ + libzip-dev \ + make \ + nodejs \ + python3-sphinx \ + xz-utils \ + ; \ + docker-php-ext-install gd mysqli zip; \ + corepack enable; \ + rm -rf /var/lib/apt/lists/*; \ + echo 'memory_limit = 512M' > "$PHP_INI_DIR/conf.d/zz-build.ini" + +# The release tag must be signed by the phpMyAdmin release key and point at the +# commit pinned in the generated Dockerfile +RUN set -eux; \ + git init /src; \ + cd /src; \ + git remote add origin https://github.com/phpmyadmin/phpmyadmin.git; \ + git fetch --depth 1 origin "refs/tags/${PMA_TAG}:refs/tags/${PMA_TAG}"; \ + test "$(git rev-parse "${PMA_TAG}^{commit}")" = "$PMA_COMMIT"; \ + export GNUPGHOME="$(mktemp -d)"; \ + gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$PMA_GPG_KEY" \ + || gpg --batch --keyserver pgp.mit.edu --recv-keys "$PMA_GPG_KEY" \ + || gpg --batch --keyserver keyserver.pgp.com --recv-keys "$PMA_GPG_KEY" \ + || gpg --batch --keyserver keys.openpgp.org --recv-keys "$PMA_GPG_KEY" \ + ; \ + gpg --batch --with-colons --list-keys "$PMA_GPG_KEY" | grep -q "^fpr:.*:${PMA_GPG_KEY}:"; \ + git verify-tag --raw "$PMA_TAG" > /tmp/verify-tag.log 2>&1; \ + ! grep -qE "REVKEYSIG|EXPKEYSIG|EXPSIG|BADSIG|ERRSIG" /tmp/verify-tag.log; \ + grep -qE "^\[GNUPG:\] VALIDSIG [0-9A-F]+ [0-9-]+ [0-9]+ .*${PMA_GPG_KEY}( |$)" /tmp/verify-tag.log; \ + git checkout -B "$PMA_BRANCH" "$PMA_COMMIT"; \ + gpgconf --kill all; \ + rm -r "$GNUPGHOME" + +# create-release.sh locks the dependencies for the minimum PHP version it +# parses out of composer.json, lock them for the one of this image instead +RUN set -eux; \ + cd /src; \ + php_version="$(php -r 'echo PHP_VERSION;')"; \ + sed -i "s|^PHP_REQ=.*|PHP_REQ=\"${php_version}\"|" scripts/create-release.sh; \ + grep -q "^PHP_REQ=\"${php_version}\"$" scripts/create-release.sh; \ + echo y | ./scripts/create-release.sh "$PMA_VERSION" "$PMA_BRANCH" \ + --kits all-languages --compressions txz --no-sign; \ + sha256sum "/src/release/phpMyAdmin-${PMA_VERSION}-all-languages.tar.xz" + +# Show the advisories left in the kit that actually ships +RUN set -eux; \ + mkdir -p /kit; \ + tar -xf "/src/release/phpMyAdmin-${PMA_VERSION}-all-languages.tar.xz" -C /kit --strip-components=1; \ + cd /kit; \ + composer --version; \ + composer audit --no-dev --format=table || true + FROM php:8.3-apache ENV UPLOAD_PROGRESS_EXT_URL="https://github.com/php/pecl-php-uploadprogress/archive/refs/tags/uploadprogress-2.0.2.tar.gz" @@ -8,10 +86,6 @@ ENV UPLOAD_PROGRESS_SHA256="fe3f6cdfcedad563c970c4fd1cda31e422cfc0df5cc9a217d8c8 RUN set -ex; \ \ apt-get update; \ - apt-get install -y --no-install-recommends \ - gnupg \ - dirmngr \ - ; \ \ savedAptMark="$(apt-mark showmanual)"; \ \ @@ -108,10 +182,8 @@ RUN set -ex; \ USER www-data:www-data -# Calculate download URL +# Version of phpMyAdmin built above ENV VERSION=5.2.3 -ENV SHA256=57881348297c4412f86c410547cf76b4d8a236574dd2c6b7d6a2beebe7fc44e3 -ENV URL=https://files.phpmyadmin.net/phpMyAdmin/${VERSION}/phpMyAdmin-${VERSION}-all-languages.tar.xz LABEL org.opencontainers.image.title="Official phpMyAdmin Docker image" \ org.opencontainers.image.description="Run phpMyAdmin with Alpine, Apache and PHP FPM." \ @@ -123,22 +195,11 @@ LABEL org.opencontainers.image.title="Official phpMyAdmin Docker image" \ org.opencontainers.image.url="https://github.com/phpmyadmin/docker#readme" \ org.opencontainers.image.source="https://github.com/phpmyadmin/docker.git" -# Download tarball, verify it using gpg and extract +# Copy the kit built from the signed release tag +COPY --chown=www-data:www-data --from=phpmyadmin-kit /kit/ /var/www/html/ + RUN set -ex; \ - export GNUPGHOME="$(mktemp -d)"; \ - export GPGKEY="3D06A59ECE730EB71B511C17CE752F178259BD92"; \ - curl -fsSL -o phpMyAdmin.tar.xz $URL; \ - curl -fsSL -o phpMyAdmin.tar.xz.asc $URL.asc; \ - echo "$SHA256 *phpMyAdmin.tar.xz" | sha256sum -c -; \ - gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$GPGKEY" \ - || gpg --batch --keyserver pgp.mit.edu --recv-keys "$GPGKEY" \ - || gpg --batch --keyserver keyserver.pgp.com --recv-keys "$GPGKEY" \ - || gpg --batch --keyserver keys.openpgp.org --recv-keys "$GPGKEY"; \ - gpg --batch --verify phpMyAdmin.tar.xz.asc phpMyAdmin.tar.xz; \ - tar -xf phpMyAdmin.tar.xz -C /var/www/html --strip-components=1; \ mkdir -p /var/www/html/tmp; \ - gpgconf --kill all; \ - rm -r "$GNUPGHOME" phpMyAdmin.tar.xz phpMyAdmin.tar.xz.asc; \ rm -r -v /var/www/html/setup/ /var/www/html/examples/ /var/www/html/js/src/ /var/www/html/babel.config.json /var/www/html/doc/html/_sources/ /var/www/html/RELEASE-DATE-$VERSION /var/www/html/CONTRIBUTING.md; \ grep -q -F "'configFile' => ROOT_PATH . 'config.inc.php'," /var/www/html/libraries/vendor_config.php; \ sed -i "s@'configFile' => .*@'configFile' => '/etc/phpmyadmin/config.inc.php',@" /var/www/html/libraries/vendor_config.php; \ diff --git a/fpm-alpine/Dockerfile b/fpm-alpine/Dockerfile index dcac4fcd..52d9e4b2 100644 --- a/fpm-alpine/Dockerfile +++ b/fpm-alpine/Dockerfile @@ -1,4 +1,82 @@ # DO NOT EDIT: created by update.sh from Dockerfile-alpine.template +# Build the release kit from the signed release tag instead of downloading it, so +# that the dependencies are locked for the PHP version of this image and can be +# updated to fix vulnerabilities for the lifetime of the version. +# See https://github.com/phpmyadmin/docker/issues/472 +FROM --platform=$BUILDPLATFORM php:8.3-cli-trixie AS phpmyadmin-kit + +ENV PMA_VERSION="5.2.3" \ + PMA_BRANCH="QA_5_2" \ + PMA_TAG="RELEASE_5_2_3" \ + PMA_COMMIT="962857e4f63d42e38f11ff4d63f5e722018add76" \ + PMA_GPG_KEY="3D06A59ECE730EB71B511C17CE752F178259BD92" \ + COREPACK_ENABLE_DOWNLOAD_PROMPT="0" + +# Official image, so no installer is downloaded from getcomposer.org +COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer + +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + gettext \ + git \ + gnupg \ + libfreetype6-dev \ + libjpeg62-turbo-dev \ + libpng-dev \ + libzip-dev \ + make \ + nodejs \ + python3-sphinx \ + xz-utils \ + ; \ + docker-php-ext-install gd mysqli zip; \ + corepack enable; \ + rm -rf /var/lib/apt/lists/*; \ + echo 'memory_limit = 512M' > "$PHP_INI_DIR/conf.d/zz-build.ini" + +# The release tag must be signed by the phpMyAdmin release key and point at the +# commit pinned in the generated Dockerfile +RUN set -eux; \ + git init /src; \ + cd /src; \ + git remote add origin https://github.com/phpmyadmin/phpmyadmin.git; \ + git fetch --depth 1 origin "refs/tags/${PMA_TAG}:refs/tags/${PMA_TAG}"; \ + test "$(git rev-parse "${PMA_TAG}^{commit}")" = "$PMA_COMMIT"; \ + export GNUPGHOME="$(mktemp -d)"; \ + gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$PMA_GPG_KEY" \ + || gpg --batch --keyserver pgp.mit.edu --recv-keys "$PMA_GPG_KEY" \ + || gpg --batch --keyserver keyserver.pgp.com --recv-keys "$PMA_GPG_KEY" \ + || gpg --batch --keyserver keys.openpgp.org --recv-keys "$PMA_GPG_KEY" \ + ; \ + gpg --batch --with-colons --list-keys "$PMA_GPG_KEY" | grep -q "^fpr:.*:${PMA_GPG_KEY}:"; \ + git verify-tag --raw "$PMA_TAG" > /tmp/verify-tag.log 2>&1; \ + ! grep -qE "REVKEYSIG|EXPKEYSIG|EXPSIG|BADSIG|ERRSIG" /tmp/verify-tag.log; \ + grep -qE "^\[GNUPG:\] VALIDSIG [0-9A-F]+ [0-9-]+ [0-9]+ .*${PMA_GPG_KEY}( |$)" /tmp/verify-tag.log; \ + git checkout -B "$PMA_BRANCH" "$PMA_COMMIT"; \ + gpgconf --kill all; \ + rm -r "$GNUPGHOME" + +# create-release.sh locks the dependencies for the minimum PHP version it +# parses out of composer.json, lock them for the one of this image instead +RUN set -eux; \ + cd /src; \ + php_version="$(php -r 'echo PHP_VERSION;')"; \ + sed -i "s|^PHP_REQ=.*|PHP_REQ=\"${php_version}\"|" scripts/create-release.sh; \ + grep -q "^PHP_REQ=\"${php_version}\"$" scripts/create-release.sh; \ + echo y | ./scripts/create-release.sh "$PMA_VERSION" "$PMA_BRANCH" \ + --kits all-languages --compressions txz --no-sign; \ + sha256sum "/src/release/phpMyAdmin-${PMA_VERSION}-all-languages.tar.xz" + +# Show the advisories left in the kit that actually ships +RUN set -eux; \ + mkdir -p /kit; \ + tar -xf "/src/release/phpMyAdmin-${PMA_VERSION}-all-languages.tar.xz" -C /kit --strip-components=1; \ + cd /kit; \ + composer --version; \ + composer audit --no-dev --format=table || true + FROM php:8.3-fpm-alpine ENV UPLOAD_PROGRESS_EXT_URL="https://github.com/php/pecl-php-uploadprogress/archive/refs/tags/uploadprogress-2.0.2.tar.gz" @@ -7,8 +85,7 @@ ENV UPLOAD_PROGRESS_SHA256="fe3f6cdfcedad563c970c4fd1cda31e422cfc0df5cc9a217d8c8 # install and docker-entrypoint.sh dependencies RUN apk add --no-cache \ bash \ - tzdata \ - gnupg + tzdata # Install dependencies RUN set -ex; \ @@ -93,10 +170,8 @@ RUN set -ex; \ USER www-data:www-data -# Calculate download URL +# Version of phpMyAdmin built above ENV VERSION=5.2.3 -ENV SHA256=57881348297c4412f86c410547cf76b4d8a236574dd2c6b7d6a2beebe7fc44e3 -ENV URL=https://files.phpmyadmin.net/phpMyAdmin/${VERSION}/phpMyAdmin-${VERSION}-all-languages.tar.xz LABEL org.opencontainers.image.title="Official phpMyAdmin Docker image" \ org.opencontainers.image.description="Run phpMyAdmin with Alpine, Apache and PHP FPM." \ @@ -108,23 +183,12 @@ LABEL org.opencontainers.image.title="Official phpMyAdmin Docker image" \ org.opencontainers.image.url="https://github.com/phpmyadmin/docker#readme" \ org.opencontainers.image.source="https://github.com/phpmyadmin/docker.git" -# Download tarball, verify it using gpg and extract +# Copy the kit built from the signed release tag +COPY --chown=www-data:www-data --from=phpmyadmin-kit /kit/ /var/www/html/ + RUN set -ex; \ \ - export GNUPGHOME="$(mktemp -d)"; \ - export GPGKEY="3D06A59ECE730EB71B511C17CE752F178259BD92"; \ - curl -fsSL -o phpMyAdmin.tar.xz $URL; \ - curl -fsSL -o phpMyAdmin.tar.xz.asc $URL.asc; \ - echo "$SHA256 *phpMyAdmin.tar.xz" | sha256sum -c -; \ - gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$GPGKEY" \ - || gpg --batch --keyserver pgp.mit.edu --recv-keys "$GPGKEY" \ - || gpg --batch --keyserver keyserver.pgp.com --recv-keys "$GPGKEY" \ - || gpg --batch --keyserver keys.openpgp.org --recv-keys "$GPGKEY"; \ - gpg --batch --verify phpMyAdmin.tar.xz.asc phpMyAdmin.tar.xz; \ - tar -xf phpMyAdmin.tar.xz -C /var/www/html --strip-components=1; \ mkdir -p /var/www/html/tmp; \ - gpgconf --kill all; \ - rm -r "$GNUPGHOME" phpMyAdmin.tar.xz phpMyAdmin.tar.xz.asc; \ rm -r -v /var/www/html/setup/ /var/www/html/examples/ /var/www/html/js/src/ /var/www/html/babel.config.json /var/www/html/doc/html/_sources/ /var/www/html/RELEASE-DATE-$VERSION /var/www/html/CONTRIBUTING.md; \ grep -q -F "'configFile' => ROOT_PATH . 'config.inc.php'," /var/www/html/libraries/vendor_config.php; \ sed -i "s@'configFile' => .*@'configFile' => '/etc/phpmyadmin/config.inc.php',@" /var/www/html/libraries/vendor_config.php; \ diff --git a/fpm/Dockerfile b/fpm/Dockerfile index 4b6fc4b9..7defa52e 100644 --- a/fpm/Dockerfile +++ b/fpm/Dockerfile @@ -1,4 +1,82 @@ # DO NOT EDIT: created by update.sh from Dockerfile-debian.template +# Build the release kit from the signed release tag instead of downloading it, so +# that the dependencies are locked for the PHP version of this image and can be +# updated to fix vulnerabilities for the lifetime of the version. +# See https://github.com/phpmyadmin/docker/issues/472 +FROM --platform=$BUILDPLATFORM php:8.3-cli-trixie AS phpmyadmin-kit + +ENV PMA_VERSION="5.2.3" \ + PMA_BRANCH="QA_5_2" \ + PMA_TAG="RELEASE_5_2_3" \ + PMA_COMMIT="962857e4f63d42e38f11ff4d63f5e722018add76" \ + PMA_GPG_KEY="3D06A59ECE730EB71B511C17CE752F178259BD92" \ + COREPACK_ENABLE_DOWNLOAD_PROMPT="0" + +# Official image, so no installer is downloaded from getcomposer.org +COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer + +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + gettext \ + git \ + gnupg \ + libfreetype6-dev \ + libjpeg62-turbo-dev \ + libpng-dev \ + libzip-dev \ + make \ + nodejs \ + python3-sphinx \ + xz-utils \ + ; \ + docker-php-ext-install gd mysqli zip; \ + corepack enable; \ + rm -rf /var/lib/apt/lists/*; \ + echo 'memory_limit = 512M' > "$PHP_INI_DIR/conf.d/zz-build.ini" + +# The release tag must be signed by the phpMyAdmin release key and point at the +# commit pinned in the generated Dockerfile +RUN set -eux; \ + git init /src; \ + cd /src; \ + git remote add origin https://github.com/phpmyadmin/phpmyadmin.git; \ + git fetch --depth 1 origin "refs/tags/${PMA_TAG}:refs/tags/${PMA_TAG}"; \ + test "$(git rev-parse "${PMA_TAG}^{commit}")" = "$PMA_COMMIT"; \ + export GNUPGHOME="$(mktemp -d)"; \ + gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$PMA_GPG_KEY" \ + || gpg --batch --keyserver pgp.mit.edu --recv-keys "$PMA_GPG_KEY" \ + || gpg --batch --keyserver keyserver.pgp.com --recv-keys "$PMA_GPG_KEY" \ + || gpg --batch --keyserver keys.openpgp.org --recv-keys "$PMA_GPG_KEY" \ + ; \ + gpg --batch --with-colons --list-keys "$PMA_GPG_KEY" | grep -q "^fpr:.*:${PMA_GPG_KEY}:"; \ + git verify-tag --raw "$PMA_TAG" > /tmp/verify-tag.log 2>&1; \ + ! grep -qE "REVKEYSIG|EXPKEYSIG|EXPSIG|BADSIG|ERRSIG" /tmp/verify-tag.log; \ + grep -qE "^\[GNUPG:\] VALIDSIG [0-9A-F]+ [0-9-]+ [0-9]+ .*${PMA_GPG_KEY}( |$)" /tmp/verify-tag.log; \ + git checkout -B "$PMA_BRANCH" "$PMA_COMMIT"; \ + gpgconf --kill all; \ + rm -r "$GNUPGHOME" + +# create-release.sh locks the dependencies for the minimum PHP version it +# parses out of composer.json, lock them for the one of this image instead +RUN set -eux; \ + cd /src; \ + php_version="$(php -r 'echo PHP_VERSION;')"; \ + sed -i "s|^PHP_REQ=.*|PHP_REQ=\"${php_version}\"|" scripts/create-release.sh; \ + grep -q "^PHP_REQ=\"${php_version}\"$" scripts/create-release.sh; \ + echo y | ./scripts/create-release.sh "$PMA_VERSION" "$PMA_BRANCH" \ + --kits all-languages --compressions txz --no-sign; \ + sha256sum "/src/release/phpMyAdmin-${PMA_VERSION}-all-languages.tar.xz" + +# Show the advisories left in the kit that actually ships +RUN set -eux; \ + mkdir -p /kit; \ + tar -xf "/src/release/phpMyAdmin-${PMA_VERSION}-all-languages.tar.xz" -C /kit --strip-components=1; \ + cd /kit; \ + composer --version; \ + composer audit --no-dev --format=table || true + FROM php:8.3-fpm ENV UPLOAD_PROGRESS_EXT_URL="https://github.com/php/pecl-php-uploadprogress/archive/refs/tags/uploadprogress-2.0.2.tar.gz" @@ -8,10 +86,6 @@ ENV UPLOAD_PROGRESS_SHA256="fe3f6cdfcedad563c970c4fd1cda31e422cfc0df5cc9a217d8c8 RUN set -ex; \ \ apt-get update; \ - apt-get install -y --no-install-recommends \ - gnupg \ - dirmngr \ - ; \ \ savedAptMark="$(apt-mark showmanual)"; \ \ @@ -105,10 +179,8 @@ RUN set -ex; \ USER www-data:www-data -# Calculate download URL +# Version of phpMyAdmin built above ENV VERSION=5.2.3 -ENV SHA256=57881348297c4412f86c410547cf76b4d8a236574dd2c6b7d6a2beebe7fc44e3 -ENV URL=https://files.phpmyadmin.net/phpMyAdmin/${VERSION}/phpMyAdmin-${VERSION}-all-languages.tar.xz LABEL org.opencontainers.image.title="Official phpMyAdmin Docker image" \ org.opencontainers.image.description="Run phpMyAdmin with Alpine, Apache and PHP FPM." \ @@ -120,22 +192,11 @@ LABEL org.opencontainers.image.title="Official phpMyAdmin Docker image" \ org.opencontainers.image.url="https://github.com/phpmyadmin/docker#readme" \ org.opencontainers.image.source="https://github.com/phpmyadmin/docker.git" -# Download tarball, verify it using gpg and extract +# Copy the kit built from the signed release tag +COPY --chown=www-data:www-data --from=phpmyadmin-kit /kit/ /var/www/html/ + RUN set -ex; \ - export GNUPGHOME="$(mktemp -d)"; \ - export GPGKEY="3D06A59ECE730EB71B511C17CE752F178259BD92"; \ - curl -fsSL -o phpMyAdmin.tar.xz $URL; \ - curl -fsSL -o phpMyAdmin.tar.xz.asc $URL.asc; \ - echo "$SHA256 *phpMyAdmin.tar.xz" | sha256sum -c -; \ - gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$GPGKEY" \ - || gpg --batch --keyserver pgp.mit.edu --recv-keys "$GPGKEY" \ - || gpg --batch --keyserver keyserver.pgp.com --recv-keys "$GPGKEY" \ - || gpg --batch --keyserver keys.openpgp.org --recv-keys "$GPGKEY"; \ - gpg --batch --verify phpMyAdmin.tar.xz.asc phpMyAdmin.tar.xz; \ - tar -xf phpMyAdmin.tar.xz -C /var/www/html --strip-components=1; \ mkdir -p /var/www/html/tmp; \ - gpgconf --kill all; \ - rm -r "$GNUPGHOME" phpMyAdmin.tar.xz phpMyAdmin.tar.xz.asc; \ rm -r -v /var/www/html/setup/ /var/www/html/examples/ /var/www/html/js/src/ /var/www/html/babel.config.json /var/www/html/doc/html/_sources/ /var/www/html/RELEASE-DATE-$VERSION /var/www/html/CONTRIBUTING.md; \ grep -q -F "'configFile' => ROOT_PATH . 'config.inc.php'," /var/www/html/libraries/vendor_config.php; \ sed -i "s@'configFile' => .*@'configFile' => '/etc/phpmyadmin/config.inc.php',@" /var/www/html/libraries/vendor_config.php; \ diff --git a/generate-stackbrew-library.sh b/generate-stackbrew-library.sh index 09074e82..28b16d51 100755 --- a/generate-stackbrew-library.sh +++ b/generate-stackbrew-library.sh @@ -18,29 +18,72 @@ dirCommit() { Dockerfile \ $(git show HEAD:./Dockerfile | awk ' toupper($1) == "COPY" { + # a file taken from another build stage is not in the repository + from = 0 + for (i = 2; i <= NF; i++) { + if ($i ~ /^--from=/) { + from = 1 + } + } + if (from) { + next + } + # the last argument is the destination, the options are not paths for (i = 2; i < NF; i++) { - print $i + if ($i !~ /^-/) { + print $i + } } } ') ) } +# the image of the final FROM instruction, without its options +finalFrom() { + awk ' + toupper($1) == "FROM" { + image = "" + for (i = 2; i <= NF; i++) { + if ($i !~ /^-/ && toupper($i) != "AS") { + image = $i + break + } + } + } + END { + if (image != "") { + print image + } + } + ' "$1" +} + getArches() { local repo="$1"; shift local officialImagesUrl='https://github.com/docker-library/official-images/raw/master/library/' eval "declare -A -g parentRepoToArches=( $( find -name 'Dockerfile' -exec awk ' - toupper($1) == "FROM" && $2 !~ /^('"$repo"'|scratch|.*\/.*)(:|$)/ { - print "'"$officialImagesUrl"'" $2 + toupper($1) == "FROM" { + image = "" + for (i = 2; i <= NF; i++) { + if ($i !~ /^-/ && toupper($i) != "AS") { + image = $i + break + } + } } - ' '{}' + \ + END { + if (image != "" && image !~ /^('"$repo"'|scratch|.*\/.*)(:|$)/) { + print "'"$officialImagesUrl"'" image + } + } + ' '{}' \; \ | sort -u \ | xargs bashbrew cat --format '[{{ .RepoName }}:{{ .TagName }}]="{{ join " " .TagEntry.Architectures }}"' ) )" } -getArches 'phpmyadmin' if ! command -v bashbrew --version &> /dev/null then @@ -49,6 +92,8 @@ then exit 1 fi +getArches 'phpmyadmin' + cat <<-EOH # This file is generated via https://github.com/phpmyadmin/docker/blob/$(fileCommit "$self")/$self Maintainers: Isaac Bennetch (@ibennetch), @@ -63,7 +108,7 @@ join() { echo "${out#$sep}" } -latest="$(curl -fsSL 'https://www.phpmyadmin.net/home_page/version.json' | jq -r '.version' | grep -E '^[0-9]{1,}.[0-9]{1,}.[0-9]{1,}$')" +latest="$(curl -fsSL 'https://www.phpmyadmin.net/home_page/version.json' | jq -r '.version' | grep -E '^[0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?$')" for variant in apache fpm fpm-alpine; do commit="$(dirCommit "$variant")" @@ -81,7 +126,7 @@ for variant in apache fpm fpm-alpine; do variantAliases+=( "${versionAliases[@]}" ) fi - variantParent="$(awk 'toupper($1) == "FROM" { print $2 }' "$variant/Dockerfile")" + variantParent="$(finalFrom "$variant/Dockerfile")" variantArches="${parentRepoToArches[$variantParent]}" diff --git a/update.sh b/update.sh index 15f3da11..76f798a0 100755 --- a/update.sh +++ b/update.sh @@ -29,17 +29,73 @@ function download_url() { echo "https://files.phpmyadmin.net/phpMyAdmin/$1/phpMyAdmin-$1-all-languages.tar.xz" } +# Commit the signed release tag points at; the Dockerfiles build from it +# Release tags are RELEASE___[_], the format the +# daily-composer script of phpmyadmin/scripts relies on to process releases +release_tag_re='RELEASE_[0-9]+_[0-9]+_[0-9]+(_[0-9]+)?' + +# The version 5.2.3 is released as the tag RELEASE_5_2_3 +function release_tag() { + local version="$1" + local tag="RELEASE_${version//./_}" + + if ! grep -qE "^${release_tag_re}$" <<< "$tag"; then + echo >&2 "'$version' does not match the release tag format $release_tag_re. Aborting." + exit 1 + fi + + echo "$tag" +} + +function release_commit() { + local tag="$1" + local repo='https://github.com/phpmyadmin/phpmyadmin.git' + local tags commit + + if ! grep -qE "refs/tags/${release_tag_re}$" <<< "refs/tags/${tag}"; then + echo >&2 "'$tag' does not match the release tag format $release_tag_re. Aborting." + exit 1 + fi + + # One request, so the known tags can be listed when this one is missing + tags="$(git ls-remote --tags "$repo")" || exit 1 + + if ! grep -qE "refs/tags/${tag}$" <<< "$tags"; then + echo >&2 "Unable to find the tag $tag in $repo. The latest release tags are:" >&2 + grep -oE "refs/tags/${release_tag_re}$" <<< "$tags" \ + | sed -e 's@refs/tags/@@' \ + | sort -t_ -k2,2n -k3,3n -k4,4n -k5,5n \ + | tail -n 5 >&2 + exit 1 + fi + + # An annotated tag is listed twice, the tag object and its peeled commit + commit="$(grep -E "refs/tags/${tag}\^\{\}$" <<< "$tags" | cut -f1)" + if [ -z "$commit" ]; then + commit="$(grep -E "refs/tags/${tag}$" <<< "$tags" | cut -f1)" + fi + if [ -z "$commit" ]; then + echo >&2 "Unable to resolve the commit of $tag in $repo. Aborting." + exit 1 + fi + + echo "$commit" +} + function create_variant() { local variant="$1" local version="$2" - local sha256="$3" - local branch="$(sed -ne 's/^\([0-9]*\.[0-9]*\)\..*$/\1/p' <<< "$version")" - local url="$(download_url "$version")" - local ascUrl="$(download_url "$version").asc" + local branch + branch="$(sed -ne 's/^\([0-9]*\.[0-9]*\)\..*$/\1/p' <<< "$version")" local phpVersion="${php_version[$version]-${php_version[default]}}" + local tag + local releaseBranch="QA_${branch//./_}" + local commit + tag="$(release_tag "$version")" + commit="$(release_commit "$tag")" - echo "updating $version [$branch] $variant" + echo "updating $version [$branch] $variant (tag $tag, commit $commit)" # Create the variant directory with a Dockerfile mkdir -p "$variant" @@ -52,11 +108,11 @@ function create_variant() { sed -ri -e ' s/%%VARIANT%%/'"$variant"'/; s/%%VERSION%%/'"$version"'/; - s/%%SHA256%%/'"$sha256"'/; - s/%%DOWNLOAD_URL%%/'"$(sed -e 's/[\/&]/\\&/g' <<< "$url")"'/; - s/%%DOWNLOAD_URL_ASC%%/'"$(sed -e 's/[\/&]/\\&/g' <<< "$ascUrl")"'/; s/%%PHP_VERSION%%/'"$phpVersion"'/g; s/%%GPG_KEY%%/'"$gpg_key"'/g; + s/%%RELEASE_BRANCH%%/'"$releaseBranch"'/g; + s/%%TAG%%/'"$tag"'/g; + s/%%PMA_COMMIT%%/'"$commit"'/g; s/%%CMD%%/'"${cmd[$variant]}"'/; ' "$variant/Dockerfile" @@ -70,32 +126,18 @@ function create_variant() { # Copy config.inc.php and helpers.php cp config.inc.php "$variant/config.inc.php" cp helpers.php "$variant/helpers.php" - - # Add variant to versions.json - versionVariantsJson="$(jq -e \ - --arg branch "$branch" --arg variant "$variant" --arg base "${base[$variant]}" --arg phpVersion "$phpVersion" \ - '.[$branch].variants[$variant] = {"variant": $variant, "base": $base, "phpVersion": $phpVersion}' versions.json)" - versionJson="$(jq -e \ - --arg branch "$branch" --arg version "$version" --arg sha256 "$sha256" --arg url "$url" --arg ascUrl "$ascUrl" --argjson variants "$versionVariantsJson" \ - '.[$branch] = {"branch": $branch, "version": $version, "sha256": $sha256, "url": $url, "ascUrl": $ascUrl, "variants": $variants[$branch].variants}' versions.json)" - printf '%s\n' "$versionJson" > versions.json } # Check script dependencies command -v curl >/dev/null 2>&1 || { echo >&2 "'curl' is required but not found. Aborting."; exit 1; } +command -v git >/dev/null 2>&1 || { echo >&2 "'git' is required but not found. Aborting."; exit 1; } command -v jq >/dev/null 2>&1 || { echo >&2 "'jq' is required but not found. Aborting."; exit 1; } [ -n "${BASH_VERSINFO}" ] && [ -n "${BASH_VERSINFO[0]}" ] && [ ${BASH_VERSINFO[0]} -ge 4 ] \ || { echo >&2 "Bash 4.0 or greater is required. Aborting."; exit 1; } # Create variants -printf '%s\n' "{}" > versions.json - -latest="$(curl -fsSL 'https://www.phpmyadmin.net/home_page/version.json' | jq -r '.version' | grep -E '^[0-9]{1,}.[0-9]{1,}.[0-9]{1,}$')" -sha256="$(curl -fsSL "$(download_url "$latest").sha256" | cut -f1 -d ' ' | tr -cd 'a-f0-9' | cut -c 1-64)" - +latest="$(curl -fsSL 'https://www.phpmyadmin.net/home_page/version.json' | jq -r '.version' | grep -E '^[0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?$')" for variant in "${variants[@]}"; do - create_variant "$variant" "$latest" "$sha256" + create_variant "$variant" "$latest" done -# Cleanup the file as for now it's not wanted in the repository -rm versions.json