Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .github/actions/create-manifest-list/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# https://docs.github.com/en/actions/creating-actions/creating-a-composite-action
# https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#inputs
# https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#runs-for-composite-run-steps-actions

name: "Create and push manifest lists"

description: "Creates a multi-platform manifest list per image from pushed digests and tags it using docker/metadata-action JSON output."

inputs:
metadata-json:
description: "JSON output of docker/metadata-action"
required: true
digests-directory:
description: "Directory containing one empty file per pushed digest, named after its sha256 hex"
required: true
images:
description: "Newline-separated list of image names to create manifest lists for"
required: true

runs:
using: "composite"

steps:
- name: "Create and push manifest lists"
run: |
mapfile -t slugs <<< "$IMAGES"
for slug in "${slugs[@]}"; do
[ -n "$slug" ] || continue
mapfile -t tags < <(jq -r --arg slug "$slug" '.tags[] | select(startswith($slug)) | "--tag=" + .' <<< "$JSON")
sources=()
for digest in *; do
sources+=("$slug@sha256:$digest")
done
docker buildx imagetools create "${tags[@]}" "${sources[@]}"
done
shell: "bash"
working-directory: "${{ inputs.digests-directory }}"
env:
IMAGES: ${{ inputs.images }}
JSON: ${{ inputs.metadata-json }}
8 changes: 0 additions & 8 deletions .github/dependabot.yml

This file was deleted.

83 changes: 47 additions & 36 deletions .github/renovate.json
Original file line number Diff line number Diff line change
@@ -1,85 +1,96 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"rebaseWhen": "behind-base-branch",
"labels": [
"dependencies"
],
"extends": [
"config:recommended"
"config:recommended",
"helpers:pinGitHubActionDigests"
],
"separateMinorPatch": true,
"packageRules": [
{
"matchPackageNames": [
"*"
],
"dependencyDashboardApproval": false
"description": "Batch action updates (each one triggers full multi-arch builds) and add a cooldown",
"matchManagers": [
"github-actions"
],
"matchUpdateTypes": [
"minor",
"patch",
"digest"
],
"groupName": "GitHub Actions",
"minimumReleaseAge": "7 days"
},
{
"matchPackageNames": [
"composer/composer"
],
"enabled": true
"separateMinorPatch": true
},
{
"description": "Disables major and minor updates for composer/composer in 2.2",
"description": "2.2 is LTS: patch releases only",
"matchFileNames": [
"2.2/Dockerfile"
],
"matchPackageNames": [
"composer/composer"
],
"matchUpdateTypes": [
"major",
"minor"
"allowedVersions": "<2.3.0",
"commitMessageSuffix": " (2.2)",
"additionalBranchPrefix": "2.2-"
},
{
"matchFileNames": [
"latest/Dockerfile"
],
"enabled": false
"matchPackageNames": [
"composer/composer"
],
"commitMessageSuffix": " (Latest)",
"additionalBranchPrefix": "latest-"
},
{
"description": "Enables patch updates for composer/composer in 2.2",
"description": "A new Composer major needs manual follow-up",
"matchFileNames": [
"2.2/Dockerfile"
"latest/Dockerfile"
],
"matchPackageNames": [
"composer/composer"
],
"matchUpdateTypes": [
"patch"
"major"
],
"commitMessageSuffix": " (2.2)",
"additionalBranchPrefix": "2.2-",
"enabled": true
"prBodyNotes": [
"⚠️ New major: update aliases in `generate-stackbrew-library.sh` and consider creating an LTS directory for the previous major."
]
},
{
"description": "Legacy/LTS images stay on PHP 8",
"matchFileNames": [
"latest/Dockerfile"
"1.10/Dockerfile",
"2.2/Dockerfile"
],
"matchDatasources": [
"docker"
],
"matchPackageNames": [
"composer/composer"
"php"
],
"commitMessageSuffix": " (Latest)",
"additionalBranchPrefix": "latest-"
"matchUpdateTypes": [
"major"
],
"enabled": false
}
],
"customManagers": [
{
"customType": "regex",
"description": "Composer version in maintained Dockerfiles (1.10 is frozen)",
"managerFilePatterns": [
"/latest/Dockerfile$/"
],
"matchStrings": [
"ENV COMPOSER_VERSION=[\"']?(?<currentValue>\\d+\\.\\d+\\.\\d+)[\"']?\\s+"
],
"datasourceTemplate": "github-releases",
"depNameTemplate": "composer/composer"
},
{
"customType": "regex",
"managerFilePatterns": [
"/2.2/Dockerfile$/"
"/^(latest|2\\.2)/Dockerfile$/"
],
"matchStrings": [
"ENV COMPOSER_VERSION=[\"']?(?<currentValue>\\d+\\.\\d+\\.\\d+)[\"']?\\s+"
"ENV COMPOSER_VERSION=[\"']?(?<currentValue>\\d+\\.\\d+\\.\\d+(?:-RC\\d+)?)[\"']?\\s"
],
"datasourceTemplate": "github-releases",
"depNameTemplate": "composer/composer"
Expand Down
39 changes: 19 additions & 20 deletions .github/workflows/1.10.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ jobs:

- name: Determine Composer version from Dockerfile
id: composer-version
# "$/" = this repository at the running commit (no checkout needed), see https://github.blog/changelog/2026-07-30-reference-same-repository-actions-with-self-repository-syntax
uses: $/.github/actions/determine-composer-version
with:
working-directory: ${{ env.DIRECTORY }}
Expand Down Expand Up @@ -172,6 +173,7 @@ jobs:
context: ${{ env.DIRECTORY }}
target: binary-with-runtime
annotations: ${{ needs.prepare.outputs.full-annotations }}
labels: ${{ needs.prepare.outputs.full-labels }}
platforms: ${{ matrix.platform }}
outputs: type=image,"name=${{ env.DOCKERHUB_SLUG }},${{ env.ECR_SLUG }},${{ env.GHCR_SLUG }}",push-by-digest=true,name-canonical=true,push=${{ github.ref == 'refs/heads/main' && github.event_name != 'pull_request' }}

Expand All @@ -182,6 +184,7 @@ jobs:
context: ${{ env.DIRECTORY }}
target: standalone-binary
annotations: ${{ needs.prepare.outputs.bin-annotations }}
labels: ${{ needs.prepare.outputs.bin-labels }}
platforms: ${{ matrix.platform }}
outputs: type=image,"name=${{ env.DOCKERHUB_SLUG }},${{ env.ECR_SLUG }},${{ env.GHCR_SLUG }}",push-by-digest=true,name-canonical=true,push=${{ github.ref == 'refs/heads/main' && github.event_name != 'pull_request' }}

Expand Down Expand Up @@ -252,25 +255,21 @@ jobs:
password: ${{ secrets.GITHUB_TOKEN }}

- name: Create manifest list for full image and push
working-directory: /tmp/digests/full
env:
JSON: ${{ needs.prepare.outputs.full-json }}
run: |
docker buildx imagetools create $(jq -cr --arg slug "$DOCKERHUB_SLUG" '.tags | map(select(startswith($slug)) | "--tag " + .) | join(" ")' <<< "$JSON") \
$(printf "$DOCKERHUB_SLUG@sha256:%s " *)
docker buildx imagetools create $(jq -cr --arg slug "$ECR_SLUG" '.tags | map(select(startswith($slug)) | "--tag " + .) | join(" ")' <<< "$JSON") \
$(printf "$ECR_SLUG@sha256:%s " *)
docker buildx imagetools create $(jq -cr --arg slug "$GHCR_SLUG" '.tags | map(select(startswith($slug)) | "--tag " + .) | join(" ")' <<< "$JSON") \
$(printf "$GHCR_SLUG@sha256:%s " *)
uses: $/.github/actions/create-manifest-list
with:
metadata-json: ${{ needs.prepare.outputs.full-json }}
digests-directory: /tmp/digests/full
images: |
${{ env.DOCKERHUB_SLUG }}
${{ env.ECR_SLUG }}
${{ env.GHCR_SLUG }}

- name: Create manifest list for binary-only image and push
working-directory: /tmp/digests/bin
env:
JSON: ${{ needs.prepare.outputs.bin-json }}
run: |
docker buildx imagetools create $(jq -cr --arg slug "$DOCKERHUB_SLUG" '.tags | map(select(startswith($slug)) | "--tag " + .) | join(" ")' <<< "$JSON") \
$(printf "$DOCKERHUB_SLUG@sha256:%s " *)
docker buildx imagetools create $(jq -cr --arg slug "$ECR_SLUG" '.tags | map(select(startswith($slug)) | "--tag " + .) | join(" ")' <<< "$JSON") \
$(printf "$ECR_SLUG@sha256:%s " *)
docker buildx imagetools create $(jq -cr --arg slug "$GHCR_SLUG" '.tags | map(select(startswith($slug)) | "--tag " + .) | join(" ")' <<< "$JSON") \
$(printf "$GHCR_SLUG@sha256:%s " *)
uses: $/.github/actions/create-manifest-list
with:
metadata-json: ${{ needs.prepare.outputs.bin-json }}
digests-directory: /tmp/digests/bin
images: |
${{ env.DOCKERHUB_SLUG }}
${{ env.ECR_SLUG }}
${{ env.GHCR_SLUG }}
39 changes: 19 additions & 20 deletions .github/workflows/2.2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ jobs:

- name: Determine Composer version from Dockerfile
id: composer-version
# "$/" = this repository at the running commit (no checkout needed), see https://github.blog/changelog/2026-07-30-reference-same-repository-actions-with-self-repository-syntax
uses: $/.github/actions/determine-composer-version
with:
working-directory: ${{ env.DIRECTORY }}
Expand Down Expand Up @@ -172,6 +173,7 @@ jobs:
context: ${{ env.DIRECTORY }}
target: binary-with-runtime
annotations: ${{ needs.prepare.outputs.full-annotations }}
labels: ${{ needs.prepare.outputs.full-labels }}
platforms: ${{ matrix.platform }}
outputs: type=image,"name=${{ env.DOCKERHUB_SLUG }},${{ env.ECR_SLUG }},${{ env.GHCR_SLUG }}",push-by-digest=true,name-canonical=true,push=${{ github.ref == 'refs/heads/main' && github.event_name != 'pull_request' }}

Expand All @@ -182,6 +184,7 @@ jobs:
context: ${{ env.DIRECTORY }}
target: standalone-binary
annotations: ${{ needs.prepare.outputs.bin-annotations }}
labels: ${{ needs.prepare.outputs.bin-labels }}
platforms: ${{ matrix.platform }}
outputs: type=image,"name=${{ env.DOCKERHUB_SLUG }},${{ env.ECR_SLUG }},${{ env.GHCR_SLUG }}",push-by-digest=true,name-canonical=true,push=${{ github.ref == 'refs/heads/main' && github.event_name != 'pull_request' }}

Expand Down Expand Up @@ -252,25 +255,21 @@ jobs:
password: ${{ secrets.GITHUB_TOKEN }}

- name: Create manifest list for full image and push
working-directory: /tmp/digests/full
env:
JSON: ${{ needs.prepare.outputs.full-json }}
run: |
docker buildx imagetools create $(jq -cr --arg slug "$DOCKERHUB_SLUG" '.tags | map(select(startswith($slug)) | "--tag " + .) | join(" ")' <<< "$JSON") \
$(printf "$DOCKERHUB_SLUG@sha256:%s " *)
docker buildx imagetools create $(jq -cr --arg slug "$ECR_SLUG" '.tags | map(select(startswith($slug)) | "--tag " + .) | join(" ")' <<< "$JSON") \
$(printf "$ECR_SLUG@sha256:%s " *)
docker buildx imagetools create $(jq -cr --arg slug "$GHCR_SLUG" '.tags | map(select(startswith($slug)) | "--tag " + .) | join(" ")' <<< "$JSON") \
$(printf "$GHCR_SLUG@sha256:%s " *)
uses: $/.github/actions/create-manifest-list
with:
metadata-json: ${{ needs.prepare.outputs.full-json }}
digests-directory: /tmp/digests/full
images: |
${{ env.DOCKERHUB_SLUG }}
${{ env.ECR_SLUG }}
${{ env.GHCR_SLUG }}

- name: Create manifest list for binary-only image and push
working-directory: /tmp/digests/bin
env:
JSON: ${{ needs.prepare.outputs.bin-json }}
run: |
docker buildx imagetools create $(jq -cr --arg slug "$DOCKERHUB_SLUG" '.tags | map(select(startswith($slug)) | "--tag " + .) | join(" ")' <<< "$JSON") \
$(printf "$DOCKERHUB_SLUG@sha256:%s " *)
docker buildx imagetools create $(jq -cr --arg slug "$ECR_SLUG" '.tags | map(select(startswith($slug)) | "--tag " + .) | join(" ")' <<< "$JSON") \
$(printf "$ECR_SLUG@sha256:%s " *)
docker buildx imagetools create $(jq -cr --arg slug "$GHCR_SLUG" '.tags | map(select(startswith($slug)) | "--tag " + .) | join(" ")' <<< "$JSON") \
$(printf "$GHCR_SLUG@sha256:%s " *)
uses: $/.github/actions/create-manifest-list
with:
metadata-json: ${{ needs.prepare.outputs.bin-json }}
digests-directory: /tmp/digests/bin
images: |
${{ env.DOCKERHUB_SLUG }}
${{ env.ECR_SLUG }}
${{ env.GHCR_SLUG }}
39 changes: 19 additions & 20 deletions .github/workflows/latest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ jobs:

- name: Determine Composer version from Dockerfile
id: composer-version
# "$/" = this repository at the running commit (no checkout needed), see https://github.blog/changelog/2026-07-30-reference-same-repository-actions-with-self-repository-syntax
uses: $/.github/actions/determine-composer-version
with:
working-directory: ${{ env.DIRECTORY }}
Expand Down Expand Up @@ -176,6 +177,7 @@ jobs:
context: ${{ env.DIRECTORY }}
target: binary-with-runtime
annotations: ${{ needs.prepare.outputs.full-annotations }}
labels: ${{ needs.prepare.outputs.full-labels }}
platforms: ${{ matrix.platform }}
outputs: type=image,"name=${{ env.DOCKERHUB_SLUG }},${{ env.ECR_SLUG }},${{ env.GHCR_SLUG }}",push-by-digest=true,name-canonical=true,push=${{ github.ref == 'refs/heads/main' && github.event_name != 'pull_request' }}

Expand All @@ -186,6 +188,7 @@ jobs:
context: ${{ env.DIRECTORY }}
target: standalone-binary
annotations: ${{ needs.prepare.outputs.bin-annotations }}
labels: ${{ needs.prepare.outputs.bin-labels }}
platforms: ${{ matrix.platform }}
outputs: type=image,"name=${{ env.DOCKERHUB_SLUG }},${{ env.ECR_SLUG }},${{ env.GHCR_SLUG }}",push-by-digest=true,name-canonical=true,push=${{ github.ref == 'refs/heads/main' && github.event_name != 'pull_request' }}

Expand Down Expand Up @@ -256,25 +259,21 @@ jobs:
password: ${{ secrets.GITHUB_TOKEN }}

- name: Create manifest list for full image and push
working-directory: /tmp/digests/full
env:
JSON: ${{ needs.prepare.outputs.full-json }}
run: |
docker buildx imagetools create $(jq -cr --arg slug "$DOCKERHUB_SLUG" '.tags | map(select(startswith($slug)) | "--tag " + .) | join(" ")' <<< "$JSON") \
$(printf "$DOCKERHUB_SLUG@sha256:%s " *)
docker buildx imagetools create $(jq -cr --arg slug "$ECR_SLUG" '.tags | map(select(startswith($slug)) | "--tag " + .) | join(" ")' <<< "$JSON") \
$(printf "$ECR_SLUG@sha256:%s " *)
docker buildx imagetools create $(jq -cr --arg slug "$GHCR_SLUG" '.tags | map(select(startswith($slug)) | "--tag " + .) | join(" ")' <<< "$JSON") \
$(printf "$GHCR_SLUG@sha256:%s " *)
uses: $/.github/actions/create-manifest-list
with:
metadata-json: ${{ needs.prepare.outputs.full-json }}
digests-directory: /tmp/digests/full
images: |
${{ env.DOCKERHUB_SLUG }}
${{ env.ECR_SLUG }}
${{ env.GHCR_SLUG }}

- name: Create manifest list for binary-only image and push
working-directory: /tmp/digests/bin
env:
JSON: ${{ needs.prepare.outputs.bin-json }}
run: |
docker buildx imagetools create $(jq -cr --arg slug "$DOCKERHUB_SLUG" '.tags | map(select(startswith($slug)) | "--tag " + .) | join(" ")' <<< "$JSON") \
$(printf "$DOCKERHUB_SLUG@sha256:%s " *)
docker buildx imagetools create $(jq -cr --arg slug "$ECR_SLUG" '.tags | map(select(startswith($slug)) | "--tag " + .) | join(" ")' <<< "$JSON") \
$(printf "$ECR_SLUG@sha256:%s " *)
docker buildx imagetools create $(jq -cr --arg slug "$GHCR_SLUG" '.tags | map(select(startswith($slug)) | "--tag " + .) | join(" ")' <<< "$JSON") \
$(printf "$GHCR_SLUG@sha256:%s " *)
uses: $/.github/actions/create-manifest-list
with:
metadata-json: ${{ needs.prepare.outputs.bin-json }}
digests-directory: /tmp/digests/bin
images: |
${{ env.DOCKERHUB_SLUG }}
${{ env.ECR_SLUG }}
${{ env.GHCR_SLUG }}
2 changes: 1 addition & 1 deletion .github/workflows/shellcheck.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ jobs:
with:
persist-credentials: false
- name: ShellCheck
run: find . -type f -name '*.sh' | grep -v generate-stackbrew-library | xargs shellcheck
run: find . -type f -name '*.sh' -print0 | xargs -0 shellcheck
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ on:
- main
paths:
- '.github/**.yml'
- '.github/**.yaml'
pull_request:
paths:
- '.github/**.yml'
- '.github/**.yaml'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand Down
Loading
Loading