diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 2c7d170..8e85703 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,3 +1,4 @@ +--- version: 2 updates: # Maintain dependencies for GitHub Actions diff --git a/.github/labels.yml b/.github/labels.yml new file mode 100644 index 0000000..9a507e8 --- /dev/null +++ b/.github/labels.yml @@ -0,0 +1,12 @@ +# The labels in this file are automatically synced with the repository +# using the micnncim/action-label-syncer action. +--- +- name: C-dependency + color: 1abc9c + description: "Category: Dependency" +- name: PR-block + color: 3498db + description: "Pull Request: Do not merge" +- name: PR-merge + color: 3498db + description: "Pull Request: Merge when ready" diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml new file mode 100644 index 0000000..03439b4 --- /dev/null +++ b/.github/release-drafter.yml @@ -0,0 +1,33 @@ +--- +name-template: '$RESOLVED_VERSION 🌈' +tag-template: '$RESOLVED_VERSION' +version-template: '$MAJOR.$MINOR' +categories: + - title: '🚀 Features' + labels: + - 'feature' + - 'enhancement' + - title: '🐛 Bug Fixes' + labels: + - 'fix' + - 'bugfix' + - 'bug' + - title: '🧰 Maintenance' + label: 'chore' +change-template: '- $TITLE @$AUTHOR (#$NUMBER)' +change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks. +version-resolver: + major: + labels: + - 'major' + minor: + labels: + - 'minor' + patch: + labels: + - 'patch' + default: minor +template: | + ## Changes + + $CHANGES diff --git a/.github/workflows/action_branch.yml b/.github/workflows/action_branch.yml new file mode 100644 index 0000000..55d6950 --- /dev/null +++ b/.github/workflows/action_branch.yml @@ -0,0 +1,33 @@ +--- + +# ------------------------------------------------------------------------------------------------- +# Job Name +# ------------------------------------------------------------------------------------------------- +name: build + + +# ------------------------------------------------------------------------------------------------- +# When to run +# ------------------------------------------------------------------------------------------------- +on: + push: + + +jobs: + + # (1/2) Determine repository params + params: + uses: ./.github/workflows/params.yml + + # (2/2) Build + docker: + needs: [params] + uses: devilbox/github-actions/.github/workflows/docker-name-version-arch.yml@master + 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/action_pull_request.yml b/.github/workflows/action_pull_request.yml new file mode 100644 index 0000000..c80bf78 --- /dev/null +++ b/.github/workflows/action_pull_request.yml @@ -0,0 +1,35 @@ +--- + +# ------------------------------------------------------------------------------------------------- +# Job Name +# ------------------------------------------------------------------------------------------------- +name: build + + +# ------------------------------------------------------------------------------------------------- +# When to run +# ------------------------------------------------------------------------------------------------- +on: + pull_request: + + +jobs: + + # (1/2) Determine repository params + params: + uses: ./.github/workflows/params.yml + # Only run for forks (contributor) + if: github.event.pull_request.head.repo.fork + + # (2/2) Build + docker: + needs: [params] + uses: devilbox/github-actions/.github/workflows/docker-name-version-arch.yml@master + with: + enabled: true + can_deploy: false + matrix: ${{ needs.params.outputs.matrix }} + refs: ${{ needs.params.outputs.refs }} + secrets: + dockerhub_username: "" + dockerhub_password: "" diff --git a/.github/workflows/action_schedule.yml b/.github/workflows/action_schedule.yml new file mode 100644 index 0000000..36d979a --- /dev/null +++ b/.github/workflows/action_schedule.yml @@ -0,0 +1,35 @@ +--- + +# ------------------------------------------------------------------------------------------------- +# Job Name +# ------------------------------------------------------------------------------------------------- +name: nightly + + +# ------------------------------------------------------------------------------------------------- +# When to run +# ------------------------------------------------------------------------------------------------- +on: + # Runs daily + schedule: + - cron: '0 0 * * *' + + +jobs: + + # (1/2) Determine repository params + params: + uses: ./.github/workflows/params.yml + + # (2/2) Build + docker: + needs: [params] + uses: devilbox/github-actions/.github/workflows/docker-name-version-arch.yml@master + with: + enabled: true + can_deploy: true + 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/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 2cfd4b3..0000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,202 +0,0 @@ ---- - -# ------------------------------------------------------------------------------------------------- -# Job Name -# ------------------------------------------------------------------------------------------------- -name: build - - -# ------------------------------------------------------------------------------------------------- -# When to run -# ------------------------------------------------------------------------------------------------- -on: - # Runs on Push - push: - -env: - MATRIX_VERSION: '["8.2"]' - MATRIX_ARCH: '["linux/amd64","linux/386","linux/arm64","linux/arm/v7","linux/arm/v6"]' - - -jobs: - - # ----------------------------------------------------------------------------------------------- - # Job (1/3): Configure Pipeline - # ----------------------------------------------------------------------------------------------- - configure: - name: Configure - runs-on: ubuntu-latest - outputs: - matrix_version: ${{ steps.set-matrix-version.outputs.matrix_version }} - matrix_arch: ${{ steps.set-matrix-arch.outputs.matrix_arch }} - manifest_arch: ${{ steps.set-manifest-arch.outputs.manifest }} - steps: - - - name: "[OUTPUT] Export Matrix 'Version'" - id: set-matrix-version - run: | - echo '::set-output name=matrix_version::${{ env.MATRIX_VERSION }}' - echo "${{ env.MATRIX_VERSION }}" - - - name: "[OUTPUT] Export Matrix 'Arch'" - id: set-matrix-arch - run: | - echo '::set-output name=matrix_arch::${{ env.MATRIX_ARCH }}' - echo "${{ env.MATRIX_ARCH }}" - - - name: "[OUTPUT] Export Manifest 'Arch'" - id: set-manifest-arch - run: | - ARCH="$( echo ${{ env.MATRIX_ARCH }} | sed 's/"//g' | sed 's/\[//g' | sed 's/\]//g' | sed 's/ //g' )" - echo "::set-output name=manifest::${ARCH}" - echo "${ARCH}" - - - # ----------------------------------------------------------------------------------------------- - # Job (2/3): BUILD - # ----------------------------------------------------------------------------------------------- - build: - needs: configure - name: Build PHP-${{ matrix.version }} (${{ matrix.arch }}) - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - version: - - ${{ fromJson(needs.configure.outputs.matrix_version) }} - arch: - - ${{ fromJson(needs.configure.outputs.matrix_arch) }} - steps: - # ------------------------------------------------------------ - # Setup repository - # ------------------------------------------------------------ - - name: "[SETUP] Checkout repository" - uses: actions/checkout@v2 - with: - fetch-depth: 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.7 - - # ------------------------------------------------------------ - # Build - # ------------------------------------------------------------ - - name: Build - uses: cytopia/shell-command-retry-action@v0.1.2 - with: - command: | - make build ARCH=${{ matrix.arch }} - - # ------------------------------------------------------------ - # Test - # ------------------------------------------------------------ - - name: "[TEST] Docker Image" - uses: cytopia/shell-command-retry-action@v0.1.2 - with: - command: | - make test ARCH=${{ matrix.arch }} - - - name: "[TEST] Update README" - uses: cytopia/shell-command-retry-action@v0.1.2 - with: - command: | - make update-readme ARCH=${{ matrix.arch }} - - - name: "[TEST] Verify README" - run: | - git diff --quiet || { echo "Build Changes"; git diff; git status; false; } - - # ------------------------------------------------------------ - # Deploy - # ------------------------------------------------------------ - - name: "[DEPLOY] Login (only repo owner)" - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_PASSWORD }} - # https://help.github.com/en/github/automating-your-workflow-with-github-actions/contexts-and-expression-syntax-for-github-actions#functions - if: github.event.pull_request.base.repo.id == github.event.pull_request.head.repo.id - && ( - (github.event_name == 'schedule' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/'))) - || - (github.event_name == 'push' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/'))) - || - (github.event_name == 'push' && startsWith(github.ref, 'refs/heads/release-')) - ) - - - name: "[DEPLOY] Publish architecture image (only repo owner)" - uses: cytopia/shell-command-retry-action@v0.1.2 - with: - command: | - make push-arch TAG=${{ steps.tag.outputs.docker-tag }} ARCH=${{ matrix.arch }} - # https://help.github.com/en/github/automating-your-workflow-with-github-actions/contexts-and-expression-syntax-for-github-actions#functions - if: github.event.pull_request.base.repo.id == github.event.pull_request.head.repo.id - && ( - (github.event_name == 'schedule' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/'))) - || - (github.event_name == 'push' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/'))) - || - (github.event_name == 'push' && startsWith(github.ref, 'refs/heads/release-')) - ) - - # ----------------------------------------------------------------------------------------------- - # Job (3/3): DEPLOY - # ----------------------------------------------------------------------------------------------- - deploy: - needs: [configure, build] - name: Deploy - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - version: - - ${{ fromJson(needs.configure.outputs.matrix_version) }} - # https://help.github.com/en/github/automating-your-workflow-with-github-actions/contexts-and-expression-syntax-for-github-actions#functions - if: github.event.pull_request.base.repo.id == github.event.pull_request.head.repo.id - && ( - (github.event_name == 'schedule' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/'))) - || - (github.event_name == 'push' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/'))) - || - (github.event_name == 'push' && startsWith(github.ref, 'refs/heads/release-')) - ) - steps: - # ------------------------------------------------------------ - # Setup repository - # ------------------------------------------------------------ - - name: "[SETUP] Checkout repository" - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - - name: "[SETUP] Determine Docker tag" - id: tag - uses: cytopia/docker-tag-action@v0.4.7 - - # ------------------------------------------------------------ - # Deploy - # ------------------------------------------------------------ - - name: "[DEPLOY] Login" - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_PASSWORD }} - - - name: "[DEPLOY] Create Docker manifest" - uses: cytopia/shell-command-retry-action@v0.1.2 - with: - command: | - make manifest-create TAG=${{ steps.tag.outputs.docker-tag }} ARCH="${{ needs.configure.outputs.manifest_arch }}" - - - name: "[DEPLOY] Publish Docker manifest" - uses: cytopia/shell-command-retry-action@v0.1.2 - with: - command: | - make manifest-push TAG=${{ steps.tag.outputs.docker-tag }} diff --git a/.github/workflows/contributor.yml b/.github/workflows/contributor.yml deleted file mode 100644 index d09144c..0000000 --- a/.github/workflows/contributor.yml +++ /dev/null @@ -1,118 +0,0 @@ ---- - -# ------------------------------------------------------------------------------------------------- -# Job Name -# ------------------------------------------------------------------------------------------------- -name: build - - -# ------------------------------------------------------------------------------------------------- -# When to run -# ------------------------------------------------------------------------------------------------- -on: - # Runs on Pull Requests - pull_request: - -env: - MATRIX_VERSION: '["8.2"]' - MATRIX_ARCH: '["linux/amd64","linux/386","linux/arm64","linux/arm/v7","linux/arm/v6"]' - - -jobs: - - # ----------------------------------------------------------------------------------------------- - # Job (1/3): Configure Pipeline - # ----------------------------------------------------------------------------------------------- - configure: - name: Configure - runs-on: ubuntu-latest - outputs: - matrix_version: ${{ steps.set-matrix-version.outputs.matrix_version }} - matrix_arch: ${{ steps.set-matrix-arch.outputs.matrix_arch }} - manifest_arch: ${{ steps.set-manifest-arch.outputs.manifest }} - # Only run for forks (contributor) - if: ${{ github.event.pull_request.head.repo.fork }} - steps: - - - name: "[OUTPUT] Export Matrix 'Version'" - id: set-matrix-version - run: | - echo '::set-output name=matrix_version::${{ env.MATRIX_VERSION }}' - echo "${{ env.MATRIX_VERSION }}" - - - name: "[OUTPUT] Export Matrix 'Arch'" - id: set-matrix-arch - run: | - echo '::set-output name=matrix_arch::${{ env.MATRIX_ARCH }}' - echo "${{ env.MATRIX_ARCH }}" - - - name: "[OUTPUT] Export Manifest 'Arch'" - id: set-manifest-arch - run: | - ARCH="$( echo ${{ env.MATRIX_ARCH }} | sed 's/"//g' | sed 's/\[//g' | sed 's/\]//g' | sed 's/ //g' )" - echo "::set-output name=manifest::${ARCH}" - echo "${ARCH}" - - - # ----------------------------------------------------------------------------------------------- - # Job (2/3): BUILD - # ----------------------------------------------------------------------------------------------- - build: - needs: configure - name: Build PHP-${{ matrix.version }} (${{ matrix.arch }}) - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - version: - - ${{ fromJson(needs.configure.outputs.matrix_version) }} - arch: - - ${{ fromJson(needs.configure.outputs.matrix_arch) }} - # Only run for forks (contributor) - if: ${{ github.event.pull_request.head.repo.fork }} - steps: - # ------------------------------------------------------------ - # Setup repository - # ------------------------------------------------------------ - - name: "[SETUP] Checkout repository" - uses: actions/checkout@v2 - with: - fetch-depth: 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.7 - - # ------------------------------------------------------------ - # Build - # ------------------------------------------------------------ - - name: Build - uses: cytopia/shell-command-retry-action@v0.1.2 - with: - command: | - make build ARCH=${{ matrix.arch }} - - # ------------------------------------------------------------ - # Test - # ------------------------------------------------------------ - - name: "[TEST] Docker Image" - uses: cytopia/shell-command-retry-action@v0.1.2 - with: - command: | - make test ARCH=${{ matrix.arch }} - - - name: "[TEST] Update README" - uses: cytopia/shell-command-retry-action@v0.1.2 - with: - command: | - make update-readme ARCH=${{ matrix.arch }} - - - name: "[TEST] Verify README" - run: | - git diff --quiet || { echo "Build Changes"; git diff; git status; false; } diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index b6ddac8..f83d099 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -19,25 +19,4 @@ on: # ------------------------------------------------------------------------------------------------- jobs: lint: - name: "Lint" - runs-on: ubuntu-latest - if: github.actor != 'dependabot[bot]' - steps: - # ------------------------------------------------------------ - # Setup repository - # ------------------------------------------------------------ - - name: Checkout repository - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - - name: Output info - run: | - echo "${{ github.actor }}" - - # ------------------------------------------------------------ - # Lint repository - # ------------------------------------------------------------ - - name: Lint workflow - run: | - make lint-workflow + uses: devilbox/github-actions/.github/workflows/lint-generic.yml@master diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml deleted file mode 100644 index 1d8696f..0000000 --- a/.github/workflows/nightly.yml +++ /dev/null @@ -1,184 +0,0 @@ ---- - -# ------------------------------------------------------------------------------------------------- -# Job Name -# ------------------------------------------------------------------------------------------------- -name: nightly - - -# ------------------------------------------------------------------------------------------------- -# When to run -# ------------------------------------------------------------------------------------------------- -on: - # Runs daily - schedule: - - cron: '0 0 * * *' - -env: - MATRIX_VERSION: '["8.2"]' - MATRIX_ARCH: '["linux/amd64","linux/386","linux/arm64","linux/arm/v7","linux/arm/v6"]' - - -jobs: - - # ----------------------------------------------------------------------------------------------- - # Job (1/3): Configure Pipeline - # ----------------------------------------------------------------------------------------------- - configure: - name: Configure - runs-on: ubuntu-latest - outputs: - matrix_version: ${{ steps.set-matrix-version.outputs.matrix_version }} - matrix_arch: ${{ steps.set-matrix-arch.outputs.matrix_arch }} - manifest_arch: ${{ steps.set-manifest-arch.outputs.manifest }} - steps: - - - name: "[OUTPUT] Export Matrix 'Version'" - id: set-matrix-version - run: | - echo '::set-output name=matrix_version::${{ env.MATRIX_VERSION }}' - echo "${{ env.MATRIX_VERSION }}" - - - name: "[OUTPUT] Export Matrix 'Arch'" - id: set-matrix-arch - run: | - echo '::set-output name=matrix_arch::${{ env.MATRIX_ARCH }}' - echo "${{ env.MATRIX_ARCH }}" - - - name: "[OUTPUT] Export Manifest 'Arch'" - id: set-manifest-arch - run: | - ARCH="$( echo ${{ env.MATRIX_ARCH }} | sed 's/"//g' | sed 's/\[//g' | sed 's/\]//g' | sed 's/ //g' )" - echo "::set-output name=manifest::${ARCH}" - echo "${ARCH}" - - - # ----------------------------------------------------------------------------------------------- - # Job (2/3): BUILD - # ----------------------------------------------------------------------------------------------- - build: - needs: configure - name: Build PHP-${{ matrix.version }} (${{ matrix.arch }}) - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - version: - - ${{ fromJson(needs.configure.outputs.matrix_version) }} - arch: - - ${{ fromJson(needs.configure.outputs.matrix_arch) }} - refs: - - 'master' - - '0.4' - steps: - # ------------------------------------------------------------ - # Setup repository - # ------------------------------------------------------------ - - name: "[SETUP] Checkout repository" - uses: actions/checkout@v2 - with: - fetch-depth: 0 - ref: ${{ matrix.refs }} - - - 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.7 - - # ------------------------------------------------------------ - # Build - # ------------------------------------------------------------ - - name: Build - uses: cytopia/shell-command-retry-action@v0.1.2 - with: - command: | - make build ARCH=${{ matrix.arch }} - - # ------------------------------------------------------------ - # Test - # ------------------------------------------------------------ - - name: "[TEST] Docker Image" - uses: cytopia/shell-command-retry-action@v0.1.2 - with: - command: | - make test ARCH=${{ matrix.arch }} - - - name: "[TEST] Update README" - uses: cytopia/shell-command-retry-action@v0.1.2 - with: - command: | - make update-readme ARCH=${{ matrix.arch }} - - - name: "[TEST] Verify README" - run: | - git diff --quiet || { echo "Build Changes"; git diff; git status; false; } - - # ------------------------------------------------------------ - # Deploy - # ------------------------------------------------------------ - - name: "[DEPLOY] Login" - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_PASSWORD }} - - - name: "[DEPLOY] Publish architecture image" - uses: cytopia/shell-command-retry-action@v0.1.2 - with: - command: | - make push-arch TAG=${{ steps.tag.outputs.docker-tag }} ARCH=${{ matrix.arch }} - - # ----------------------------------------------------------------------------------------------- - # Job (3/3): DEPLOY - # ----------------------------------------------------------------------------------------------- - deploy: - needs: [configure, build] - name: Deploy - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - version: - - ${{ fromJson(needs.configure.outputs.matrix_version) }} - refs: - - 'master' - - '0.4' - steps: - # ------------------------------------------------------------ - # Setup repository - # ------------------------------------------------------------ - - name: "[SETUP] Checkout repository" - uses: actions/checkout@v2 - with: - fetch-depth: 0 - ref: ${{ matrix.refs }} - - - name: "[SETUP] Determine Docker tag" - id: tag - uses: cytopia/docker-tag-action@v0.4.7 - - # ------------------------------------------------------------ - # Deploy - # ------------------------------------------------------------ - - name: "[DEPLOY] Login" - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_PASSWORD }} - - - name: "[DEPLOY] Create Docker manifest" - uses: cytopia/shell-command-retry-action@v0.1.2 - with: - command: | - make manifest-create TAG=${{ steps.tag.outputs.docker-tag }} ARCH="${{ needs.configure.outputs.manifest_arch }}" - - - name: "[DEPLOY] Publish Docker manifest" - uses: cytopia/shell-command-retry-action@v0.1.2 - with: - command: | - make manifest-push TAG=${{ steps.tag.outputs.docker-tag }} diff --git a/.github/workflows/params.yml b/.github/workflows/params.yml new file mode 100644 index 0000000..6b2fe55 --- /dev/null +++ b/.github/workflows/params.yml @@ -0,0 +1,69 @@ +--- + +# ------------------------------------------------------------------------------------------------- +# Job Name +# ------------------------------------------------------------------------------------------------- +name: params + + +# ------------------------------------------------------------------------------------------------- +# Custom Variables +# ------------------------------------------------------------------------------------------------- +env: + MATRIX: >- + [ + { + "NAME": "PHP", + "VERSION": ["8.2"], + "ARCH": ["linux/amd64", "linux/386", "linux/arm64", "linux/arm/v7", "linux/arm/v6"] + } + ] + + +# ------------------------------------------------------------------------------------------------- +# 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/release-drafter.yml b/.github/workflows/release-drafter.yml new file mode 100644 index 0000000..1a63d7e --- /dev/null +++ b/.github/workflows/release-drafter.yml @@ -0,0 +1,19 @@ +--- +name: Release Drafter + +on: + push: + # branches to consider in the event; optional, defaults to all + branches: + - master + +jobs: + update_release_draft: + runs-on: ubuntu-latest + steps: + # Drafts your next Release notes as Pull Requests are merged into "master" + - uses: release-drafter/release-drafter@v5 + with: + publish: true + env: + GITHUB_TOKEN: ${{ secrets.RELEASE_DRAFTER_TOKEN }} diff --git a/.github/workflows/repository.yml b/.github/workflows/repository.yml new file mode 100644 index 0000000..ca21e7d --- /dev/null +++ b/.github/workflows/repository.yml @@ -0,0 +1,25 @@ +--- +name: Repository + +on: + push: + branches: + - master + paths: + - .github/labels.yml + +jobs: + labels: + name: Labels + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Sync labels + uses: micnncim/action-label-syncer@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + manifest: .github/labels.yml diff --git a/.gitignore b/.gitignore index cc3a8c2..7457dff 100644 --- a/.gitignore +++ b/.gitignore @@ -1,86 +1,2 @@ -# Note: -# To effectively apply the changes you will have -# to re-index the git index (if there are already -# commited files) -# -# $ git rm -r --cached . -# $ git add . -# $ git commit -m ".gitignore index rebuild" -# - - -###################################### -# CUSTOM -###################################### - - -###################################### -# 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 -*.shortcut - -###################################### -# Editors -###################################### - -###### Sublime ###### -*.sublime-workspace -*.sublime-project - -###### Eclipse ###### -.classpath -.buildpath -.project -.settings/ - -###### Netbeans ###### -/nbproject/ - -###### Intellij IDE ###### -.idea/ -.idea_modules/ - -###### vim ###### -*.swp -*.swo -*.swn -*.swm -*~ - -###### TextMate ###### -.tm_properties -*.tmproj - -###### BBEdit ###### -*.bbprojectd -*.bbproject - -.vagrant +Makefile.docker +Makefile.lint diff --git a/.yamllint b/.yamllint new file mode 100644 index 0000000..2c7758f --- /dev/null +++ b/.yamllint @@ -0,0 +1,13 @@ +--- +extends: default + +ignore: | + .yamllint + + +rules: + truthy: + allowed-values: ['true', 'false'] + check-keys: False + level: error + line-length: disable diff --git a/Dockerfile b/Dockerfile index 82d3ccc..ee5f7fb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -233,6 +233,7 @@ RUN docker-php-ext-enable sodium ENTRYPOINT ["docker-php-entrypoint"] WORKDIR /var/www/html +COPY data/php.ini /usr/local/etc/php/php.ini RUN set -eux; \ cd /usr/local/etc; \ diff --git a/Makefile b/Makefile index 4a413b2..4b8cb0c 100644 --- a/Makefile +++ b/Makefile @@ -2,17 +2,39 @@ ifneq (,) .error This Makefile requires GNU Make. endif +# 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 + # ------------------------------------------------------------------------------------------------- -# Docker configuration +# Default configuration # ------------------------------------------------------------------------------------------------- +# Own vars +TAG = latest + +# Makefile.docker overwrites +NAME = PHP +VERSION = 8.2 +IMAGE = devilbox/php-fpm-$(VERSION) +DIR = . +FILE = Dockerfile +DOCKER_TAG = $(TAG) +ARCH = linux/amd64 -DIR = . -FILE = Dockerfile -IMAGE = devilbox/php-fpm-8.2 -TAG = latest -ARCH = linux/amd64 -NO_CACHE = +# Makefile.lint overwrites +FL_IGNORES = .git/,.github/,tests/,data/ +SC_IGNORES = .git/,.github/,tests/ # ------------------------------------------------------------------------------------------------- @@ -20,124 +42,57 @@ NO_CACHE = # ------------------------------------------------------------------------------------------------- .PHONY: help help: - @echo "lint Lint project files and repository" + @echo "lint Lint project files and repository" @echo - @echo "build Build Docker image" - @echo "rebuild Build Docker image without cache" + @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 Create multi-arch manifest" - @echo "manifest-push Push multi-arch manifest" + @echo "manifest-create [ARCHES=...] [TAG=...] Create multi-arch manifest" + @echo "manifest-push [TAG=...] Push multi-arch manifest" @echo - @echo "test Test built Docker image" - @echo "update-readme Update README.md with PHP modules" + @echo "test [ARCH=...] Test built Docker image" @echo - @echo "tag [TAG=...] Retag Docker image" - @echo "login USER=... PASS=... Login to Docker hub" - @echo "push [TAG=...] Push Docker image to Docker hub" - - -# ------------------------------------------------------------------------------------------------- -# Lint Targets -# ------------------------------------------------------------------------------------------------- -.PHONY: lint -lint: lint-workflow - -.PHONY: lint-workflow -lint-workflow: - @\ - 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 ))"; \ - grep 'refs:' -A 20 .github/workflows/nightly.yml \ - | grep '^ -' \ - | grep -v master \ - | while read -r i; do \ - if ! echo "$${i}" | 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}"; \ - fi \ - done # ------------------------------------------------------------------------------------------------- -# Build Targets +# Docker Targets # ------------------------------------------------------------------------------------------------- .PHONY: build -build: - docker build --platform=$(ARCH) $(NO_CACHE) -t $(IMAGE) -f $(DIR)/$(FILE) $(DIR) +build: docker-arch-build .PHONY: rebuild -rebuild: NO_CACHE=--no-cache -rebuild: pull-base-image -rebuild: build +rebuild: docker-arch-rebuild + +.PHONY: push +push: docker-arch-push # ------------------------------------------------------------------------------------------------- # Manifest Targets # ------------------------------------------------------------------------------------------------- .PHONY: manifest-create -manifest-create: - @echo "docker manifest create \ - $(IMAGE):$(TAG) \ - $$( echo $(ARCH) | sed 's/,/ /g' | sed 's|/|-|g' | xargs -n1 sh -c 'printf -- " --amend $(IMAGE):$(TAG)-manifest-$${1}"' -- )" \ - | sed 's/\s\s*/ /g' \ - | sed 's/--/\\\n --/g' - @echo "docker manifest create \ - $(IMAGE):$(TAG) \ - $$( echo $(ARCH) | sed 's/,/ /g' | sed 's|/|-|g' | xargs -n1 sh -c 'printf -- " --amend $(IMAGE):$(TAG)-manifest-$${1}"' -- )" \ - | bash +manifest-create: docker-manifest-create .PHONY: manifest-push -manifest-push: - docker manifest push $(IMAGE):$(TAG) +manifest-push: docker-manifest-push # ------------------------------------------------------------------------------------------------- # Test Targets # ------------------------------------------------------------------------------------------------- .PHONY: test -test: - ./tests/test.sh $(IMAGE) $(ARCH) +test: _test-integration +test: update-readme + +.PHONY: _test-integration +_test-integration: + ./tests/start-ci.sh $(IMAGE) $(NAME) $(VERSION) $(DOCKER_TAG) $(ARCH) .PHONY: update-readme update-readme: cat "./README.md" \ - | perl -0 -pe "s/.*/\n$$(./tests/get-modules.sh $(IMAGE) $(ARCH))\n/s" \ + | perl -0 -pe "s/.*/\n$$(./tests/get-modules.sh $(IMAGE) $(NAME) $(VERSION) $(DOCKER_TAG) $(ARCH))\n/s" \ > "./README.md.tmp" yes | mv -f "./README.md.tmp" "./README.md" - - -# ------------------------------------------------------------------------------------------------- -# Deploy Targets -# ------------------------------------------------------------------------------------------------- -.PHONY: tag -tag: - docker tag $(IMAGE) $(IMAGE):$(TAG) - -.PHONY: login -login: - yes | docker login --username $(USER) --password $(PASS) - -.PHONY: push -push: - @$(MAKE) tag TAG=$(TAG) - docker push $(IMAGE):$(TAG) - -.PHONY: push-arch -push-arch: - $(MAKE) tag TAG=$(TAG)-manifest-$(subst /,-,$(ARCH)) - docker push $(IMAGE):$(TAG)-manifest-$(subst /,-,$(ARCH)) - - -# ------------------------------------------------------------------------------------------------- -# Helper Targets -# ------------------------------------------------------------------------------------------------- -.PHONY: enter -enter: - docker run --rm --platform=$(ARCH) -it --entrypoint=bash $(ARG) $(IMAGE) - -.PHONY: pull-base-image -pull-base-image: - @docker pull $(shell grep FROM Dockerfile | sed 's/^FROM\s*//g';) + git diff --quiet || { echo "Build Changes"; git diff; git status; false; } diff --git a/data/php.ini b/data/php.ini new file mode 100644 index 0000000..fa1dff6 --- /dev/null +++ b/data/php.ini @@ -0,0 +1,13 @@ +;xmlrpc_errors = on +;html_errors = on +;track_errors = on +display_errors = on +;display_startup_errors = on +;error_reporting = E_ALL | E_STRICT +error_reporting = E_ALL +log_errors = on +error_log = /usr/local/logs/php.log +date.timezone = UTC +variables_order = "EGPCS" +cgi.fix_pathinfo= 0 +fastcgi.logging = 1 diff --git a/tests/01-version.sh b/tests/01-version.sh new file mode 100755 index 0000000..24d2944 --- /dev/null +++ b/tests/01-version.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +set -eu +set -o pipefail + +IMAGE="${1}" +#NAME="${2}" +VERSION="${3}" +TAG="${4}" +ARCH="${5}" + + +echo +echo "\$ docker run --rm --platform ${ARCH} --entrypoint=php ${IMAGE}:${TAG} -v | grep -E '^PHP ${VERSION}'" +docker run --rm --platform "${ARCH}" --entrypoint=php "${IMAGE}:${TAG}" -v | grep -E "^PHP ${VERSION}" +echo + +echo +echo "\$ docker run --rm --platform ${ARCH} --entrypoint=php-fpm ${IMAGE}:${TAG} -v | grep -E '^PHP ${VERSION}'" +docker run --rm --platform "${ARCH}" --entrypoint=php-fpm "${IMAGE}:${TAG}" -v | grep -E "^PHP ${VERSION}" +echo diff --git a/tests/02-server-index.php.sh b/tests/02-server-index.php.sh new file mode 100755 index 0000000..051da33 --- /dev/null +++ b/tests/02-server-index.php.sh @@ -0,0 +1,256 @@ +#!/usr/bin/env bash +set -eu +set -o pipefail + +IMAGE="${1}" +#NAME="${2}" +VERSION="${3}" +TAG="${4}" +ARCH="${5}" + + + +### +### Variables +### +WWW_PORT="81" +DOC_ROOT_HOST="$( mktemp -d )" +DOC_ROOT_CONT="/var/www/default" + +CONFIG_HOST="$( mktemp -d )" +CONFIG_CONT="/etc/nginx/conf.d" + +NAME_PHP="devilbox-php-fpm-${VERSION}" + +NAME_WEB="nginx-stable-devilbox" +CONT_WEB="nginx:stable" + + +### +### Create required files +### + +# PHP Index File +{ + echo ' "${DOC_ROOT_HOST}/index.php" +# PHP Error File +{ + echo ' "${DOC_ROOT_HOST}/error.php" + +# Nginx conf +{ + echo "server {" + echo " server_name _;" + echo " listen 80;" + echo " root ${DOC_ROOT_CONT};" + echo " index index.php;" + echo " location ~* \.php\$ {" + echo " fastcgi_index index.php;" + echo " fastcgi_pass ${NAME_PHP}:9000;" + echo " include fastcgi_params;" + echo " fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;" + echo " fastcgi_param SCRIPT_NAME \$fastcgi_script_name;" + echo " }" + echo "}" +} > "${CONFIG_HOST}/php.conf" + + +### +### Fix mount permissions +### +chmod 0777 "${CONFIG_HOST}" +chmod 0777 "${DOC_ROOT_HOST}" +chmod 0644 "${DOC_ROOT_HOST}/index.php" +chmod 0644 "${DOC_ROOT_HOST}/error.php" + + +### +### Start containers +### +PHP_DID="$( docker run -d --platform "${ARCH}" --name "${NAME_PHP}" -v "${DOC_ROOT_HOST}:${DOC_ROOT_CONT}" "${IMAGE}:${TAG}" )" +sleep 4 +WEB_DID="$( docker run -d --platform "${ARCH}" --name "${NAME_WEB}" -v "${DOC_ROOT_HOST}:${DOC_ROOT_CONT}" -v "${CONFIG_HOST}:${CONFIG_CONT}" -p "${WWW_PORT}:80" --link "${NAME_PHP}" "${CONT_WEB}" )" +sleep 4 + + +### +### Test PHP ini +### +#docker exec "${PHP_DID}" + +### +### Test for PHP success +### +echo "[TEST] curl index.php:" +echo "------------------------------------" +if ! curl -sS 127.0.0.1:${WWW_PORT}/index.php 2>/dev/null | grep 'itworks'; then + echo "[FAILED], could not connect to index.php" + echo + + echo "index.php:" + echo "------------------------------------" + cat "${DOC_ROOT_HOST}/index.php" + echo + + echo "curl:" + echo "------------------------------------" + curl -v 127.0.0.1:${WWW_PORT}/index.php + echo + + echo "docker logs php" + echo "------------------------------------" + docker logs "${PHP_DID}" + echo + + echo "docker logs web" + echo "------------------------------------" + docker logs "${WEB_DID}" + echo + + docker stop "${WEB_DID}" || true + docker stop "${PHP_DID}" || true + + docker rm -f "${NAME_WEB}" || true + docker rm -f "${NAME_PHP}" || true + + rm -rf "${DOC_ROOT_HOST}" + rm -rf "${CONFIG_HOST}" + exit 1 +fi +echo "[SUCCESS]" +echo + +### +### Test for Docker access logs +### +echo "[TEST] docker logs 'GET /index.php':" +echo "------------------------------------" +if ! docker logs "${WEB_DID}" 2>&1 | grep 'GET /index.php'; then + echo "[FAILED], could not find access requests in docker logs." + echo + + echo "docker logs php" + echo "------------------------------------" + docker logs "${PHP_DID}" + echo + + echo "docker logs web" + echo "------------------------------------" + docker logs "${WEB_DID}" + echo + + docker stop "${WEB_DID}" || true + docker stop "${PHP_DID}" || true + + docker rm -f "${NAME_WEB}" || true + docker rm -f "${NAME_PHP}" || true + + rm -rf "${DOC_ROOT_HOST}" + rm -rf "${CONFIG_HOST}" + exit 1 +fi +echo "[SUCCESS]" +echo + + +### +### Test for PHP errors +### +echo "[TEST] curl error.php:" +echo "------------------------------------" +if ! curl -sS 127.0.0.1:${WWW_PORT}/error.php 2>/dev/null | grep 'syntax error'; then + echo "[FAILED], could not connect to error.php" + echo + + echo "error.php:" + echo "------------------------------------" + cat "${DOC_ROOT_HOST}/index.php" + echo + + echo "curl:" + echo "------------------------------------" + curl -v 127.0.0.1:${WWW_PORT}/error.php + echo + + echo "docker logs php" + echo "------------------------------------" + docker logs "${PHP_DID}" + echo + + echo "docker logs web" + echo "------------------------------------" + docker logs "${WEB_DID}" + echo + + docker stop "${WEB_DID}" || true + docker stop "${PHP_DID}" || true + + docker rm -f "${NAME_WEB}" || true + docker rm -f "${NAME_PHP}" || true + + rm -rf "${DOC_ROOT_HOST}" + rm -rf "${CONFIG_HOST}" + exit 1 +fi +echo "[SUCCESS]" +echo + +### +### Test for Docker error logs +### +echo "[TEST] docker logs 'syntax error':" +echo "------------------------------------" + +if ! docker logs "${WEB_DID}" 2>&1 | grep 'syntax error'; then + echo "[FAILED], could not find error message in docker logs." + echo + + echo "docker logs php" + echo "------------------------------------" + docker logs "${PHP_DID}" + echo + + echo "docker logs web" + echo "------------------------------------" + docker logs "${WEB_DID}" + echo + + docker stop "${WEB_DID}" || true + docker stop "${PHP_DID}" || true + + docker rm -f "${NAME_WEB}" || true + docker rm -f "${NAME_PHP}" || true + + rm -rf "${DOC_ROOT_HOST}" + rm -rf "${CONFIG_HOST}" + exit 1 +fi +echo "[SUCCESS]" +echo + + +### +### Clean-up +### +echo "[CLEANUP] shutdown:" +echo "------------------------------------" +docker stop "${WEB_DID}" >/dev/null 2>&1 || true +docker stop "${PHP_DID}" >/dev/null 2>&1 || true + +docker rm -f "${NAME_WEB}" >/dev/null 2>&1 || true +docker rm -f "${NAME_PHP}" >/dev/null 2>&1 || true + +rm -rf "${DOC_ROOT_HOST}" >/dev/null 2>&1 || true +rm -rf "${CONFIG_HOST}" >/dev/null 2>&1 || true + +exit 0 diff --git a/tests/get-modules.sh b/tests/get-modules.sh index adacaa5..641444b 100755 --- a/tests/get-modules.sh +++ b/tests/get-modules.sh @@ -4,10 +4,14 @@ set -e set -u set -o pipefail -IMAGE="${1:-devilbox/php-fpm-8.2}" -ARCH="${2:-linux/amd64}" -MODULES="$( docker run --rm -t --platform "${ARCH}" --entrypoint=php "${IMAGE}" -m \ +IMAGE="${1}" +#NAME="${2}" +#VERSION="${3}" +TAG="${4}" +ARCH="${5}" + +MODULES="$( docker run --rm -t --platform "${ARCH}" --entrypoint=php "${IMAGE}:${TAG}" -m \ | grep -vE '(^\[)|(^\s*$)' \ | sort -u -f )" diff --git a/tests/start-ci.sh b/tests/start-ci.sh new file mode 100755 index 0000000..1777030 --- /dev/null +++ b/tests/start-ci.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash + +set -e +set -u +set -o pipefail + +### +### Variables +### + +IFS=$'\n' + +# Current directory +CWD="$( dirname "${0}" )" +IMAGE="${1}" +NAME="${2}" +VERSION="${3}" +TAG="${4}" +ARCH="${5}" + +declare -a TESTS=() + + + + +### +### Run tests +### + +# Get all [0-9]+.sh test files +FILES="$( find "${CWD}" -regex "${CWD}/[0-9].+\.sh" | sort -u )" +for f in ${FILES}; do + TESTS+=("${f}") +done + +# Start a single test +if [ "${#}" -eq "3" ]; then + sh -c "${TESTS[${2}]} ${IMAGE} ${NAME} ${VERSION} ${TAG} ${ARCH}" + +# Run all tests +else + for i in "${TESTS[@]}"; do + echo "################################################################################" + echo "# [${CWD}/${i}] ${IMAGE}:${TAG} ${NAME}-${VERSION} (${ARCH})" + echo "################################################################################" + sh -c "${i} ${IMAGE} ${NAME} ${VERSION} ${TAG} ${ARCH}" + done +fi diff --git a/tests/test.sh b/tests/test.sh deleted file mode 100755 index 778213e..0000000 --- a/tests/test.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -u -set -o pipefail - -IMAGE="${1:-devilbox/php-fpm-8.2}" -ARCH="${2:-linux/amd64}" - -echo -echo "\$ docker run --rm --platform ${ARCH} --entrypoint=php ${IMAGE} -v | grep -E '^PHP 8\.2'" -docker run --rm --platform "${ARCH}" --entrypoint=php "${IMAGE}" -v | grep -E '^PHP 8\.2' - -echo -echo "\$ docker run --rm --platform ${ARCH} --entrypoint=php-fpm ${IMAGE} -v | grep -E '^PHP 8\.2'" -docker run --rm --platform "${ARCH}" --entrypoint=php-fpm "${IMAGE}" -v | grep -E '^PHP 8\.2'