--- name: Docker on: # See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_dispatch workflow_dispatch: # See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#push push: branches: - dev - staging tags: - "*" # See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request pull_request: types: - opened - reopened - synchronize jobs: lint: name: hadolint runs-on: ubuntu-latest permissions: contents: read steps: - name: Checkout Code uses: actions/checkout@v4 - name: Docker Lint uses: hadolint/hadolint-action@v3.1.0 with: dockerfile: Dockerfile failure-threshold: error shellcheck: name: ShellCheck runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Run ShellCheck uses: ludeeus/action-shellcheck@master env: SHELLCHECK_OPTS: --shell=bash --external-sources with: version: v0.9.0 additional_files: "*.envsh .env .env.docker .env.example .env.testing" bats: name: Bats Testing runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Run bats run: docker run -v "$PWD:/var/www" bats/bats:latest /var/www/tests/bats build: name: Build, Test, and Push runs-on: ubuntu-latest strategy: fail-fast: false # See: https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs matrix: php_version: - 8.2 - 8.3 target_runtime: - apache - fpm - nginx php_base: - apache - fpm # See: https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs#excluding-matrix-configurations # See: https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategymatrixexclude exclude: # targeting [apache] runtime with [fpm] base type doesn't make sense - target_runtime: apache php_base: fpm # targeting [fpm] runtime with [apache] base type doesn't make sense - target_runtime: fpm php_base: apache # targeting [nginx] runtime with [apache] base type doesn't make sense - target_runtime: nginx php_base: apache # See: https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#example-using-concurrency-and-the-default-behavior concurrency: group: docker-build-${{ github.ref }}-${{ matrix.php_base }}-${{ matrix.php_version }}-${{ matrix.target_runtime }} cancel-in-progress: true permissions: contents: read packages: write env: # Set the repo variable [DOCKER_HUB_USERNAME] to override the default # at https://github.com/<user>/<project>/settings/variables/actions DOCKER_HUB_USERNAME: ${{ vars.DOCKER_HUB_USERNAME || 'pixelfed' }} # Set the repo variable [DOCKER_HUB_ORGANISATION] to override the default # at https://github.com/<user>/<project>/settings/variables/actions DOCKER_HUB_ORGANISATION: ${{ vars.DOCKER_HUB_ORGANISATION || 'pixelfed' }} # Set the repo variable [DOCKER_HUB_REPO] to override the default # at https://github.com/<user>/<project>/settings/variables/actions DOCKER_HUB_REPO: ${{ vars.DOCKER_HUB_REPO || 'pixelfed' }} # For Docker Hub pushing to work, you need the secret [DOCKER_HUB_TOKEN] # set to your Personal Access Token at https://github.com/<user>/<project>/settings/secrets/actions # # ! NOTE: no [login] or [push] will happen to Docker Hub until this secret is set! HAS_DOCKER_HUB_CONFIGURED: ${{ secrets.DOCKER_HUB_TOKEN != '' }} steps: - name: Checkout Code uses: actions/checkout@v4 - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 id: buildx with: version: v0.12.0 # *or* newer, needed for annotations to work # See: https://github.com/docker/login-action?tab=readme-ov-file#github-container-registry - name: Log in to the GitHub Container registry uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} # See: https://github.com/docker/login-action?tab=readme-ov-file#docker-hub - name: Login to Docker Hub registry (conditionally) if: ${{ env.HAS_DOCKER_HUB_CONFIGURED == true }} uses: docker/login-action@v3 with: username: ${{ env.DOCKER_HUB_USERNAME }} password: ${{ secrets.DOCKER_HUB_TOKEN }} - name: Docker meta uses: docker/metadata-action@v5 id: meta with: images: | name=ghcr.io/${{ github.repository }},enable=true name=${{ env.DOCKER_HUB_ORGANISATION }}/${{ env.DOCKER_HUB_REPO }},enable=${{ env.HAS_DOCKER_HUB_CONFIGURED }} flavor: | latest=auto suffix=-${{ matrix.target_runtime }}-${{ matrix.php_version }} tags: | type=raw,value=dev,enable=${{ github.ref == format('refs/heads/{0}', 'dev') }} type=raw,value=staging,enable=${{ github.ref == format('refs/heads/{0}', 'staging') }} type=pep440,pattern={{raw}} type=pep440,pattern=v{{major}}.{{minor}} type=ref,event=branch,prefix=branch- type=ref,event=pr,prefix=pr- type=ref,event=tag env: DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index - name: Docker meta (Cache) uses: docker/metadata-action@v5 id: cache with: images: | name=ghcr.io/${{ github.repository }}-cache,enable=true name=${{ env.DOCKER_HUB_ORGANISATION }}/${{ env.DOCKER_HUB_REPO }}-cache,enable=${{ env.HAS_DOCKER_HUB_CONFIGURED }} flavor: | latest=auto suffix=-${{ matrix.target_runtime }}-${{ matrix.php_version }} tags: | type=raw,value=dev,enable=${{ github.ref == format('refs/heads/{0}', 'dev') }} type=raw,value=staging,enable=${{ github.ref == format('refs/heads/{0}', 'staging') }} type=pep440,pattern={{raw}} type=pep440,pattern=v{{major}}.{{minor}} type=ref,event=branch,prefix=branch- type=ref,event=pr,prefix=pr- type=ref,event=tag env: DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index - name: Build and push Docker image uses: docker/build-push-action@v5 with: context: . file: Dockerfile target: ${{ matrix.target_runtime }}-runtime platforms: linux/amd64,linux/arm64 builder: ${{ steps.buildx.outputs.name }} tags: ${{ steps.meta.outputs.tags }} annotations: ${{ steps.meta.outputs.annotations }} push: true sbom: true provenance: true build-args: | PHP_VERSION=${{ matrix.php_version }} PHP_BASE_TYPE=${{ matrix.php_base }} cache-from: | type=gha,scope=${{ matrix.target_runtime }}-${{ matrix.php_base }}-${{ matrix.php_version }} cache-to: | type=gha,mode=max,scope=${{ matrix.target_runtime }}-${{ matrix.php_base }}-${{ matrix.php_version }} ${{ steps.cache.outputs.tags }} # goss validate the image # # See: https://github.com/goss-org/goss - uses: e1himself/goss-installation-action@v1 with: version: "v0.4.4" - name: Execute Goss tests run: | dgoss run \ -v "./.env.testing:/var/www/.env" \ -e "EXPECTED_PHP_VERSION=${{ matrix.php_version }}" \ -e "PHP_BASE_TYPE=${{ matrix.php_base }}" \ ${{ steps.meta.outputs.tags }}