From 1f893e6029bfb8ac4f0751e83e030d3103124883 Mon Sep 17 00:00:00 2001 From: Dave Miller Date: Wed, 10 Dec 2025 20:31:39 -0500 Subject: [PATCH 01/13] Clean up docker configs, run tests locally easier --- .github/workflows/ci.yml | 23 ++++-- .github/workflows/release.yml | 73 ------------------- ....test.yml => docker-compose.test-mysql.yml | 0 docker/gen-cpanfile-snapshot.sh | 8 +- docker/gen-docker-image.sh | 2 +- docker/images/Dockerfile.release-test | 45 ++++++++++++ docker/run-tests-in-docker.sh | 44 ++++++++++- 7 files changed, 110 insertions(+), 85 deletions(-) delete mode 100644 .github/workflows/release.yml rename docker-compose.test.yml => docker-compose.test-mysql.yml (100%) create mode 100644 docker/images/Dockerfile.release-test diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b3fa4fe03..aba355bb4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,9 +20,9 @@ jobs: - name: Install docker-compose run: sudo apt-get update && sudo apt-get install -y docker-compose - name: Build the Docker images - run: docker compose -f docker-compose.test.yml build + run: docker compose -f docker-compose.test-mysql.yml build - name: Run sanity tests - run: docker compose -f docker-compose.test.yml run --no-deps bugzilla6.test test_sanity t/*.t extensions/*/t/*.t + run: docker compose -f docker-compose.test-mysql.yml run --no-deps bugzilla6.test test_sanity t/*.t extensions/*/t/*.t # test_webservices: # runs-on: ubuntu-latest @@ -31,9 +31,9 @@ jobs: # - name: Install docker-compose # run: sudo apt-get update && sudo apt-get install -y docker-compose # - name: Build the Docker images -# run: docker compose -f docker-compose.test.yml build +# run: docker compose -f docker-compose.test-mysql.yml build # - name: Run webservice tests -# run: docker compose -f docker-compose.test.yml run bugzilla6.test test_webservices +# run: docker compose -f docker-compose.test-mysql.yml run bugzilla6.test test_webservices test_bugzilla6_mysql: runs-on: ubuntu-latest @@ -42,9 +42,9 @@ jobs: - name: Install docker-compose run: sudo apt-get update && sudo apt-get install -y docker-compose - name: Build the Docker images - run: docker compose -f docker-compose.test.yml build + run: docker compose -f docker-compose.test-mysql.yml build - name: Run bmo specific tests - run: docker compose -f docker-compose.test.yml run -e CI=1 bugzilla6.test test_bmo -q -f t/bmo/*.t + run: docker compose -f docker-compose.test-mysql.yml run -e CI=1 bugzilla6.test test_bmo -q -f t/bmo/*.t test_bugzilla6_mariadb: runs-on: ubuntu-latest @@ -79,3 +79,14 @@ jobs: - name: Run bmo specific tests run: docker compose -f docker-compose.test-sqlite.yml run -e CI=1 bugzilla6.test test_bmo -q -f t/bmo/*.t + test_release: + name: Release Tests on Ubuntu 24.04 + runs-on: ubuntu-latest + steps: + - name: Checkout the repository + uses: actions/checkout@v4 + - name: Build Docker image + run: docker build -t bugzilla-release-test -f docker/images/Dockerfile.release-test . + - name: Run tests + run: docker run --rm bugzilla-release-test + diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 97a8af1d7..000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,73 +0,0 @@ -# This is a basic workflow to help you get started with Actions - -name: Release Tests - -# Controls when the action will run. Triggers the workflow on push or pull request -# events but only for the main branch -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - ubuntu: - name: Release Tests on Ubuntu 24.04 - runs-on: ubuntu-24.04 - steps: - - name: Checkout the repository - uses: actions/checkout@v4 - - name: Cache CPAN packages - uses: actions/cache@v4 - with: - path: | - ~/.perl-cpm/cache - ~/.perl-cpm/builds - **/local/ - key: ${{ runner.os }}-ubuntu-24.04 - restore-keys: | - ${{ runner.os }}-ubuntu-24.04 - - name: apt install - run: | - sudo apt-get update - sudo apt-get -y dist-upgrade - sudo apt-get install --ignore-hold --allow-downgrades -y \ - apache2 \ - cpanminus \ - mariadb-client \ - netcat-traditional \ - build-essential \ - libapache2-mod-perl2 \ - libapache2-mod-perl2-dev \ - libgd3 \ - libgd-dev \ - perlmagick \ - graphviz \ - curl libssl-dev zlib1g-dev openssl \ - libexpat-dev cmake git libcairo-dev \ - unzip wget - - name: Run Makefile.PL - run: | - perl Makefile.PL - cpanm --notest --quiet --local-lib="$GITHUB_WORKSPACE/.github/cpm/lib/perl5" Module::CPANfile - make cpanfile GEN_CPANFILE_ARGS='-A -U oracle' - - name: cpm install - run: | - perl -I"$GITHUB_WORKSPACE/.github/cpm/lib/perl5" "$GITHUB_WORKSPACE/.github/cpm/bin/cpm" install \ - && tar -C "$GITHUB_WORKSPACE" \ - --exclude 'local/cache/*' \ - --exclude 'local/man/*' \ - --exclude '*.pod' \ - -zcvf local-lib.tar.gz local - - name: Save dependencies - uses: actions/upload-artifact@v4 - with: - name: ubuntu-24.04-local-lib.tar.gz - path: local-lib.tar.gz - - name: Run checksetup - run: 'perl checksetup.pl --no-database --default-localconfig --no-templates' - - name: Run tests - run: 'prove -Ilocal/lib/perl5 t' diff --git a/docker-compose.test.yml b/docker-compose.test-mysql.yml similarity index 100% rename from docker-compose.test.yml rename to docker-compose.test-mysql.yml diff --git a/docker/gen-cpanfile-snapshot.sh b/docker/gen-cpanfile-snapshot.sh index 38676b4cc..5c628f0bb 100644 --- a/docker/gen-cpanfile-snapshot.sh +++ b/docker/gen-cpanfile-snapshot.sh @@ -6,10 +6,16 @@ # This Source Code Form is "Incompatible With Secondary Licenses", as # defined by the Mozilla Public License, v. 2.0. +if [ ! -e 'Makefile.PL' ]; then + echo + echo "Please run this from the root of the Bugzilla source tree." + echo + exit -1 +fi if [ -z "$DOCKER" ]; then DOCKER=`which docker` fi -if [ ! -x "$DOCKER" ]; then +if [ -n "$DOCKER" ] && [ ! -x "$DOCKER" ]; then echo echo "You specified a custom Docker executable via the DOCKER" echo "environment variable at $DOCKER" diff --git a/docker/gen-docker-image.sh b/docker/gen-docker-image.sh index 1268d23d2..218869e3e 100755 --- a/docker/gen-docker-image.sh +++ b/docker/gen-docker-image.sh @@ -15,7 +15,7 @@ fi if [ -z "$DOCKER" ]; then DOCKER=`which docker` fi -if [ ! -x "$DOCKER" ]; then +if [ -n "$DOCKER" ] && [ ! -x "$DOCKER" ]; then echo echo "You specified a custom Docker executable via the DOCKER" echo "environment variable at $DOCKER" diff --git a/docker/images/Dockerfile.release-test b/docker/images/Dockerfile.release-test new file mode 100644 index 000000000..f375e8124 --- /dev/null +++ b/docker/images/Dockerfile.release-test @@ -0,0 +1,45 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +FROM ubuntu:24.04 + +WORKDIR /app + +# Install system dependencies +RUN apt-get update && apt-get -y dist-upgrade && \ + apt-get install --ignore-hold --allow-downgrades -y \ + apache2 \ + cpanminus \ + mariadb-client \ + netcat-traditional \ + build-essential \ + libapache2-mod-perl2 \ + libapache2-mod-perl2-dev \ + libgd3 \ + libgd-dev \ + perlmagick \ + graphviz \ + curl libssl-dev zlib1g-dev openssl \ + libexpat-dev cmake git libcairo-dev \ + unzip wget && \ + rm -rf /var/lib/apt/lists/* + +# Copy the source code +COPY . /app/ + +# Run Makefile.PL and install dependencies +RUN perl Makefile.PL && \ + cpanm --notest --quiet --local-lib="/app/local" Module::CPANfile && \ + make cpanfile GEN_CPANFILE_ARGS='-A -U oracle' && \ + cpanm --notest --quiet --local-lib="/app/local" -f --installdeps . + +# Run checksetup +RUN perl checksetup.pl --no-database --default-localconfig --no-templates + +# Set the default command to run tests +ENTRYPOINT ["prove", "-Ilocal/lib/perl5", "t"] +CMD [] diff --git a/docker/run-tests-in-docker.sh b/docker/run-tests-in-docker.sh index 592878f41..dfe14700b 100644 --- a/docker/run-tests-in-docker.sh +++ b/docker/run-tests-in-docker.sh @@ -15,7 +15,7 @@ fi if [ -z "$DOCKER" ]; then DOCKER=`which docker` fi -if [ ! -x "$DOCKER" ]; then +if [ -n "$DOCKER" ] && [ ! -x "$DOCKER" ]; then echo echo "You specified a custom Docker executable via the DOCKER" echo "environment variable at $DOCKER" @@ -51,17 +51,53 @@ export DOCKER_CLI_HINTS=false export CI="" export CIRCLE_SHA1="" export CIRCLE_BUILD_URL="" -DOCKER_COMPOSE_FILE=docker-compose.test.yml -if [ "$1" == "pg" ]; then + +TEST_NAME="test_bmo" +DOCKER_COMPOSE_FILE=docker-compose.test-mysql.yml +if [ "$#" -eq 0 ]; then + echo "Available test options:" + echo " 1) sanity - Run sanity tests" + echo " 2) mysql - Run BMO tests with MySQL (default)" + echo " 3) pg - Run BMO tests with PostgreSQL" + echo " 4) sqlite - Run BMO tests with SQLite" + echo " 5) mariadb - Run BMO tests with MariaDB" + echo " 6) release - Run release tests" + echo + read -p "Select a test option (1-6, default is mysql): " choice + case "$choice" in + 1) set -- "sanity" ;; + 2|"") set -- "mysql" ;; + 3) set -- "pg" ;; + 4) set -- "sqlite" ;; + 5) set -- "mariadb" ;; + 6) set -- "release" ;; + *) echo "Invalid choice. Using default (mysql)"; set -- "mysql" ;; + esac +fi +if [ "$1" == "sanity" ]; then + DOCKER_COMPOSE_FILE=docker-compose.test-mysql.yml + TEST_NAME="test_sanity" +elif [ "$1" == "mysql" ]; then + DOCKER_COMPOSE_FILE=docker-compose.test-mysql.yml +elif [ "$1" == "pg" ]; then DOCKER_COMPOSE_FILE=docker-compose.test-pg.yml elif [ "$1" == "sqlite" ]; then DOCKER_COMPOSE_FILE=docker-compose.test-sqlite.yml elif [ "$1" == "mariadb" ]; then DOCKER_COMPOSE_FILE=docker-compose.test-mariadb.yml +elif [ "$1" == "release" ]; then + DOCKER_FILE=docker/images/Dockerfile.release-test + $DOCKER build -t bugzilla-release-test -f $DOCKER_FILE . + if [ $? == 0 ]; then + $DOCKER run --rm bugzilla-release-test + else + echo "docker build failed." + fi + exit $? fi $DOCKER compose -f $DOCKER_COMPOSE_FILE build if [ $? == 0 ]; then - $DOCKER compose -f $DOCKER_COMPOSE_FILE run --rm --name bugzilla6.test bugzilla6.test test_bmo -q -f t/bmo/*.t + $DOCKER compose -f $DOCKER_COMPOSE_FILE run --rm --name bugzilla6.test bugzilla6.test $TEST_NAME -q -f t/bmo/*.t $DOCKER compose -f $DOCKER_COMPOSE_FILE down else echo "docker compose build failed." From 471b870e539346e4fbae2bb82b50989588328f67 Mon Sep 17 00:00:00 2001 From: Dave Miller Date: Wed, 10 Dec 2025 21:36:22 -0500 Subject: [PATCH 02/13] Better names on the tests --- .github/workflows/ci.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aba355bb4..4559a8533 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,6 +14,7 @@ on: jobs: test_sanity: + name: Sanity Tests runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -36,6 +37,7 @@ jobs: # run: docker compose -f docker-compose.test-mysql.yml run bugzilla6.test test_webservices test_bugzilla6_mysql: + name: Interactive Tests with MySQL runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -47,6 +49,7 @@ jobs: run: docker compose -f docker-compose.test-mysql.yml run -e CI=1 bugzilla6.test test_bmo -q -f t/bmo/*.t test_bugzilla6_mariadb: + name: Interactive Tests with MariaDB runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -58,6 +61,7 @@ jobs: run: docker compose -f docker-compose.test-mariadb.yml run -e CI=1 bugzilla6.test test_bmo -q -f t/bmo/*.t test_bugzilla6_pg: + name: Interactive Tests with PostgreSQL runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -69,6 +73,7 @@ jobs: run: docker compose -f docker-compose.test-pg.yml run -e CI=1 bugzilla6.test test_bmo -q -f t/bmo/*.t test_bugzilla6_sqlite: + name: Interactive Tests with SQLite runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -80,7 +85,7 @@ jobs: run: docker compose -f docker-compose.test-sqlite.yml run -e CI=1 bugzilla6.test test_bmo -q -f t/bmo/*.t test_release: - name: Release Tests on Ubuntu 24.04 + name: Perl Test Suite runs-on: ubuntu-latest steps: - name: Checkout the repository From a41dc8b3dabe0037aeed9b71ecd3c981b42501c3 Mon Sep 17 00:00:00 2001 From: Dave Miller Date: Wed, 10 Dec 2025 21:36:40 -0500 Subject: [PATCH 03/13] Make release-test actually work --- docker/images/Dockerfile.release-test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/images/Dockerfile.release-test b/docker/images/Dockerfile.release-test index f375e8124..8fdc76021 100644 --- a/docker/images/Dockerfile.release-test +++ b/docker/images/Dockerfile.release-test @@ -34,7 +34,7 @@ COPY . /app/ # Run Makefile.PL and install dependencies RUN perl Makefile.PL && \ cpanm --notest --quiet --local-lib="/app/local" Module::CPANfile && \ - make cpanfile GEN_CPANFILE_ARGS='-A -U oracle' && \ + make cpanfile GEN_CPANFILE_ARGS='-A -U oracle -U mariadb -U pg -U mysql' && \ cpanm --notest --quiet --local-lib="/app/local" -f --installdeps . # Run checksetup From 47d82eb3858b34001a10894c3fab0cb4fd699eed Mon Sep 17 00:00:00 2001 From: Dave Miller Date: Wed, 10 Dec 2025 21:38:22 -0500 Subject: [PATCH 04/13] Stop calling the one test "release tests" because they're all release tests --- .github/workflows/ci.yml | 2 +- .../{Dockerfile.release-test => Dockerfile.perl-testsuite} | 0 docker/run-tests-in-docker.sh | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename docker/images/{Dockerfile.release-test => Dockerfile.perl-testsuite} (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4559a8533..122dc5330 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -91,7 +91,7 @@ jobs: - name: Checkout the repository uses: actions/checkout@v4 - name: Build Docker image - run: docker build -t bugzilla-release-test -f docker/images/Dockerfile.release-test . + run: docker build -t bugzilla-release-test -f docker/images/Dockerfile.perl-testsuite . - name: Run tests run: docker run --rm bugzilla-release-test diff --git a/docker/images/Dockerfile.release-test b/docker/images/Dockerfile.perl-testsuite similarity index 100% rename from docker/images/Dockerfile.release-test rename to docker/images/Dockerfile.perl-testsuite diff --git a/docker/run-tests-in-docker.sh b/docker/run-tests-in-docker.sh index dfe14700b..7de607601 100644 --- a/docker/run-tests-in-docker.sh +++ b/docker/run-tests-in-docker.sh @@ -86,7 +86,7 @@ elif [ "$1" == "sqlite" ]; then elif [ "$1" == "mariadb" ]; then DOCKER_COMPOSE_FILE=docker-compose.test-mariadb.yml elif [ "$1" == "release" ]; then - DOCKER_FILE=docker/images/Dockerfile.release-test + DOCKER_FILE=docker/images/Dockerfile.perl-testsuite $DOCKER build -t bugzilla-release-test -f $DOCKER_FILE . if [ $? == 0 ]; then $DOCKER run --rm bugzilla-release-test From 20cba071f2c94bcddf13b540f61640b8828390a0 Mon Sep 17 00:00:00 2001 From: Dave Miller Date: Wed, 10 Dec 2025 21:51:42 -0500 Subject: [PATCH 05/13] Use bugzilla-perl-slim as a base image, cuts build time in half. --- docker/images/Dockerfile.perl-testsuite | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docker/images/Dockerfile.perl-testsuite b/docker/images/Dockerfile.perl-testsuite index 8fdc76021..a3b2b2964 100644 --- a/docker/images/Dockerfile.perl-testsuite +++ b/docker/images/Dockerfile.perl-testsuite @@ -5,7 +5,8 @@ # This Source Code Form is "Incompatible With Secondary Licenses", as # defined by the Mozilla Public License, v. 2.0. -FROM ubuntu:24.04 +ARG BZDB="" +FROM bugzilla/bugzilla-perl-slim${BZDB}:20250925.1 WORKDIR /app From dc5ba4cbc9a0cef52659635f1be52051d285d3c4 Mon Sep 17 00:00:00 2001 From: Dave Miller Date: Wed, 10 Dec 2025 21:57:36 -0500 Subject: [PATCH 06/13] more-accurate instructions to user in docker publish script --- docker/gen-docker-image.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/gen-docker-image.sh b/docker/gen-docker-image.sh index 218869e3e..fd822770e 100755 --- a/docker/gen-docker-image.sh +++ b/docker/gen-docker-image.sh @@ -79,7 +79,7 @@ select IMAGE in $FILES; do if [ $? == 0 ]; then echo echo "The build appears to have succeeded. Don't forget to change the FROM line" - echo "at the top of Dockerfile to use:" + echo "at the top of Dockerfile and each of docker/Dockerfile.* to use:" echo " bugzilla/${IMAGE}:${DATE}.${ITER}" echo "to make use of this image." echo From de47fad13efa4884232b4de9e1720f33a77a1238 Mon Sep 17 00:00:00 2001 From: Dave Miller Date: Wed, 10 Dec 2025 22:00:17 -0500 Subject: [PATCH 07/13] Additional idiot-proofing in instructions of Docker publish script --- docker/gen-docker-image.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker/gen-docker-image.sh b/docker/gen-docker-image.sh index fd822770e..994caede8 100755 --- a/docker/gen-docker-image.sh +++ b/docker/gen-docker-image.sh @@ -108,6 +108,8 @@ select IMAGE in $FILES; do *) echo "Not pushing. You can just run this script again when you're ready" echo "to push. The prior build result is cached." + echo "Remember NOT to commit any changes to the FROM lines of Dockerfiles until" + echo "you've pushed to DockerHub." ;; esac fi From d7626a1797c29e591e5506e534ffac8a37c424f6 Mon Sep 17 00:00:00 2001 From: Dave Miller Date: Wed, 10 Dec 2025 22:16:23 -0500 Subject: [PATCH 08/13] Automatically update the Dockerfiles to use newly built images --- .gitignore | 1 + docker/gen-docker-image.sh | 24 ++++++++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index c22c12e75..f64bec8dd 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,7 @@ version.json __lbheartbeat__ .perl-version +*.bak /skins/contrib/Dusk/admin.css /skins/contrib/Dusk/bug.css diff --git a/docker/gen-docker-image.sh b/docker/gen-docker-image.sh index 994caede8..83ab1b6b0 100755 --- a/docker/gen-docker-image.sh +++ b/docker/gen-docker-image.sh @@ -78,11 +78,27 @@ select IMAGE in $FILES; do $DOCKER build $CACHE -t bugzilla/${IMAGE}:${DATE}.${ITER} -f docker/images/Dockerfile.${IMAGE} . if [ $? == 0 ]; then echo - echo "The build appears to have succeeded. Don't forget to change the FROM line" - echo "at the top of Dockerfile and each of docker/Dockerfile.* to use:" - echo " bugzilla/${IMAGE}:${DATE}.${ITER}" - echo "to make use of this image." + echo "The build appears to have succeeded." + echo "Updating FROM lines in Dockerfiles to use bugzilla/${IMAGE}:${DATE}.${ITER}..." echo + + # Update all Dockerfiles that reference this image + for dockerfile in Dockerfile docker/images/Dockerfile.*; do + if [ -f "$dockerfile" ]; then + # Check for both direct references and BZDB variable references + if grep -q "FROM bugzilla/${IMAGE}:" "$dockerfile" || grep -q "FROM bugzilla/${IMAGE}\${BZDB}:" "$dockerfile"; then + # Create a backup + cp "$dockerfile" "${dockerfile}.bak" + # Update the FROM line - handle both direct and BZDB variable patterns + sed -i.tmp "s|FROM bugzilla/${IMAGE}:[^ ]*|FROM bugzilla/${IMAGE}:${DATE}.${ITER}|g" "$dockerfile" + sed -i.tmp "s|FROM bugzilla/${IMAGE}\${BZDB}:[^ ]*|FROM bugzilla/${IMAGE}\${BZDB}:${DATE}.${ITER}|g" "$dockerfile" + rm -f "${dockerfile}.tmp" + echo " Updated: $dockerfile" + fi + fi + done + echo + # check if the user is logged in if [ -z "$PYTHON" ]; then PYTHON=`which python` From 35d51acd22a168e3d3e9abdacc49bd3f51470c26 Mon Sep 17 00:00:00 2001 From: Dave Miller Date: Wed, 10 Dec 2025 22:29:20 -0500 Subject: [PATCH 09/13] fix syntax on ENV directive in Dockerfiles --- Dockerfile | 2 +- docker/images/Dockerfile.bugzilla-perl-slim | 2 +- docker/images/Dockerfile.bugzilla-perl-slim-mariadb | 2 +- docker/images/Dockerfile.bugzilla-perl-slim-mysql | 2 +- docker/images/Dockerfile.bugzilla-perl-slim-pg | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index 85a88cd97..1f3858599 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ ARG BZDB="-mysql" FROM bugzilla/bugzilla-perl-slim${BZDB}:20250925.1 -ENV DEBIAN_FRONTEND noninteractive +ENV DEBIAN_FRONTEND=noninteractive ENV LOG4PERL_CONFIG_FILE=log4perl-json.conf diff --git a/docker/images/Dockerfile.bugzilla-perl-slim b/docker/images/Dockerfile.bugzilla-perl-slim index bd4258ed0..d9d0692c1 100644 --- a/docker/images/Dockerfile.bugzilla-perl-slim +++ b/docker/images/Dockerfile.bugzilla-perl-slim @@ -43,7 +43,7 @@ RUN find local -name '*.so' -exec ldd {} \; \ FROM perl:5.38.2-slim -ENV DEBIAN_FRONTEND noninteractive +ENV DEBIAN_FRONTEND=noninteractive COPY --from=builder /app/local /app/local COPY --from=builder /app/PACKAGES /app/PACKAGES diff --git a/docker/images/Dockerfile.bugzilla-perl-slim-mariadb b/docker/images/Dockerfile.bugzilla-perl-slim-mariadb index d5acd77fe..d4b7e6642 100644 --- a/docker/images/Dockerfile.bugzilla-perl-slim-mariadb +++ b/docker/images/Dockerfile.bugzilla-perl-slim-mariadb @@ -40,7 +40,7 @@ RUN find local -name '*.so' -exec ldd {} \; \ FROM bugzilla/bugzilla-perl-slim:20250925.1 -ENV DEBIAN_FRONTEND noninteractive +ENV DEBIAN_FRONTEND=noninteractive COPY --from=builder /app/local /app/local COPY --from=builder /app/PACKAGES /app/PACKAGES diff --git a/docker/images/Dockerfile.bugzilla-perl-slim-mysql b/docker/images/Dockerfile.bugzilla-perl-slim-mysql index a807fca41..64562cec7 100644 --- a/docker/images/Dockerfile.bugzilla-perl-slim-mysql +++ b/docker/images/Dockerfile.bugzilla-perl-slim-mysql @@ -50,7 +50,7 @@ RUN find local -name '*.so' -exec ldd {} \; \ FROM bugzilla/bugzilla-perl-slim:20250925.1 -ENV DEBIAN_FRONTEND noninteractive +ENV DEBIAN_FRONTEND=noninteractive COPY --from=builder /app/local /app/local COPY --from=builder /app/PACKAGES /app/PACKAGES diff --git a/docker/images/Dockerfile.bugzilla-perl-slim-pg b/docker/images/Dockerfile.bugzilla-perl-slim-pg index d2fe4b575..3601a0d4e 100644 --- a/docker/images/Dockerfile.bugzilla-perl-slim-pg +++ b/docker/images/Dockerfile.bugzilla-perl-slim-pg @@ -51,7 +51,7 @@ RUN find local -name '*.so' -exec ldd {} \; \ # developer tools FROM bugzilla/bugzilla-perl-slim:20250925.1 -ENV DEBIAN_FRONTEND noninteractive +ENV DEBIAN_FRONTEND=noninteractive # copy the stuff we built over from the temporary image COPY --from=builder /app/local /app/local From 7c59c526ea4e464382cdf33dbdaeaa7e65410a06 Mon Sep 17 00:00:00 2001 From: Dave Miller Date: Wed, 10 Dec 2025 23:45:03 -0500 Subject: [PATCH 10/13] Lots of cleanup to docker-related scripts --- docker/common.sh | 78 ++++++++++ docker/gen-cpanfile-snapshot.sh | 44 +----- docker/gen-docker-image.sh | 244 ++++++++++++++++++-------------- docker/run-tests-in-docker.sh | 43 +----- 4 files changed, 217 insertions(+), 192 deletions(-) create mode 100644 docker/common.sh diff --git a/docker/common.sh b/docker/common.sh new file mode 100644 index 000000000..a75da851c --- /dev/null +++ b/docker/common.sh @@ -0,0 +1,78 @@ +#!/bin/bash +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +################################################## +# Common checks and functions for docker scripts # +################################################## + +# Function to print text in red if terminal supports it +echo_red() { + if [ -t 1 ] && command -v tput >/dev/null 2>&1 && [ $(tput colors 2>/dev/null || echo 0) -ge 8 ]; then + echo -e "\033[31m$1\033[0m" + else + echo "$1" + fi +} + +# Function to print text in green if terminal supports it +echo_green() { + if [ -t 1 ] && command -v tput >/dev/null 2>&1 && [ $(tput colors 2>/dev/null || echo 0) -ge 8 ]; then + echo -e "\033[32m$1\033[0m" + else + echo "$1" + fi +} + +# Check that we're in the root of the Bugzilla source tree +if [ ! -e 'Makefile.PL' ]; then + echo + echo_red "Please run this from the root of the Bugzilla source tree." + echo + exit -1 +fi + +# Find and validate the Docker executable +if [ -z "$DOCKER" ]; then + DOCKER=`which docker` +fi +if [ -n "$DOCKER" ] && [ ! -x "$DOCKER" ]; then + echo + echo_red "You specified a custom Docker executable via the DOCKER" + echo_red "environment variable at $DOCKER" + echo_red "which either does not exist or is not executable." + echo "Please fix it to point at a working Docker or remove the" + echo "DOCKER environment variable to use the one in your PATH" + echo "if it exists." + echo + exit -1 +fi +if [ -z "$DOCKER" ]; then + echo + echo_red "You do not appear to have docker installed or I can't find it." + echo "Windows and Mac versions can be downloaded from" + echo "https://www.docker.com/products/docker-desktop" + echo "Linux users can install using your package manager." + echo + echo "Please install docker or specify the location of the docker" + echo "executable in the DOCKER environment variable and try again." + echo + exit -1 +fi + +# Check that Docker daemon is running +$DOCKER info 1>/dev/null 2>/dev/null +if [ $? != 0 ]; then + echo + echo_red "The docker daemon is not running or I can't connect to it." + echo "Please make sure it's running and try again." + echo + exit -1 +fi + +# Disable Docker CLI hints +export DOCKER_CLI_HINTS=false diff --git a/docker/gen-cpanfile-snapshot.sh b/docker/gen-cpanfile-snapshot.sh index 5c628f0bb..6835db3a9 100644 --- a/docker/gen-cpanfile-snapshot.sh +++ b/docker/gen-cpanfile-snapshot.sh @@ -6,46 +6,9 @@ # This Source Code Form is "Incompatible With Secondary Licenses", as # defined by the Mozilla Public License, v. 2.0. -if [ ! -e 'Makefile.PL' ]; then - echo - echo "Please run this from the root of the Bugzilla source tree." - echo - exit -1 -fi -if [ -z "$DOCKER" ]; then - DOCKER=`which docker` -fi -if [ -n "$DOCKER" ] && [ ! -x "$DOCKER" ]; then - echo - echo "You specified a custom Docker executable via the DOCKER" - echo "environment variable at $DOCKER" - echo "which either does not exist or is not executable." - echo "Please fix it to point at a working Docker or remove the" - echo "DOCKER environment variable to use the one in your PATH" - echo "if it exists." - echo - exit -1 -fi -if [ -z "$DOCKER" ]; then - echo - echo "You do not appear to have docker installed or I can't find it." - echo "Windows and Mac versions can be downloaded from" - echo "https://www.docker.com/products/docker-desktop" - echo "Linux users can install using your package manager." - echo - echo "Please install docker or specify the location of the docker" - echo "executable in the DOCKER environment variable and try again." - echo - exit -1 -fi -$DOCKER info 1>/dev/null 2>/dev/null -if [ $? != 0 ]; then - echo - echo "The docker daemon is not running or I can't connect to it." - echo "Please make sure it's running and try again." - echo - exit -1 -fi +# Source common Docker script checks and functions +source "$(dirname "$0")/common.sh" + if [ ! -f "docker/images/Dockerfile.cpanfile" ]; then echo echo "Can't locate the Dockerfile, try running from the root of" @@ -54,7 +17,6 @@ if [ ! -f "docker/images/Dockerfile.cpanfile" ]; then exit -1 fi -export DOCKER_CLI_HINTS=false $DOCKER build -t bugzilla-cpanfile -f docker/images/Dockerfile.cpanfile . $DOCKER run -it -v "$(pwd):/app/result" bugzilla-cpanfile cp cpanfile cpanfile.snapshot /app/result diff --git a/docker/gen-docker-image.sh b/docker/gen-docker-image.sh index 83ab1b6b0..98019eede 100755 --- a/docker/gen-docker-image.sh +++ b/docker/gen-docker-image.sh @@ -6,49 +6,27 @@ # This Source Code Form is "Incompatible With Secondary Licenses", as # defined by the Mozilla Public License, v. 2.0. -if [ ! -e 'Makefile.PL' ]; then - echo - echo "Please run this from the root of the Bugzilla source tree." - echo - exit -1 -fi -if [ -z "$DOCKER" ]; then - DOCKER=`which docker` -fi -if [ -n "$DOCKER" ] && [ ! -x "$DOCKER" ]; then - echo - echo "You specified a custom Docker executable via the DOCKER" - echo "environment variable at $DOCKER" - echo "which either does not exist or is not executable." - echo "Please fix it to point at a working Docker or remove the" - echo "DOCKER environment variable to use the one in your PATH" - echo "if it exists." - echo - exit -1 -fi -if [ -z "$DOCKER" ]; then - echo - echo "You do not appear to have docker installed or I can't find it." - echo "Windows and Mac versions can be downloaded from" - echo "https://www.docker.com/products/docker-desktop" - echo "Linux users can install using your package manager." - echo - echo "Please install docker or specify the location of the docker" - echo "executable in the DOCKER environment variable and try again." - echo - exit -1 -fi -$DOCKER info 1>/dev/null 2>/dev/null -if [ $? != 0 ]; then - echo - echo "The docker daemon is not running or I can't connect to it." - echo "Please make sure it's running and try again." - echo - exit -1 +# Ensure this script is run with bash +# BASH_VERSION can be set in some shells; instead, verify declare -A works. +if ! (declare -A __test_assoc 2>/dev/null); then + echo "This script requires bash. Checking if you have it..." + bash=`which bash` + if [ -n "$bash" ] && [ -x "$bash" ]; then + echo "Found bash at $bash. Re-running script with bash..." + echo + exec bash "$0" "$@" + else + echo_red "Could not find bash. Put it in your PATH and try again." + exit -1 + fi fi -FILES=`ls -1 docker/images/Dockerfile.b* | sed -e 's@^docker/images/Dockerfile\.@@'` + +# Source common Docker script checks and functions +source "$(dirname "$0")/common.sh" + +FILES=`ls -1 docker/images/Dockerfile.b* | grep -v '\.bak$' | sed -e 's@^docker/images/Dockerfile\.@@'` PS3="Choose an image to build or CTRL-C to abort: " -select IMAGE in $FILES; do +select IMAGE in "All images" $FILES; do CACHE="" if [ "$1" == "--no-cache" ]; then CACHE="--no-cache" @@ -59,81 +37,127 @@ select IMAGE in $FILES; do export CIRCLE_SHA1="" export CIRCLE_BUILD_URL="" - # Figure out the tag name to use for the image. We'll do this by generating - # a code based on today's date, then attempt to pull it from DockerHub. If - # we successfully pull, then it already exists, and we bump the interation - # number on the end. - DATE=`date +"%Y%m%d"` - ITER=1 - $DOCKER pull bugzilla/${IMAGE}:${DATE}.${ITER} >/dev/null 2>/dev/null - while [ $? == 0 ]; do - # as long as we succesfully pull, keep bumping the number on the end - ((ITER++)) + # Determine which images to build + if [ "$IMAGE" == "All images" ]; then + IMAGES_TO_BUILD=($FILES) + else + IMAGES_TO_BUILD=($IMAGE) + fi + + # Track successfully built images + declare -A BUILT_IMAGES + + for IMAGE in "${IMAGES_TO_BUILD[@]}"; do + # Figure out the tag name to use for the image. We'll do this by generating + # a code based on today's date, then attempt to pull it from DockerHub. If + # we successfully pull, then it already exists, and we bump the interation + # number on the end. + DATE=`date +"%Y%m%d"` + ITER=1 $DOCKER pull bugzilla/${IMAGE}:${DATE}.${ITER} >/dev/null 2>/dev/null - done - LINE="Building bugzilla/${IMAGE}:${DATE}.${ITER}" - echo "##${LINE//?/#}##" - echo "# ${LINE} #" - echo "##${LINE//?/#}##" - $DOCKER build $CACHE -t bugzilla/${IMAGE}:${DATE}.${ITER} -f docker/images/Dockerfile.${IMAGE} . - if [ $? == 0 ]; then - echo - echo "The build appears to have succeeded." - echo "Updating FROM lines in Dockerfiles to use bugzilla/${IMAGE}:${DATE}.${ITER}..." - echo + while [ $? == 0 ]; do + # as long as we succesfully pull, keep bumping the number on the end + ((ITER++)) + $DOCKER pull bugzilla/${IMAGE}:${DATE}.${ITER} >/dev/null 2>/dev/null + done + LINE="Building bugzilla/${IMAGE}:${DATE}.${ITER}" + echo "##${LINE//?/#}##" + echo "# ${LINE} #" + echo "##${LINE//?/#}##" + $DOCKER build $CACHE -t bugzilla/${IMAGE}:${DATE}.${ITER} -f docker/images/Dockerfile.${IMAGE} . + if [ $? == 0 ]; then + echo + echo_green "The build appears to have succeeded." - # Update all Dockerfiles that reference this image - for dockerfile in Dockerfile docker/images/Dockerfile.*; do - if [ -f "$dockerfile" ]; then - # Check for both direct references and BZDB variable references - if grep -q "FROM bugzilla/${IMAGE}:" "$dockerfile" || grep -q "FROM bugzilla/${IMAGE}\${BZDB}:" "$dockerfile"; then - # Create a backup - cp "$dockerfile" "${dockerfile}.bak" - # Update the FROM line - handle both direct and BZDB variable patterns - sed -i.tmp "s|FROM bugzilla/${IMAGE}:[^ ]*|FROM bugzilla/${IMAGE}:${DATE}.${ITER}|g" "$dockerfile" - sed -i.tmp "s|FROM bugzilla/${IMAGE}\${BZDB}:[^ ]*|FROM bugzilla/${IMAGE}\${BZDB}:${DATE}.${ITER}|g" "$dockerfile" - rm -f "${dockerfile}.tmp" - echo " Updated: $dockerfile" - fi + # Only update Dockerfiles when building the perl-slim image specifically (not variants like perl-slim-mysql) + if [[ "$IMAGE" == "bugzilla-perl-slim" ]]; then + echo "Updating FROM lines in Dockerfiles to use bugzilla/${IMAGE}:${DATE}.${ITER}..." + echo + + # Update all Dockerfiles that reference this image + for dockerfile in Dockerfile docker/images/Dockerfile.*; do + # Skip backups and temp files + case "$dockerfile" in + *.bak|*.tmp) continue ;; + esac + if [ -f "$dockerfile" ]; then + # Check for both direct references and BZDB variable references + if grep -q "FROM bugzilla/${IMAGE}:" "$dockerfile" || grep -q "FROM bugzilla/${IMAGE}\${BZDB}:" "$dockerfile"; then + # Create a backup + cp "$dockerfile" "${dockerfile}.bak" + echo " Created backup: ${dockerfile}.bak" + # Update the FROM line - handle both direct and BZDB variable patterns + sed -i.tmp "s|FROM bugzilla/${IMAGE}:[^ ]*|FROM bugzilla/${IMAGE}:${DATE}.${ITER}|g" "$dockerfile" + sed -i.tmp "s|FROM bugzilla/${IMAGE}\${BZDB}:[^ ]*|FROM bugzilla/${IMAGE}\${BZDB}:${DATE}.${ITER}|g" "$dockerfile" + rm -f "${dockerfile}.tmp" + echo " Updated: $dockerfile" + fi + fi + done + echo fi - done - echo - # check if the user is logged in - if [ -z "$PYTHON" ]; then - PYTHON=`which python` - fi - if [ -z "$PYTHON" ]; then - PYTHON=`which python3` - fi - if [ ! -x "$PYTHON" ]; then - echo "The python executable specified in your PYTHON environment value or your PATH is not executable or I can't find it." - exit -1 - fi - AUTHINFO=`$PYTHON -c "import json; print(len(json.load(open('${HOME}/.docker/config.json','r',encoding='utf-8'))['auths']))"` - if [ $AUTHINFO -gt 0 ]; then - # user is logged in - read -p "Do you wish to push to DockerHub? [y/N]: " yesno - case $yesno in - [Yy]*) - echo "Pushing..." - $DOCKER push bugzilla/${IMAGE}:${DATE}.${ITER} - $DOCKER tag bugzilla/${IMAGE}:${DATE}.${ITER} bugzilla/${IMAGE}:latest - $DOCKER push bugzilla/${IMAGE}:latest - ;; - *) - echo "Not pushing. You can just run this script again when you're ready" - echo "to push. The prior build result is cached." - echo "Remember NOT to commit any changes to the FROM lines of Dockerfiles until" - echo "you've pushed to DockerHub." - ;; - esac + # Track the successfully built image + BUILT_IMAGES["${IMAGE}"]="${DATE}.${ITER}" + else + echo + echo_red "Docker build failed for ${IMAGE}. See output above." + echo + if [ ${#IMAGES_TO_BUILD[@]} -eq 1 ]; then + exit -1 + fi fi - else - echo - echo "Docker build failed. See output above." - echo + done + + # Check if any images were built successfully + if [ ${#BUILT_IMAGES[@]} -eq 0 ]; then + echo_red "No images were built successfully." + exit -1 + fi + echo + echo_green "Successfully built ${#BUILT_IMAGES[@]} image(s):" + for img in "${!BUILT_IMAGES[@]}"; do + echo " - bugzilla/${img}:${BUILT_IMAGES[$img]}" + done + + # check if the user is logged in + if [ -z "$PYTHON" ]; then + PYTHON=`which python` + fi + if [ -z "$PYTHON" ]; then + PYTHON=`which python3` + fi + if [ ! -x "$PYTHON" ]; then + echo "The python executable specified in your PYTHON environment value or your PATH is not executable or I can't find it." exit -1 fi + AUTHINFO=`$PYTHON -c "import json; print(len(json.load(open('${HOME}/.docker/config.json','r',encoding='utf-8'))['auths']))"` + if [ $AUTHINFO -gt 0 ]; then + # user is logged in + echo + read -p "Do you wish to push to DockerHub? [y/N]: " yesno + case $yesno in + [Yy]*) + echo + echo "Pushing images..." + for img in "${!BUILT_IMAGES[@]}"; do + tag="${BUILT_IMAGES[$img]}" + echo "Pushing bugzilla/${img}:${tag}..." + $DOCKER push bugzilla/${img}:${tag} + echo "Tagging bugzilla/${img}:${tag} as bugzilla/${img}:latest..." + $DOCKER tag bugzilla/${img}:${tag} bugzilla/${img}:latest + $DOCKER push bugzilla/${img}:latest + done + echo_green "All images pushed successfully." + ;; + *) + echo + echo "Not pushing. You can just run this script again when you're ready" + echo "to push. The prior build results are cached." + echo_red "Remember DO NOT commit any changes to the FROM lines of Dockerfiles until" + echo_red "you've pushed to DockerHub. Doing so will break tests on GitHub Actions." + ;; + esac + fi break done diff --git a/docker/run-tests-in-docker.sh b/docker/run-tests-in-docker.sh index 7de607601..de9e2c139 100644 --- a/docker/run-tests-in-docker.sh +++ b/docker/run-tests-in-docker.sh @@ -6,48 +6,9 @@ # This Source Code Form is "Incompatible With Secondary Licenses", as # defined by the Mozilla Public License, v. 2.0. -if [ ! -e 'Makefile.PL' ]; then - echo - echo "Please run this from the root of the Bugzilla source tree." - echo - exit -1 -fi -if [ -z "$DOCKER" ]; then - DOCKER=`which docker` -fi -if [ -n "$DOCKER" ] && [ ! -x "$DOCKER" ]; then - echo - echo "You specified a custom Docker executable via the DOCKER" - echo "environment variable at $DOCKER" - echo "which either does not exist or is not executable." - echo "Please fix it to point at a working Docker or remove the" - echo "DOCKER environment variable to use the one in your PATH" - echo "if it exists." - echo - exit -1 -fi -if [ -z "$DOCKER" ]; then - echo - echo "You do not appear to have docker installed or I can't find it." - echo "Windows and Mac versions can be downloaded from" - echo "https://www.docker.com/products/docker-desktop" - echo "Linux users can install using your package manager." - echo - echo "Please install docker or specify the location of the docker" - echo "executable in the DOCKER environment variable and try again." - echo - exit -1 -fi -$DOCKER info 1>/dev/null 2>/dev/null -if [ $? != 0 ]; then - echo - echo "The docker daemon is not running or I can't connect to it." - echo "Please make sure it's running and try again." - echo - exit -1 -fi +# Source common Docker script checks and functions +source "$(dirname "$0")/common.sh" -export DOCKER_CLI_HINTS=false export CI="" export CIRCLE_SHA1="" export CIRCLE_BUILD_URL="" From db7af9bb4ddab85368d64ae085b7a64b832c2f83 Mon Sep 17 00:00:00 2001 From: Dave Miller Date: Tue, 16 Dec 2025 22:57:47 -0500 Subject: [PATCH 11/13] Change backticks to $() --- docker/common.sh | 2 +- docker/gen-docker-image.sh | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docker/common.sh b/docker/common.sh index a75da851c..7a6a1b988 100644 --- a/docker/common.sh +++ b/docker/common.sh @@ -38,7 +38,7 @@ fi # Find and validate the Docker executable if [ -z "$DOCKER" ]; then - DOCKER=`which docker` + DOCKER=$(which docker) fi if [ -n "$DOCKER" ] && [ ! -x "$DOCKER" ]; then echo diff --git a/docker/gen-docker-image.sh b/docker/gen-docker-image.sh index 98019eede..09dc50c0c 100755 --- a/docker/gen-docker-image.sh +++ b/docker/gen-docker-image.sh @@ -10,7 +10,7 @@ # BASH_VERSION can be set in some shells; instead, verify declare -A works. if ! (declare -A __test_assoc 2>/dev/null); then echo "This script requires bash. Checking if you have it..." - bash=`which bash` + bash=$(which bash) if [ -n "$bash" ] && [ -x "$bash" ]; then echo "Found bash at $bash. Re-running script with bash..." echo @@ -24,7 +24,7 @@ fi # Source common Docker script checks and functions source "$(dirname "$0")/common.sh" -FILES=`ls -1 docker/images/Dockerfile.b* | grep -v '\.bak$' | sed -e 's@^docker/images/Dockerfile\.@@'` +FILES=$(ls -1 docker/images/Dockerfile.b* | grep -v '\.bak$' | sed -e 's@^docker/images/Dockerfile\.@@') PS3="Choose an image to build or CTRL-C to abort: " select IMAGE in "All images" $FILES; do CACHE="" @@ -52,7 +52,7 @@ select IMAGE in "All images" $FILES; do # a code based on today's date, then attempt to pull it from DockerHub. If # we successfully pull, then it already exists, and we bump the interation # number on the end. - DATE=`date +"%Y%m%d"` + DATE=$(date +"%Y%m%d") ITER=1 $DOCKER pull bugzilla/${IMAGE}:${DATE}.${ITER} >/dev/null 2>/dev/null while [ $? == 0 ]; do @@ -122,16 +122,16 @@ select IMAGE in "All images" $FILES; do # check if the user is logged in if [ -z "$PYTHON" ]; then - PYTHON=`which python` + PYTHON=$(which python) fi if [ -z "$PYTHON" ]; then - PYTHON=`which python3` + PYTHON=$(which python3) fi if [ ! -x "$PYTHON" ]; then echo "The python executable specified in your PYTHON environment value or your PATH is not executable or I can't find it." exit -1 fi - AUTHINFO=`$PYTHON -c "import json; print(len(json.load(open('${HOME}/.docker/config.json','r',encoding='utf-8'))['auths']))"` + AUTHINFO=$($PYTHON -c "import json; print(len(json.load(open('${HOME}/.docker/config.json','r',encoding='utf-8'))['auths']))") if [ $AUTHINFO -gt 0 ]; then # user is logged in echo From 6f7e77ea2f8d936a6f3eb1f5530b813ef7870311 Mon Sep 17 00:00:00 2001 From: Dave Miller Date: Tue, 16 Dec 2025 23:37:20 -0500 Subject: [PATCH 12/13] fix errors reported by shellcheck lint --- docker/common.sh | 15 +++++++------ docker/gen-cpanfile-snapshot.sh | 3 ++- docker/gen-docker-image.sh | 37 +++++++++++++++++---------------- docker/run-tests-in-docker.sh | 19 ++++++++++------- 4 files changed, 40 insertions(+), 34 deletions(-) diff --git a/docker/common.sh b/docker/common.sh index 7a6a1b988..e0ce1fc11 100644 --- a/docker/common.sh +++ b/docker/common.sh @@ -12,7 +12,7 @@ # Function to print text in red if terminal supports it echo_red() { - if [ -t 1 ] && command -v tput >/dev/null 2>&1 && [ $(tput colors 2>/dev/null || echo 0) -ge 8 ]; then + if [ -t 1 ] && command -v tput >/dev/null 2>&1 && [ "$(tput colors 2>/dev/null || echo 0)" -ge 8 ]; then echo -e "\033[31m$1\033[0m" else echo "$1" @@ -21,7 +21,7 @@ echo_red() { # Function to print text in green if terminal supports it echo_green() { - if [ -t 1 ] && command -v tput >/dev/null 2>&1 && [ $(tput colors 2>/dev/null || echo 0) -ge 8 ]; then + if [ -t 1 ] && command -v tput >/dev/null 2>&1 && [ "$(tput colors 2>/dev/null || echo 0)" -ge 8 ]; then echo -e "\033[32m$1\033[0m" else echo "$1" @@ -33,7 +33,7 @@ if [ ! -e 'Makefile.PL' ]; then echo echo_red "Please run this from the root of the Bugzilla source tree." echo - exit -1 + exit 1 fi # Find and validate the Docker executable @@ -49,7 +49,7 @@ if [ -n "$DOCKER" ] && [ ! -x "$DOCKER" ]; then echo "DOCKER environment variable to use the one in your PATH" echo "if it exists." echo - exit -1 + exit 1 fi if [ -z "$DOCKER" ]; then echo @@ -61,17 +61,16 @@ if [ -z "$DOCKER" ]; then echo "Please install docker or specify the location of the docker" echo "executable in the DOCKER environment variable and try again." echo - exit -1 + exit 1 fi # Check that Docker daemon is running -$DOCKER info 1>/dev/null 2>/dev/null -if [ $? != 0 ]; then +if ! $DOCKER info >/dev/null 2>&1; then echo echo_red "The docker daemon is not running or I can't connect to it." echo "Please make sure it's running and try again." echo - exit -1 + exit 1 fi # Disable Docker CLI hints diff --git a/docker/gen-cpanfile-snapshot.sh b/docker/gen-cpanfile-snapshot.sh index 6835db3a9..cbca373d4 100644 --- a/docker/gen-cpanfile-snapshot.sh +++ b/docker/gen-cpanfile-snapshot.sh @@ -7,6 +7,7 @@ # defined by the Mozilla Public License, v. 2.0. # Source common Docker script checks and functions +# shellcheck source=docker/common.sh source "$(dirname "$0")/common.sh" if [ ! -f "docker/images/Dockerfile.cpanfile" ]; then @@ -14,7 +15,7 @@ if [ ! -f "docker/images/Dockerfile.cpanfile" ]; then echo "Can't locate the Dockerfile, try running from the root of" echo "your Bugzilla checkout." echo - exit -1 + exit 1 fi $DOCKER build -t bugzilla-cpanfile -f docker/images/Dockerfile.cpanfile . diff --git a/docker/gen-docker-image.sh b/docker/gen-docker-image.sh index 09dc50c0c..314720689 100755 --- a/docker/gen-docker-image.sh +++ b/docker/gen-docker-image.sh @@ -17,16 +17,20 @@ if ! (declare -A __test_assoc 2>/dev/null); then exec bash "$0" "$@" else echo_red "Could not find bash. Put it in your PATH and try again." - exit -1 + exit 1 fi fi # Source common Docker script checks and functions +# shellcheck source=docker/common.sh source "$(dirname "$0")/common.sh" -FILES=$(ls -1 docker/images/Dockerfile.b* | grep -v '\.bak$' | sed -e 's@^docker/images/Dockerfile\.@@') +FILES=() +for f in docker/images/Dockerfile.b*; do + [[ "$f" != *.bak ]] && FILES+=("${f#docker/images/Dockerfile.}") +done PS3="Choose an image to build or CTRL-C to abort: " -select IMAGE in "All images" $FILES; do +select IMAGE in "All images" "${FILES[@]}"; do CACHE="" if [ "$1" == "--no-cache" ]; then CACHE="--no-cache" @@ -39,9 +43,9 @@ select IMAGE in "All images" $FILES; do # Determine which images to build if [ "$IMAGE" == "All images" ]; then - IMAGES_TO_BUILD=($FILES) + IMAGES_TO_BUILD=("${FILES[@]}") else - IMAGES_TO_BUILD=($IMAGE) + IMAGES_TO_BUILD=("$IMAGE") fi # Track successfully built images @@ -54,18 +58,15 @@ select IMAGE in "All images" $FILES; do # number on the end. DATE=$(date +"%Y%m%d") ITER=1 - $DOCKER pull bugzilla/${IMAGE}:${DATE}.${ITER} >/dev/null 2>/dev/null - while [ $? == 0 ]; do + while $DOCKER pull "bugzilla/${IMAGE}:${DATE}.${ITER}" >/dev/null 2>/dev/null; do # as long as we succesfully pull, keep bumping the number on the end ((ITER++)) - $DOCKER pull bugzilla/${IMAGE}:${DATE}.${ITER} >/dev/null 2>/dev/null done LINE="Building bugzilla/${IMAGE}:${DATE}.${ITER}" echo "##${LINE//?/#}##" echo "# ${LINE} #" echo "##${LINE//?/#}##" - $DOCKER build $CACHE -t bugzilla/${IMAGE}:${DATE}.${ITER} -f docker/images/Dockerfile.${IMAGE} . - if [ $? == 0 ]; then + if $DOCKER build $CACHE -t "bugzilla/${IMAGE}:${DATE}.${ITER}" -f "docker/images/Dockerfile.${IMAGE}" .; then echo echo_green "The build appears to have succeeded." @@ -104,7 +105,7 @@ select IMAGE in "All images" $FILES; do echo_red "Docker build failed for ${IMAGE}. See output above." echo if [ ${#IMAGES_TO_BUILD[@]} -eq 1 ]; then - exit -1 + exit 1 fi fi done @@ -112,7 +113,7 @@ select IMAGE in "All images" $FILES; do # Check if any images were built successfully if [ ${#BUILT_IMAGES[@]} -eq 0 ]; then echo_red "No images were built successfully." - exit -1 + exit 1 fi echo echo_green "Successfully built ${#BUILT_IMAGES[@]} image(s):" @@ -129,13 +130,13 @@ select IMAGE in "All images" $FILES; do fi if [ ! -x "$PYTHON" ]; then echo "The python executable specified in your PYTHON environment value or your PATH is not executable or I can't find it." - exit -1 + exit 1 fi AUTHINFO=$($PYTHON -c "import json; print(len(json.load(open('${HOME}/.docker/config.json','r',encoding='utf-8'))['auths']))") - if [ $AUTHINFO -gt 0 ]; then + if [ "$AUTHINFO" -gt 0 ]; then # user is logged in echo - read -p "Do you wish to push to DockerHub? [y/N]: " yesno + read -rp "Do you wish to push to DockerHub? [y/N]: " yesno case $yesno in [Yy]*) echo @@ -143,10 +144,10 @@ select IMAGE in "All images" $FILES; do for img in "${!BUILT_IMAGES[@]}"; do tag="${BUILT_IMAGES[$img]}" echo "Pushing bugzilla/${img}:${tag}..." - $DOCKER push bugzilla/${img}:${tag} + $DOCKER push "bugzilla/${img}:${tag}" echo "Tagging bugzilla/${img}:${tag} as bugzilla/${img}:latest..." - $DOCKER tag bugzilla/${img}:${tag} bugzilla/${img}:latest - $DOCKER push bugzilla/${img}:latest + $DOCKER tag "bugzilla/${img}:${tag}" "bugzilla/${img}:latest" + $DOCKER push "bugzilla/${img}:latest" done echo_green "All images pushed successfully." ;; diff --git a/docker/run-tests-in-docker.sh b/docker/run-tests-in-docker.sh index de9e2c139..1b3d5f219 100644 --- a/docker/run-tests-in-docker.sh +++ b/docker/run-tests-in-docker.sh @@ -7,6 +7,7 @@ # defined by the Mozilla Public License, v. 2.0. # Source common Docker script checks and functions +# shellcheck source=docker/common.sh source "$(dirname "$0")/common.sh" export CI="" @@ -24,7 +25,7 @@ if [ "$#" -eq 0 ]; then echo " 5) mariadb - Run BMO tests with MariaDB" echo " 6) release - Run release tests" echo - read -p "Select a test option (1-6, default is mysql): " choice + read -rp "Select a test option (1-6, default is mysql): " choice case "$choice" in 1) set -- "sanity" ;; 2|"") set -- "mysql" ;; @@ -48,18 +49,22 @@ elif [ "$1" == "mariadb" ]; then DOCKER_COMPOSE_FILE=docker-compose.test-mariadb.yml elif [ "$1" == "release" ]; then DOCKER_FILE=docker/images/Dockerfile.perl-testsuite - $DOCKER build -t bugzilla-release-test -f $DOCKER_FILE . - if [ $? == 0 ]; then + if $DOCKER build -t bugzilla-release-test -f "$DOCKER_FILE" .; then $DOCKER run --rm bugzilla-release-test else echo "docker build failed." fi exit $? fi -$DOCKER compose -f $DOCKER_COMPOSE_FILE build -if [ $? == 0 ]; then - $DOCKER compose -f $DOCKER_COMPOSE_FILE run --rm --name bugzilla6.test bugzilla6.test $TEST_NAME -q -f t/bmo/*.t - $DOCKER compose -f $DOCKER_COMPOSE_FILE down +if $DOCKER compose -f "$DOCKER_COMPOSE_FILE" build; then + if $DOCKER compose -f "$DOCKER_COMPOSE_FILE" run --rm --name bugzilla6.test bugzilla6.test "$TEST_NAME" -q -f t/bmo/*.t; then + $DOCKER compose -f "$DOCKER_COMPOSE_FILE" down + else + echo "docker compose run failed." + $DOCKER compose -f "$DOCKER_COMPOSE_FILE" down + exit 1 + fi else echo "docker compose build failed." + exit 1 fi From 825bf29fbebca8860cf068618af52a6484d355e9 Mon Sep 17 00:00:00 2001 From: Dave Miller Date: Wed, 17 Dec 2025 00:01:08 -0500 Subject: [PATCH 13/13] Add ShellCheck linting job to CI workflow --- .github/workflows/ci.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 122dc5330..7f632a186 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -95,3 +95,15 @@ jobs: - name: Run tests run: docker run --rm bugzilla-release-test + shellcheck: + name: ShellCheck (linting for shell scripts) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install ShellCheck + run: sudo apt-get update && sudo apt-get install -y shellcheck + - name: Run ShellCheck on all scripts + run: | + find . -type f -name '*.sh' | while read -r file; do + shellcheck -x "$file" + done