From 14c25cf670958e09d9ada2a83e611513b1391ef6 Mon Sep 17 00:00:00 2001 From: cytopia Date: Fri, 25 Mar 2022 00:29:07 +0100 Subject: [PATCH] Try out new workflow run --- .../workflows/{arm64.yml => arm64.yml.off} | 0 .../workflows/{build.yml => build.yml.off} | 0 .../{nightly.yml => nightly.yml.off} | 0 .github/workflows/zzz-build.yml | 33 + .github/workflows/zzz-params.yml | 70 ++ .github/workflows/zzz-reuse.yml | 300 ++++++++ .gitignore | 75 +- Makefile | 642 ++++++++---------- build/gen-readme.sh | 73 +- 9 files changed, 705 insertions(+), 488 deletions(-) rename .github/workflows/{arm64.yml => arm64.yml.off} (100%) rename .github/workflows/{build.yml => build.yml.off} (100%) rename .github/workflows/{nightly.yml => nightly.yml.off} (100%) create mode 100644 .github/workflows/zzz-build.yml create mode 100644 .github/workflows/zzz-params.yml create mode 100644 .github/workflows/zzz-reuse.yml diff --git a/.github/workflows/arm64.yml b/.github/workflows/arm64.yml.off similarity index 100% rename from .github/workflows/arm64.yml rename to .github/workflows/arm64.yml.off diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml.off similarity index 100% rename from .github/workflows/build.yml rename to .github/workflows/build.yml.off diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml.off similarity index 100% rename from .github/workflows/nightly.yml rename to .github/workflows/nightly.yml.off diff --git a/.github/workflows/zzz-build.yml b/.github/workflows/zzz-build.yml new file mode 100644 index 0000000..9c68542 --- /dev/null +++ b/.github/workflows/zzz-build.yml @@ -0,0 +1,33 @@ +--- + +# ------------------------------------------------------------------------------------------------- +# Job Name +# ------------------------------------------------------------------------------------------------- +name: build + + +# ------------------------------------------------------------------------------------------------- +# When to run +# ------------------------------------------------------------------------------------------------- +on: + push: + + +jobs: + + # (1/2) Determine repository params + params: + uses: ./.github/workflows/zzz-params.yml + + # (2/2) Build + docker: + needs: [params] + uses: ./.github/workflows/zzz-build.yml + with: + enabled: true + can_deploy: ${{ github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/') || startsWith(github.ref, 'refs/heads/release-') }} + matrix: ${{ needs.params.outputs.matrix }} + refs: ${{ needs.params.outputs.refs }} + secrets: + dockerhub_username: ${{ secrets.DOCKERHUB_USERNAME }} + dockerhub_password: ${{ secrets.DOCKERHUB_PASSWORD }} diff --git a/.github/workflows/zzz-params.yml b/.github/workflows/zzz-params.yml new file mode 100644 index 0000000..cdd97c1 --- /dev/null +++ b/.github/workflows/zzz-params.yml @@ -0,0 +1,70 @@ +--- + +# ------------------------------------------------------------------------------------------------- +# Job Name +# ------------------------------------------------------------------------------------------------- +name: params + + +# ------------------------------------------------------------------------------------------------- +# Custom Variables +# ------------------------------------------------------------------------------------------------- +env: + MATRIX: >- + [ + { + "NAME": "PHP", + "VERSION": ["5.5", "5.6"], + "FLAVOUR": ["base"], + "ARCH": ["linux/amd64", "linux/arm64"] + } + ] + + +# ------------------------------------------------------------------------------------------------- +# When to run +# ------------------------------------------------------------------------------------------------- +on: + workflow_call: + outputs: + matrix: + description: "The determined version matrix" + value: ${{ jobs.params.outputs.matrix }} + refs: + description: "The determined git ref matrix (only during scheduled run)" + value: ${{ jobs.params.outputs.refs }} + +jobs: + params: + runs-on: ubuntu-latest + + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + refs: ${{ steps.set-refs.outputs.matrix }} + + steps: + - name: "[Set-Output] Matrix" + id: set-matrix + run: | + echo "::set-output name=matrix::$( echo '${{ env.MATRIX }}' | jq -M -c )" + + - name: "[Set-Output] Matrix 'Refs' (master branch and latest tag)" + id: set-refs + uses: cytopia/git-ref-matrix-action@v0.1.4 + with: + repository_default_branch: master + branches: master + num_latest_tags: 1 + if: github.event_name == 'schedule' + + - name: "[DEBUG] Show settings'" + run: | + echo 'Matrix' + echo '--------------------' + echo '${{ steps.set-matrix.outputs.matrix }}' + echo + + echo 'Matrix: Refs' + echo '--------------------' + echo '${{ steps.set-matrix-refs.outputs.matrix }}' + echo diff --git a/.github/workflows/zzz-reuse.yml b/.github/workflows/zzz-reuse.yml new file mode 100644 index 0000000..885e2ab --- /dev/null +++ b/.github/workflows/zzz-reuse.yml @@ -0,0 +1,300 @@ +name: Build multi-arch image + +on: + workflow_call: + ### + ### Variables + ### + inputs: + enabled: + description: 'Determines wheather this workflow is enabled at all (will run or skip).' + required: true + type: boolean + can_deploy: + description: 'Determines wheather this workflow will also deploy (login and push).' + required: true + type: boolean + matrix: + description: 'The version build matrix as JSON string ( list of objects: [{NAME, VERSION[], ARCH[]}] ).' + required: true + type: string + refs: + description: 'The ref build matrix as JSON string (list of git refs to build/deploy).' + required: false + type: string + ### + ### Secrets + ### + secrets: + dockerhub_username: + description: 'The username for Dockerhub.' + required: false + dockerhub_password: + description: 'The password for Dockerhub.' + required: false + +jobs: + + # ----------------------------------------------------------------------------------------------- + # JOB (1/3): CONFIGURE + # ----------------------------------------------------------------------------------------------- + configure: + name: Configure + runs-on: ubuntu-latest + outputs: + can_login: ${{ steps.set-login.outputs.can_login }} + has_refs: ${{ steps.set-matrix.outputs.has_refs }} + matrix_build: ${{ steps.set-matrix.outputs.matrix_build }} + matrix_deploy: ${{ steps.set-matrix.outputs.matrix_deploy }} + artifact_base: ${{ steps.set-artifact.outputs.base }} + artifact_mods: ${{ steps.set-artifact.outputs.mods }} + artifact_prod: ${{ steps.set-artifact.outputs.prod }} + artifact_work: ${{ steps.set-artifact.outputs.work }} + if: inputs.enabled + steps: + - name: "[Set-Output] Set Docker login capabilities" + id: set-login + shell: bash + run: | + if [ "${{ env.ENV_USER }}" = '' ] || [ "${{ env.ENV_PASS }}" = '' ]; then + echo "::set-output name=can_login::0" + else + echo "::set-output name=can_login::1" + fi + env: + ENV_USER: ${{ secrets.dockerhub_username }} + ENV_PASS: ${{ secrets.dockerhub_password }} + + - name: "[Set-Output] Set Build & Deploy Matrix" + id: set-matrix + shell: bash + run: | + if [ "${{ inputs.refs }}" != "" ]; then + MATRIX_BUILD="$( \ + jq -M -c \ + --argjson refs '${{ inputs.refs }}' \ + 'map({name:.NAME, version:.VERSION[], flavour:.FLAVOUR[], arch:.ARCH[], refs:$refs[]})' <<<'${{ inputs.matrix }}' \ + )" + MATRIX_DEPLOY="$( \ + jq -M -c \ + --argjson refs '${{ inputs.refs }}' \ + 'map({name:.NAME, version:.VERSION[], flavour:.FLAVOUR[], refs:$refs[]})' <<<'${{ inputs.matrix }}' \ + )" + echo "::set-output name=matrix_build::${MATRIX_BUILD}" + echo "::set-output name=matrix_deploy::${MATRIX_DEPLOY}" + echo "::set-output name=has_refs::1" + else + MATRIX_BUILD="$( \ + jq -M -c \ + 'map({name:.NAME, version:.VERSION[], flavour:.FLAVOUR[], arch:.ARCH[]})' <<<'${{ inputs.matrix }}' \ + )" + MATRIX_DEPLOY="$( \ + jq -M -c \ + 'map({name:.NAME, version:.VERSION[], flavour:.FLAVOUR[]})' <<<'${{ inputs.matrix }}' \ + )" + echo "::set-output name=matrix_build::${MATRIX_BUILD}" + echo "::set-output name=matrix_deploy::${MATRIX_DEPLOY}" + echo "::set-output name=has_refs::0" + fi + + - name: "[Set-Output] Set unique Artifact filenames" + id: set-artifact + shell: bash + run: | + PRE_HASH="$( git rev-parse HEAD | head -c 10 )" + PRE_DATE="$( date +"%s" )" + BASE="${PRE_HASH}-${PRE_DATE}-base" + MODS="${PRE_HASH}-${PRE_DATE}-mods" + PROD="${PRE_HASH}-${PRE_DATE}-prod" + WORK="${PRE_HASH}-${PRE_DATE}-work" + + echo "::set-output name=base::${BASE}" + echo "::set-output name=mods::${MODS}" + echo "::set-output name=prod::${PROD}" + echo "::set-output name=work::${WORK}" + + - name: "[DEBUG] Workflow Inputs" + shell: bash + run: | + echo 'enabled: ${{ inputs.enabled }} ' + echo 'can_deploy: ${{ inputs.can_deploy }} ' + echo 'matrix: ${{ inputs.matrix }} ' + echo 'refs: ${{ inputs.refs }} ' + + - name: "[DEBUG] Determined Settings" + shell: bash + run: | + echo 'can_login=${{ steps.set-login.outputs.can_login }}' + echo 'has_refs=${{ steps.set-matrix.outputs.has_refs }}' + echo 'matrix_build=${{ steps.set-matrix.outputs.matrix_build }}' + echo 'matrix_deploy=${{ steps.set-matrix.outputs.matrix_deploy }}' + echo 'artifact_base=${{ steps.set-artifact.outputs.base }}' + echo 'artifact_mods=${{ steps.set-artifact.outputs.mods }}' + echo 'artifact_prod=${{ steps.set-artifact.outputs.prod }}' + echo 'artifact_work=${{ steps.set-artifact.outputs.work }}' + + # ----------------------------------------------------------------------------------------------- + # JOB (2/3): BUILD + # ----------------------------------------------------------------------------------------------- + build-base: + needs: [configure] + name: Build ${{ matrix.name }}-${{ matrix.version }} (${{ matrix.flavour }}) (${{ matrix.arch }}) ${{ matrix.refs }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: ${{ fromJson(needs.configure.outputs.matrix_build) }} + if: inputs.enabled + steps: + # ------------------------------------------------------------ + # Setup repository + # ------------------------------------------------------------ + - name: "[SETUP] Checkout repository (current)" + uses: actions/checkout@v3 + with: + fetch-depth: 0 + if: needs.configure.outputs.has_refs == 0 + + - name: "[SETUP] Checkout repository (ref: ${{ matrix.refs }})" + uses: actions/checkout@v3 + with: + fetch-depth: 0 + ref: ${{ matrix.refs }} + if: needs.configure.outputs.has_refs != 0 + + - name: "[SETUP] Setup QEMU environment" + uses: docker/setup-qemu-action@v1 + with: + image: tonistiigi/binfmt:latest + platforms: all + + - name: "[SETUP] Determine Docker tag" + id: tag + uses: cytopia/docker-tag-action@v0.4.15 + + # ------------------------------------------------------------ + # Build + # ------------------------------------------------------------ + - name: Build + uses: cytopia/shell-command-retry-action@v0.1.2 + with: + command: | + make build VERSION=${{ matrix.version }} FLAVOUR=${{ matrix.flavour }} ARCH=${{ matrix.arch }} TAG=${{ steps.tag.outputs.docker-tag }} + + # ------------------------------------------------------------ + # Test + # ------------------------------------------------------------ + - name: Test + uses: cytopia/shell-command-retry-action@v0.1.2 + with: + command: | + make test VERSION=${{ matrix.version }} FLAVOUR=${{ matrix.flavour }} ARCH=${{ matrix.arch }} TAG=${{ steps.tag.outputs.docker-tag }} + + # ------------------------------------------------------------ + # Export + # ------------------------------------------------------------ + - name: "[Artifact] Set name" + id: artifact + run: | + PREFIX="${{ needs.configure.outputs.artifact_base }}" + ARCH="${{ matrix.arch }}" + TAG="${{ steps.tag.outputs.docker-tag }}" + NAME="$( echo "${PREFIX}-${ARCH}-${TAG}" | sed 's|/|-|g' )" + echo "::set-output name=file::${NAME}" + echo "file=${NAME}" + + - name: "[Artifact] Export" + uses: cytopia/shell-command-retry-action@v0.1.2 + with: + command: | + make save VERSION=${{ matrix.version }} FLAVOUR=${{ matrix.flavour }} ARCH=${{ matrix.arch }} TAG=${{ steps.tag.outputs.docker-tag }} OUTFILE=${{ steps.artifact.outputs.file }} + + - name: "[Artifact] Upload" + uses: actions/upload-artifact@v3 + with: + name: ${{ steps.artifact.outputs.file }} + path: ${{ steps.artifact.outputs.file }} + +# # ------------------------------------------------------------ +# # Deploy +# # ------------------------------------------------------------ +# - name: Docker login +# uses: docker/login-action@v1 +# with: +# username: ${{ secrets.dockerhub_username }} +# password: ${{ secrets.dockerhub_password }} +# if: needs.configure.outputs.can_login == 1 && inputs.can_deploy +# +# - name: Docker push architecture image +# uses: cytopia/shell-command-retry-action@v0.1.2 +# with: +# command: | +# make push NAME=${{ matrix.name }} VERSION=${{ matrix.version }} FLAVOUR=${{ matrix.flavour }} ARCH=${{ matrix.arch }} TAG=${{ steps.tag.outputs.docker-tag }} +# if: needs.configure.outputs.can_login == 1 && inputs.can_deploy +# +# # ----------------------------------------------------------------------------------------------- +# # JOB (3/3): DEPLOY +# # ----------------------------------------------------------------------------------------------- +# deploy: +# needs: [configure, build] +# name: Deploy ${{ matrix.name }}-${{ matrix.version }} (${{ matrix.flavour }}) ${{ matrix.refs }} +# runs-on: ubuntu-latest +# strategy: +# fail-fast: false +# matrix: +# include: ${{ fromJson(needs.configure.outputs.matrix_deploy) }} +# if: inputs.enabled && needs.configure.outputs.can_login == 1 && inputs.can_deploy +# steps: +# # ------------------------------------------------------------ +# # Setup repository +# # ------------------------------------------------------------ +# - name: "[SETUP] Checkout repository (current)" +# uses: actions/checkout@v3 +# with: +# fetch-depth: 0 +# if: needs.configure.outputs.has_refs == 0 +# +# - name: "[SETUP] Checkout repository (ref: ${{ matrix.refs }})" +# uses: actions/checkout@v3 +# with: +# fetch-depth: 0 +# ref: ${{ matrix.refs }} +# if: needs.configure.outputs.has_refs != 0 +# +# - name: "[SETUP] Determine Docker tag" +# id: tag +# uses: cytopia/docker-tag-action@v0.4.15 +# +# - name: "[SETUP] Determine manifest arches" +# id: manifest +# run: | +# ARCHES="$( echo '${{ inputs.matrix }}' \ +# | jq 'group_by(.NAME, .VERSION, .ARCH)' \ +# | jq 'map({NAME: .[].NAME, VERSION: .[].VERSION[], FLAVOUR: .[].FLAVOUR[], ARCHES: .[].ARCH|join(",")})' \ +# | jq '.[] | select(.NAME=="${{ matrix.name }}" and .VERSION=="${{ matrix.version }}" and .FLAVOUR=="${{ matrix.flavour }}") | .ARCHES' \ +# | jq -c -M \ +# )" +# echo "::set-output name=arches::${ARCHES}" +# echo "ARCHES: ${ARCHES}" +# +# +# # ------------------------------------------------------------ +# # Deploy +# # ------------------------------------------------------------ +# - name: "[DEPLOY] Login" +# uses: docker/login-action@v1 +# with: +# username: ${{ secrets.DOCKERHUB_USERNAME }} +# password: ${{ secrets.DOCKERHUB_PASSWORD }} +# +# - name: "[DEPLOY] Create Docker manifest for architectures: ${{ steps.manifest.outputs.arches }}" +# uses: cytopia/shell-command-retry-action@v0.1.2 +# with: +# command: | +# make manifest-create NAME=${{ matrix.name }} VERSION=${{ matrix.version }} FLAVOUR=${{ matrix.flavour }} ARCHES=${{ steps.manifest.outputs.arches }} TAG=${{ steps.tag.outputs.docker-tag }} +# +# - name: "[DEPLOY] Publish Docker manifest: ${{ steps.tag.outputs.docker-tag }}" +# uses: cytopia/shell-command-retry-action@v0.1.2 +# with: +# command: | +# make manifest-push NAME=${{ matrix.name }} VERSION=${{ matrix.version }} FLAVOUR=${{ matrix.flavour }} TAG=${{ steps.tag.outputs.docker-tag }} diff --git a/.gitignore b/.gitignore index beb7276..0aaabdf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,74 +1,3 @@ -###################################### -# CUSTOM -###################################### - build/ansible/*.retry - - - -###################################### -# GENERIC -###################################### - -###### std ###### -.lock -*.log - -###### patches/diffs ###### -*.patch -*.diff -*.orig -*.rej - - -###################################### -# Operating Systems -###################################### - -###### OSX ###### -._* -.DS* -.Spotlight-V100 -.Trashes - -###### Windows ###### -Thumbs.db -ehthumbs.db -Desktop.ini -$RECYCLE.BIN/ -*.lnk - - -###################################### -# Editors -###################################### - -###### Sublime ###### -*.sublime-workspace -*.sublime-project - -###### Eclipse ###### -.classpath -.buildpath -.project -.settings/ - -###### Netbeans ###### -nbproject/private/ - -###### Intellij IDE ###### -.idea/ -.idea_modules/ - -###### vim ###### -*.swp -*.swo -*~ - -###### TextMate ###### -.tm_properties -*.tmproj - -###### BBEdit ###### -*.bbprojectd -*.bbproject +Makefile.docker +Makefile.lint diff --git a/Makefile b/Makefile index 13fd844..b57895e 100644 --- a/Makefile +++ b/Makefile @@ -2,109 +2,86 @@ ifneq (,) .error This Makefile requires GNU Make. endif - -# ------------------------------------------------------------------------------------------------- -# Docker configuration -# ------------------------------------------------------------------------------------------------- - -CURRENT_DIR = $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) - -DIR = Dockerfiles -IMAGE = devilbox/php-fpm -ARCH = linux/amd64 - -NO_CACHE = -PHP_EXT_DIR = - -# Run checks after each module has been installed (slow, but yields errors faster) -FAIL_FAST = False - -# File lint -FL_VERSION = 0.3 -FL_IGNORES = .git/,.github/ - - -# ------------------------------------------------------------------------------------------------- -# DEFAULT TARGET -# ------------------------------------------------------------------------------------------------- - -help: - @echo - @echo " _ _ _ _ __ _ ___ " - @echo " _| |___ _ _<_| | |_ _____ / ___| |_ ___ ___| | ___._ _ _ " - @echo " / . / ._| | | | | . / . \ \// | . | . | . |___| || . | ' ' |" - @echo " \___\___|__/|_|_|___\___/\_/_/| _|_|_| _/ |_|| _|_|_|_|" - @echo " |_| |_| |_| " - @echo - @echo - @echo "Targets" - @echo "--------------------------------------------------------------------------------" - @echo - @echo "lint Lint project files and repository" - @echo - @echo "gen-readme [VERSION=] Update README with PHP modules from built images." - @echo "gen-dockerfiles [FAIL_FAST=] Generate Dockerfiles from templates." - @echo - @echo "build-base VERSION= [ARGS=] Build base image by specified version" - @echo "build-mods VERSION= [ARGS=] Build mods image by specified version" - @echo "build-prod VERSION= [ARGS=] Build prod image by specified version" - @echo "build-work VERSION= [ARGS=] Build work image by specified version" - @echo - @echo "rebuild-base VERSION= [ARGS=] Rebuild base image by specified version" - @echo "rebuild-mods VERSION= [ARGS=] Rebuild mods image by specified version" - @echo "rebuild-prod VERSION= [ARGS=] Rebuild prod image by specified version" - @echo "rebuild-work VERSION= [ARGS=] Rebuild work image by specified version" - @echo - @echo "test-base VERSION= Test base image by specified version" - @echo "test-mods VERSION= Test mods image by specified version" - @echo "test-prod VERSION= Test prod image by specified version" - @echo "test-work VERSION= Test work image by specified version" - @echo - @echo - @echo "Variables" - @echo "--------------------------------------------------------------------------------" - @echo - @echo "VERSION One of '5.2', '5.3', '5.4', '5.5', '5.6', '7.0'," - @echo " '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2'." - @echo " For gen-readme target it is optional and if not" - @echo " specified, it will generate for all versions." - @echo - @echo "FAIL_FAST Either 'True' or 'False' (defaults to 'False')." - @echo " If set to 'True', each module install has an" - @echo " immediate check, which is very slow for CI, but" - @echo " yields errors immediately." - @echo " If set to 'False', checks are done at the end." - @echo - @echo "ARGS Can be added to all build-* and rebuild-* targets" - @echo " to supply additional docker build options." - - -# ------------------------------------------------------------------------------------------------- -# Lint Targets -# ------------------------------------------------------------------------------------------------- - -lint: lint-files -lint: lint-yaml -lint: lint-changelog -lint: lint-workflow - -lint-workflow: - @echo "################################################################################" - @echo "# Lint Workflow" - @echo "################################################################################" - @\ - GIT_CURR_MAJOR="$$( git tag | sort -V | tail -1 | sed 's|\.[0-9]*$$||g' )"; \ - GIT_CURR_MINOR="$$( git tag | sort -V | tail -1 | sed 's|^[0-9]*\.||g' )"; \ - GIT_NEXT_TAG="$${GIT_CURR_MAJOR}.$$(( GIT_CURR_MINOR + 1 ))"; \ - if ! grep 'refs:' -A 100 .github/workflows/nightly.yml \ - | grep " - '$${GIT_NEXT_TAG}'" >/dev/null; then \ - echo "[ERR] New Tag required in .github/workflows/nightly.yml: $${GIT_NEXT_TAG}"; \ - exit 1; \ - else \ - echo "[OK] Git Tag present in .github/workflows/nightly.yml: $${GIT_NEXT_TAG}"; \ +# Ensure additional Makefiles are present +MAKEFILES = Makefile.docker Makefile.lint +$(MAKEFILES): URL=https://raw.githubusercontent.com/devilbox/makefiles/master/$(@) +$(MAKEFILES): + @if ! (curl --fail -sS -o $(@) $(URL) || wget -O $(@) $(URL)); then \ + echo "Error, curl or wget required."; \ + echo "Exiting."; \ + false; \ fi +include $(MAKEFILES) + +# Set default Target +.DEFAULT_GOAL := help + + +# ------------------------------------------------------------------------------------------------- +# Default configuration +# ------------------------------------------------------------------------------------------------- +# Own vars +TAG = latest + +# Makefile.docker overwrites +NAME = PHP +#VERSION = 5.5 +IMAGE = devilbox/php-fpm +#FLAVOUR = base +FILE = Dockerfile-$(VERSION) +DIR = Dockerfiles/$(FLAVOUR) + +ifeq ($(strip $(TAG)),latest) +DOCKER_TAG = $(VERSION)-$(FLAVOUR) +BASE_TAG = $(VERSION)-base +MODS_TAG = $(VERSION)-mods +PROD_TAG = $(VERSION)-prod +WORK_TAG = $(VERSION)-work +else +DOCKER_TAG = $(VERSION)-$(FLAVOUR)-$(TAG) +BASE_TAG = $(VERSION)-base-$(TAG) +MODS_TAG = $(VERSION)-mods-$(TAG) +PROD_TAG = $(VERSION)-prod-$(TAG) +WORK_TAG = $(VERSION)-work-$(TAG) +endif +ARCH = linux/amd64 + + +# Makefile.lint overwrites +FL_IGNORES = .git/,.github/,tests/ +SC_IGNORES = .git/,.github/,tests/ + + +# ------------------------------------------------------------------------------------------------- +# Default Target +# ------------------------------------------------------------------------------------------------- +.PHONY: help +help: + @echo "lint Lint project files and repository" + @echo + @echo "build [ARCH=...] [TAG=...] Build Docker image" + @echo "rebuild [ARCH=...] [TAG=...] Build Docker image without cache" + @echo "push [ARCH=...] [TAG=...] Push Docker image to Docker hub" + @echo + @echo "manifest-create [ARCHES=...] [TAG=...] Create multi-arch manifest" + @echo "manifest-push [TAG=...] Push multi-arch manifest" + @echo + @echo "test [ARCH=...] Test built Docker image" @echo + +# ------------------------------------------------------------------------------------------------- +# Overwrite Targets +# ------------------------------------------------------------------------------------------------- + +# Append additional target to lint +lint: lint-changelog +lint: lint-ansible + +### +### Ensures CHANGELOG has an entry +### +.PHONY: lint-changelog lint-changelog: @echo "################################################################################" @echo "# Lint Changelog" @@ -121,46 +98,105 @@ lint-changelog: fi @echo -lint-files: - @echo "################################################################################" - @echo "# Lint Files" - @echo "################################################################################" - @docker run --rm $$(tty -s && echo "-it" || echo) -v $(CURRENT_DIR):/data cytopia/file-lint:$(FL_VERSION) file-cr --text --ignore '$(FL_IGNORES)' --path . - @docker run --rm $$(tty -s && echo "-it" || echo) -v $(CURRENT_DIR):/data cytopia/file-lint:$(FL_VERSION) file-crlf --text --ignore '$(FL_IGNORES)' --path . - @docker run --rm $$(tty -s && echo "-it" || echo) -v $(CURRENT_DIR):/data cytopia/file-lint:$(FL_VERSION) file-trailing-single-newline --text --ignore '$(FL_IGNORES)' --path . - @docker run --rm $$(tty -s && echo "-it" || echo) -v $(CURRENT_DIR):/data cytopia/file-lint:$(FL_VERSION) file-trailing-space --text --ignore '$(FL_IGNORES)' --path . - @docker run --rm $$(tty -s && echo "-it" || echo) -v $(CURRENT_DIR):/data cytopia/file-lint:$(FL_VERSION) file-utf8 --text --ignore '$(FL_IGNORES)' --path . - @docker run --rm $$(tty -s && echo "-it" || echo) -v $(CURRENT_DIR):/data cytopia/file-lint:$(FL_VERSION) file-utf8-bom --text --ignore '$(FL_IGNORES)' --path . - @echo - -lint-yaml: - @# Lint all files - @echo "################################################################################" - @echo "# Lint Yaml" - @echo "################################################################################" - @docker run --rm $$(tty -s && echo "-it" || echo) -v $(CURRENT_DIR):/data cytopia/yamllint . - @echo +### +### Ensures Ansible Dockerfile generation is current +### +.PHONY: lint-ansible +lint-ansible: gen-dockerfiles + @git diff --quiet || { echo "Build Changes"; git diff; git status; false; } # ------------------------------------------------------------------------------------------------- -# GENERATE TARGETS +# Docker Targets # ------------------------------------------------------------------------------------------------- -gen-readme: -ifeq ($(strip $(VERSION)),) - @echo "Generate README.md for all PHP versions" - cd build; ./gen-readme.sh $(ARCH) -else - @echo "Generate README.md for PHP $(VERSION)" - @$(MAKE) --no-print-directory _check-version - @$(MAKE) --no-print-directory _check-image-exists _EXIST_IMAGE=base - @$(MAKE) --no-print-directory _check-image-exists _EXIST_IMAGE=mods - cd build; ./gen-readme.sh $(ARCH) $(VERSION) +# ---- ONLY FOR "mods" images ---- +# When builds mods, we have a builder image and then copy everything to the final +# target image. In order to do so, we pass a build-arg EXT_DIR, which contains +# the variable directory of extensions to copy. +# The only way to "LAZY" fetch it, is by doing a call to the base image and populate +# a Makefile variable with its value upon call. +ifeq ($(strip $(FLAVOUR)),mods) +EXT_DIR=$$( docker run --rm --platform $(ARCH) --entrypoint=php $(IMAGE):$(BASE_TAG) -r \ + 'echo ini_get("extension_dir");'\ +) endif +.PHONY: build +build: check-flavour-is-set +build: check-parent-image-exists +build: ARGS+=--build-arg EXT_DIR=$(EXT_DIR) +build: docker-arch-build + +.PHONY: rebuild +rebuild: check-flavour-is-set +rebuild: check-parent-image-exists +rebuild: ARGS+=--build-arg EXT_DIR=$(EXT_DIR) +rebuild: docker-arch-rebuild + +.PHONY: push +push: docker-arch-push + + +# ------------------------------------------------------------------------------------------------- +# Save / Load Targets +# ------------------------------------------------------------------------------------------------- +.PHONY: save +docker-save: check-flavour-is-set +docker-save: check-version-is-set +docker-save: check-current-image-exists + +.PHONY: load +docker-load: check-flavour-is-set +docker-load: check-version-is-set +docker-load: check-current-image-exists + + +# ------------------------------------------------------------------------------------------------- +# Manifest Targets +# ------------------------------------------------------------------------------------------------- +.PHONY: manifest-create +manifest-create: docker-manifest-create + +.PHONY: manifest-push +manifest-push: docker-manifest-push + + +# ------------------------------------------------------------------------------------------------- +# Test Targets +# ------------------------------------------------------------------------------------------------- +.PHONY: test +test: check-flavour-is-set +test: check-current-image-exists +test: test-integration + +.PHONY: test-integration +test-integration: + ./tests/test.sh $(IMAGE) $(ARCH) $(VERSION) $(FLAVOUR) + + +# ------------------------------------------------------------------------------------------------- +# Generate Targets +# ------------------------------------------------------------------------------------------------- + +### +### Generate README (requires images to be built) +### +.PHONY: gen-readme +gen-readme: check-version-is-set +gen-readme: + @echo "################################################################################" + @echo "# Generate README.md for PHP $(VERSION) ($(IMAGE):$(DOCKER_TAG)) on $(ARCH)" + @echo "################################################################################" + ./build/gen-readme.sh $(IMAGE) $(ARCH) $(BASE_TAG) $(MODS_TAG) $(VERSION) + git diff --quiet || { echo "Build Changes"; git diff; git status; false; } + +### +### Generate Dockerfiles +### +.PHONY: gen-dockerfiles gen-dockerfiles: docker run --rm \ - --platform $(ARCH) \ $$(tty -s && echo "-it" || echo) \ -e USER=ansible \ -e MY_UID=$$(id -u) \ @@ -175,254 +211,118 @@ gen-dockerfiles: --diff $(ARGS) -# ------------------------------------------------------------------------------------------------- -# BUILD TARGETS -# ------------------------------------------------------------------------------------------------- - -build-base: _check-version -build-base: - docker build $(NO_CACHE) \ - --platform $(ARCH) \ - --label "org.opencontainers.image.created"="$$(date --rfc-3339=s)" \ - --label "org.opencontainers.image.version"="$$(git rev-parse --abbrev-ref HEAD)" \ - --label "org.opencontainers.image.revision"="$$(git rev-parse HEAD))" \ - $(ARGS) \ - -t $(IMAGE):${VERSION}-base \ - -f $(DIR)/base/Dockerfile-${VERSION} $(DIR)/base - - -build-mods: _check-version -build-mods: _EXIST_IMAGE=base -build-mods: _check-image-exists -build-mods: -ifeq ($(strip $(TARGET)),) - docker build $(NO_CACHE) \ - --platform $(ARCH) \ - --target builder \ - -t $(IMAGE):$(VERSION)-mods \ - -f $(DIR)/mods/Dockerfile-$(VERSION) $(DIR)/mods; - @# $(NO_CACHE) is removed, as it would otherwise rebuild the 'builder' image again. - docker build \ - --platform $(ARCH) \ - --target final \ - --label "org.opencontainers.image.created"="$$(date --rfc-3339=s)" \ - --label "org.opencontainers.image.version"="$$(git rev-parse --abbrev-ref HEAD)" \ - --label "org.opencontainers.image.revision"="$$(git rev-parse HEAD)" \ - --build-arg EXT_DIR="$$( docker run --rm --platform $(ARCH) --entrypoint=php $(IMAGE):$(VERSION)-mods -i \ - | grep ^extension_dir \ - | awk -F '=>' '{print $$2}' \ - | xargs \ - )" \ - $(ARGS) \ - -t $(IMAGE):$(VERSION)-mods \ - -f $(DIR)/mods/Dockerfile-$(VERSION) $(DIR)/mods; -else - docker build $(NO_CACHE) \ - --platform $(ARCH) \ - --target $(TARGET) \ - --label "org.opencontainers.image.created"="$$(date --rfc-3339=s)" \ - --label "org.opencontainers.image.version"="$$(git rev-parse --abbrev-ref HEAD)" \ - --label "org.opencontainers.image.revision"="$$(git rev-parse HEAD)" \ - $(ARGS) \ - -t $(IMAGE):$(VERSION)-mods \ - -f $(DIR)/mods/Dockerfile-$(VERSION) $(DIR)/mods -endif - - -build-prod: _check-version -build-prod: _EXIST_IMAGE=mods -build-prod: _check-image-exists -build-prod: - docker build $(NO_CACHE) \ - --platform $(ARCH) \ - --label "org.opencontainers.image.created"="$$(date --rfc-3339=s)" \ - --label "org.opencontainers.image.version"="$$(git rev-parse --abbrev-ref HEAD)" \ - --label "org.opencontainers.image.revision"="$$(git rev-parse HEAD)" \ - $(ARGS) \ - -t $(IMAGE):${VERSION}-prod \ - -f $(DIR)/prod/Dockerfile-${VERSION} $(DIR)/prod - - -build-work: _check-version -build-work: _EXIST_IMAGE=prod -build-work: _check-image-exists -build-work: - docker build $(NO_CACHE) \ - --platform $(ARCH) \ - --label "org.opencontainers.image.created"="$$(date --rfc-3339=s)" \ - --label "org.opencontainers.image.version"="$$(git rev-parse --abbrev-ref HEAD)" \ - --label "org.opencontainers.image.revision"="$$(git rev-parse HEAD)" \ - --build-arg ARCH=$(ARCH) \ - $(ARGS) \ - -t $(IMAGE):${VERSION}-work \ - -f $(DIR)/work/Dockerfile-${VERSION} $(DIR)/work - # ------------------------------------------------------------------------------------------------- -# REBUILD TARGETS +# HELPER TARGETS # ------------------------------------------------------------------------------------------------- -rebuild-base: _pull-base-image -rebuild-base: NO_CACHE=--no-cache -rebuild-base: build-base +### +### Ensures the VERSION variable is set +### +.PHONY: check-version-is-set +check-version-is-set: + @if [ "$(VERSION)" = "" ]; then \ + echo "This make target requires the VERSION variable to be set."; \ + echo "make VERSION="; \ + echo "Exiting."; \ + exit 1; \ + fi +### +### Ensures the FLAVOUR variable is set +### +.PHONY: check-flavour-is-set +check-flavour-is-set: + @if [ "$(FLAVOUR)" = "" ]; then \ + echo "This make target requires the FLAVOUR variable to be set."; \ + echo "make FLAVOUR="; \ + echo "Exiting."; \ + exit 1; \ + fi + @if [ "$(FLAVOUR)" != "base" ] && [ "$(FLAVOUR)" != "mods" ] && [ "$(FLAVOUR)" != "prod" ] && [ "$(FLAVOUR)" != "work" ]; then \ + echo "Error, Flavour can only be one of 'base', 'mods', 'prod', or 'work'."; \ + echo "Exiting."; \ + exit 1; \ + fi -rebuild-mods: NO_CACHE=--no-cache -rebuild-mods: build-mods - - -rebuild-prod: NO_CACHE=--no-cache -rebuild-prod: build-prod - - -rebuild-work: NO_CACHE=--no-cache -rebuild-work: build-work - - -# ------------------------------------------------------------------------------------------------- -# TEST TARGETS -# ------------------------------------------------------------------------------------------------- - -test-base: _check-version -test-base: _EXIST_IMAGE=base -test-base: _check-image-exists -test-base: - ./tests/test.sh $(IMAGE) $(ARCH) $(VERSION) base - - -test-mods: _check-version -test-mods: _EXIST_IMAGE=mods -test-mods: _check-image-exists -test-mods: _check-version - ./tests/test.sh $(IMAGE) $(ARCH) $(VERSION) mods - - -test-prod: _check-version -test-prod: _EXIST_IMAGE=prod -test-prod: _check-image-exists -test-prod: _check-version - ./tests/test.sh $(IMAGE) $(ARCH) $(VERSION) prod - - -test-work: _check-version -test-work: _EXIST_IMAGE=work -test-work: _check-image-exists -test-work: _check-version - ./tests/test.sh $(IMAGE) $(ARCH) $(VERSION) work - - -# ------------------------------------------------------------------------------------------------- -# DOCKERHUB TARGETS -# ------------------------------------------------------------------------------------------------- -login: -ifeq ($(strip $(USERNAME)),) - @$(info This make target requires the USERNAME variable to be set.) - @$(info make login USERNAME= PASSWORD=) - @$(info ) - @$(error Exiting) -endif -ifeq ($(strip $(PASSWORD)),) - @$(info This make target requires the PASSWORD variable to be set.) - @$(info make login USERNAME= PASSWORD=) - @$(info ) - @$(error Exiting) -endif - @yes | docker login --username $(USERNAME) --password $(PASSWORD) - - -push: -ifeq ($(strip $(TAG)),) - @$(info This make target requires the TAG variable to be set.) - @$(info make push TAG=) - @$(info ) - @$(error Exiting) -endif - docker push $(IMAGE):$(TAG) - - -tag: -ifeq ($(strip $(OLD_TAG)),) - @$(info This make target requires the OLD_TAG variable to be set.) - @$(info make tag OLD_TAG= NEW_TAG=) - @$(info ) - @$(error Exiting) -endif -ifeq ($(strip $(NEW_TAG)),) - @$(info This make target requires the NEW_TAG variable to be set.) - @$(info make tag OLD_TAG= NEW_TAG=) - @$(info ) - @$(error Exiting) -endif - docker tag $(IMAGE):$(OLD_TAG) $(IMAGE):$(NEW_TAG) - - - -# ------------------------------------------------------------------------------------------------- -# HELPER TARGETS -# ------------------------------------------------------------------------------------------------- - -_check-version: -ifeq ($(strip $(VERSION)),) - @$(info This make target requires the VERSION variable to be set.) - @$(info make build- VERSION=7.3) - @$(info ) - @$(error Exiting) -endif -ifeq ($(VERSION),5.2) -else -ifeq ($(VERSION),5.3) -else -ifeq ($(VERSION),5.4) -else -ifeq ($(VERSION),5.5) -else -ifeq ($(VERSION),5.6) -else -ifeq ($(VERSION),7.0) -else -ifeq ($(VERSION),7.1) -else -ifeq ($(VERSION),7.2) -else -ifeq ($(VERSION),7.3) -else -ifeq ($(VERSION),7.4) -else -ifeq ($(VERSION),8.0) -else -ifeq ($(VERSION),8.1) -else -ifeq ($(VERSION),8.2) -else - @$(info VERSION can only be: '5.2', '5.3', '5.4', '5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1' or '8.2') - @$(info ) - @$(error Exiting) -endif -endif -endif -endif -endif -endif -endif -endif -endif -endif -endif -endif -endif - @echo "Version $(VERSION) is valid" - - -_check-image-exists: - @if [ "$$(docker images -q $(IMAGE):$(VERSION)-$(_EXIST_IMAGE))" = "" ]; then \ - >&2 echo "Docker image '$(IMAGE):$(VERSION)-$(_EXIST_IMAGE)' was not found locally."; \ +### +### Checks if current image exists and is of correct architecture +### +.PHONY: check-current-image-exists +check-current-image-exists: check-flavour-is-set +check-current-image-exists: + @if [ "$$( docker images -q $(IMAGE):$(DOCKER_TAG) )" = "" ]; then \ + >&2 echo "Docker image '$(IMAGE):$(DOCKER_TAG)' was not found locally."; \ >&2 echo "Either build it first or explicitly pull it from Dockerhub."; \ >&2 echo "This is a safeguard to not automatically pull the Docker image."; \ >&2 echo; \ - false; \ + exit 1; \ + else \ + echo "OK: Image $(IMAGE):$(DOCKER_TAG) exists"; \ + fi; \ + OS="$$( docker image inspect $(IMAGE):$(DOCKER_TAG) --format '{{.Os}}' )"; \ + ARCH="$$( docker image inspect $(IMAGE):$(DOCKER_TAG) --format '{{.Architecture}}' )"; \ + if [ "$${OS}/$${ARCH}" != "$(ARCH)" ]; then \ + >&2 echo "Docker image '$(IMAGE):$(DOCKER_TAG)' has invalid architecture: $${OS}/$${ARCH}"; \ + >&2 echo "Expected: $(ARCH)"; \ + >&2 echo; \ + exit 1; \ + else \ + echo "OK: Image $(IMAGE):$(DOCKER_TAG) is of arch $${OS}/$${ARCH}"; \ fi; - -_pull-base-image: - @echo "Pulling root image for PHP ${VERSION}" - docker pull --platform $(ARCH) $(shell grep FROM $(DIR)/base/Dockerfile-${VERSION} | sed 's/^FROM\s*//g';) +### +### Checks if parent image exists and is of correct architecture +### +.PHONY: check-parent-image-exists +check-parent-image-exists: check-flavour-is-set +check-parent-image-exists: + @if [ "$(FLAVOUR)" = "work" ]; then \ + if [ "$$( docker images -q $(IMAGE):$(PROD_TAG) )" = "" ]; then \ + >&2 echo "Docker image '$(IMAGE):$(PROD_TAG)' was not found locally."; \ + >&2 echo "Either build it first or explicitly pull it from Dockerhub."; \ + >&2 echo "This is a safeguard to not automatically pull the Docker image."; \ + >&2 echo; \ + exit 1; \ + fi; \ + OS="$$( docker image inspect $(IMAGE):$(PROD_TAG) --format '{{.Os}}' )"; \ + ARCH="$$( docker image inspect $(IMAGE):$(PROD_TAG) --format '{{.Architecture}}' )"; \ + if [ "$${OS}/$${ARCH}" != "$(ARCH)" ]; then \ + >&2 echo "Docker image '$(IMAGE):$(PROD_TAG)' has invalid architecture: $${OS}/$${ARCH}"; \ + >&2 echo "Expected: $(ARCH)"; \ + >&2 echo; \ + exit 1; \ + fi; \ + elif [ "$(FLAVOUR)" = "prod" ]; then \ + if [ "$$( docker images -q $(IMAGE):$(MODS_TAG) )" = "" ]; then \ + >&2 echo "Docker image '$(IMAGE):$(MODS_TAG)' was not found locally."; \ + >&2 echo "Either build it first or explicitly pull it from Dockerhub."; \ + >&2 echo "This is a safeguard to not automatically pull the Docker image."; \ + >&2 echo; \ + exit 1; \ + fi \ + OS="$$( docker image inspect $(IMAGE):$(MODS_TAG) --format '{{.Os}}' )"; \ + ARCH="$$( docker image inspect $(IMAGE):$(MODS_TAG) --format '{{.Architecture}}' )"; \ + if [ "$${OS}/$${ARCH}" != "$(ARCH)" ]; then \ + >&2 echo "Docker image '$(IMAGE):$(MODS_TAG)' has invalid architecture: $${OS}/$${ARCH}"; \ + >&2 echo "Expected: $(ARCH)"; \ + >&2 echo; \ + exit 1; \ + fi; \ + elif [ "$(FLAVOUR)" = "mods" ]; then \ + if [ "$$( docker images -q $(IMAGE):$(BASE_TAG) )" = "" ]; then \ + >&2 echo "Docker image '$(IMAGE):$(BASE_TAG)' was not found locally."; \ + >&2 echo "Either build it first or explicitly pull it from Dockerhub."; \ + >&2 echo "This is a safeguard to not automatically pull the Docker image."; \ + >&2 echo; \ + exit 1; \ + fi \ + OS="$$( docker image inspect $(IMAGE):$(BASE_TAG) --format '{{.Os}}' )"; \ + ARCH="$$( docker image inspect $(IMAGE):$(BASE_TAG) --format '{{.Architecture}}' )"; \ + if [ "$${OS}/$${ARCH}" != "$(ARCH)" ]; then \ + >&2 echo "Docker image '$(IMAGE):$(BASE_TAG)' has invalid architecture: $${OS}/$${ARCH}"; \ + >&2 echo "Expected: $(ARCH)"; \ + >&2 echo; \ + exit 1; \ + fi; \ + fi; diff --git a/build/gen-readme.sh b/build/gen-readme.sh index 829db03..29abd81 100755 --- a/build/gen-readme.sh +++ b/build/gen-readme.sh @@ -8,27 +8,18 @@ set -o pipefail # Get absolute directory of this script CWD="$(cd -P -- "$(dirname -- "$0")" && pwd -P)" -ARCH="${1:-linux/amd64}" +IMAGE="${1}" +ARCH="${2}" +TAG_BASE="${3}" +TAG_MODS="${4}" +VERSION="${5:-}" ### ### Show Usage ### print_usage() { - echo "Usage: gen-readme.sh []" - echo " gen-readme.sh 5.2" - echo " gen-readme.sh 5.3" - echo " gen-readme.sh 5.4" - echo " gen-readme.sh 5.5" - echo " gen-readme.sh 5.6" - echo " gen-readme.sh 7.0" - echo " gen-readme.sh 7.1" - echo " gen-readme.sh 7.2" - echo " gen-readme.sh 7.3" - echo " gen-readme.sh 7.4" - echo " gen-readme.sh 8.0" - echo " gen-readme.sh 8.1" - echo " gen-readme.sh 8.2" + echo "Usage: gen-readme.sh []" } @@ -36,25 +27,24 @@ print_usage() { ### Extract PHP modules in alphabetical order and comma separated in one line ### get_modules() { - tag="${1}" - + current_tag="${1}" # Retrieve all modules - PHP_MODULES="$( docker run --rm --platform "${ARCH}" $(tty -s && echo '-it' || echo) --entrypoint=php devilbox/php-fpm:${tag} -m )" + PHP_MODULES="$( docker run --rm --platform "${ARCH}" "$(tty -s && echo '-it' || echo)" --entrypoint=php "${IMAGE}:${current_tag}" -m )" ALL_MODULES= - if docker run --rm --platform "${ARCH}" $(tty -s && echo '-it' || echo) --entrypoint=find devilbox/php-fpm:${tag} /usr/local/lib/php/extensions -name 'ioncube.so' | grep -q ioncube.so; then + if docker run --rm --platform "${ARCH}" "$(tty -s && echo '-it' || echo)" --entrypoint=find "${IMAGE}:${current_tag}" /usr/local/lib/php/extensions -name 'ioncube.so' | grep -q ioncube.so; then ALL_MODULES="${ALL_MODULES},ioncube"; fi - if docker run --rm --platform "${ARCH}" $(tty -s && echo '-it' || echo) --entrypoint=find devilbox/php-fpm:${tag} /usr/local/lib/php/extensions -name 'blackfire.so' | grep -q blackfire.so; then + if docker run --rm --platform "${ARCH}" "$(tty -s && echo '-it' || echo)" --entrypoint=find "${IMAGE}:${current_tag}" /usr/local/lib/php/extensions -name 'blackfire.so' | grep -q blackfire.so; then ALL_MODULES="${ALL_MODULES},blackfire"; fi - if docker run --rm --platform "${ARCH}" $(tty -s && echo '-it' || echo) --entrypoint=find devilbox/php-fpm:${tag} /usr/local/lib/php/extensions -name 'psr.so' | grep -q psr.so; then + if docker run --rm --platform "${ARCH}" "$(tty -s && echo '-it' || echo)" --entrypoint=find "${IMAGE}:${current_tag}" /usr/local/lib/php/extensions -name 'psr.so' | grep -q psr.so; then ALL_MODULES="${ALL_MODULES},psr"; fi - if docker run --rm --platform "${ARCH}" $(tty -s && echo '-it' || echo) --entrypoint=find devilbox/php-fpm:${tag} /usr/local/lib/php/extensions -name 'phalcon.so' | grep -q phalcon.so; then + if docker run --rm --platform "${ARCH}" "$(tty -s && echo '-it' || echo)" --entrypoint=find "${IMAGE}:${current_tag}" /usr/local/lib/php/extensions -name 'phalcon.so' | grep -q phalcon.so; then ALL_MODULES="${ALL_MODULES},phalcon"; fi @@ -85,15 +75,15 @@ get_modules() { update_readme() { v="${1}" # Those sections must exist in README.md, otherwise this script will exit with errors - sed -i'' "s|.*<\/td>|$( get_modules "${v}-base" )<\/td>|g" "${CWD}/../README.md" - sed -i'' "s|.*<\/td>|$( get_modules "${v}-mods" )<\/td>|g" "${CWD}/../README.md" + sed -i'' "s|.*<\/td>|$( get_modules "${TAG_BASE}" )<\/td>|g" "${CWD}/../README.md" + sed -i'' "s|.*<\/td>|$( get_modules "${TAG_MODS}" )<\/td>|g" "${CWD}/../README.md" } ### ### Entrypoint ### -if [ "${#}" -eq "0" ] || [ "${#}" -eq "1" ]; then +if [ "${VERSION}" = "" ]; then # Update PHP modules for all versions at once update_readme "5.2" update_readme "5.3" @@ -108,31 +98,26 @@ if [ "${#}" -eq "0" ] || [ "${#}" -eq "1" ]; then update_readme "8.0" update_readme "8.1" update_readme "8.2" -elif [ "${#}" -gt "2" ]; then - # Specifying more than 1 argument is wrong - echo "Error, invalid number of arguments." - print_usage - exit 1 else - if [ "${2}" != "5.2" ] \ - && [ "${2}" != "5.3" ] \ - && [ "${2}" != "5.4" ] \ - && [ "${2}" != "5.5" ] \ - && [ "${2}" != "5.6" ] \ - && [ "${2}" != "7.0" ] \ - && [ "${2}" != "7.1" ] \ - && [ "${2}" != "7.2" ] \ - && [ "${2}" != "7.3" ] \ - && [ "${2}" != "7.4" ] \ - && [ "${2}" != "8.0" ] \ - && [ "${2}" != "8.1" ] \ - && [ "${2}" != "8.2" ]; then + if [ "${VERSION}" != "5.2" ] \ + && [ "${VERSION}" != "5.3" ] \ + && [ "${VERSION}" != "5.4" ] \ + && [ "${VERSION}" != "5.5" ] \ + && [ "${VERSION}" != "5.6" ] \ + && [ "${VERSION}" != "7.0" ] \ + && [ "${VERSION}" != "7.1" ] \ + && [ "${VERSION}" != "7.2" ] \ + && [ "${VERSION}" != "7.3" ] \ + && [ "${VERSION}" != "7.4" ] \ + && [ "${VERSION}" != "8.0" ] \ + && [ "${VERSION}" != "8.1" ] \ + && [ "${VERSION}" != "8.2" ]; then # Argument does not match any of the PHP versions echo "Error, invalid argument." print_usage exit 1 else # Update PHP modules for one specific PHP version - update_readme "${2}" + update_readme "${VERSION}" fi fi