🔧 Build Docker images on Renovate branches

Signed-off-by: David Barragán Merino <david.barragan@kaleidos.net>
This commit is contained in:
David Barragán Merino 2026-10-06 13:14:22 +02:00 committed by David Barragán Merino
parent 8d8dff8de4
commit d47753dbb3

252
.github/workflows/build-renovate.yml vendored Normal file
View File

@ -0,0 +1,252 @@
name: Renovate Docker Image Check
# Triggered by pushes to Renovate branches, not by pull_request: this is a
# public repository and these jobs run on the self-hosted runners, so a PR
# from a fork must never be able to start them. Only users with write
# access can push here.
on:
push:
branches:
- 'renovate-*'
permissions: {}
concurrency:
group: renovate-image-check-${{ github.ref_name }}
cancel-in-progress: true
env:
BUNDLE_CACHE: /var/tmp/penpot-bundle-cache
jobs:
# ── 1. Pick an existing develop bundle and detect what changed ────────
prepare:
name: Prepare
runs-on: penpot-standar-runner
timeout-minutes: 10
permissions:
contents: read
outputs:
short_sha: ${{ steps.bundle.outputs.short_sha }}
devenv: ${{ steps.changes.outputs.devenv }}
imagemagick: ${{ steps.changes.outputs.imagemagick }}
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
fetch-depth: 0
- name: Find the develop commit this branch is based on
id: base
run: |
echo "sha=$(git merge-base HEAD origin/develop)" >> "$GITHUB_OUTPUT"
- name: Detect changed images
id: changes
env:
BASE_SHA: ${{ steps.base.outputs.sha }}
run: |
changed() {
git diff --quiet "$BASE_SHA" HEAD -- "$1" && echo false || echo true
}
{
echo "devenv=$(changed docker/devenv)"
echo "imagemagick=$(changed docker/imagemagick)"
} >> "$GITHUB_OUTPUT"
# Renovate only changes Dockerfiles and package manager versions, so
# the most recent develop bundle is enough to build the images.
- name: Find the latest develop bundle
id: bundle
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: ${{ secrets.AWS_REGION }}
S3_BUCKET: ${{ secrets.S3_BUCKET }}
BASE_SHA: ${{ steps.base.outputs.sha }}
run: |
for SHA in $(git rev-list --first-parent --max-count=50 "$BASE_SHA"); do
SHORT_SHA=$(git rev-parse --short=12 "$SHA")
if aws s3api head-object --bucket "$S3_BUCKET" \
--key "penpot-sha-${SHORT_SHA}.zip" > /dev/null 2>&1; then
echo "short_sha=$SHORT_SHA" >> "$GITHUB_OUTPUT"
echo "Using bundle \`penpot-sha-${SHORT_SHA}.zip\`" >> "$GITHUB_STEP_SUMMARY"
exit 0
fi
done
echo "::error::No bundle found for the last 50 develop commits"
exit 1
# ── 2. Production images, built from the PR Dockerfiles ───────────────
images:
name: Build ${{ matrix.image }}
runs-on: penpot-standar-runner
timeout-minutes: 60
needs: prepare
permissions:
contents: read
strategy:
fail-fast: false
max-parallel: 3
matrix:
image: [backend, frontend, exporter, storybook, mcp]
steps:
- name: Set common environment variables
env:
MATRIX_IMAGE: ${{ matrix.image }}
run: |
echo "DOCKER_CONFIG=${RUNNER_TEMP}/.docker-${GITHUB_RUN_ID}-${GITHUB_JOB}-${MATRIX_IMAGE}" >> "$GITHUB_ENV"
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Login to Docker Registry
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
registry: ${{ secrets.DOCKER_REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to DockerHub Registry
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
username: ${{ secrets.PUB_DOCKER_USERNAME }}
password: ${{ secrets.PUB_DOCKER_PASSWORD }}
- name: Login to Docker Hardened Images registry
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
registry: dhi.io
username: ${{ secrets.PUB_DOCKER_USERNAME }}
password: ${{ secrets.PUB_DOCKER_PASSWORD }}
- name: Prepare Penpot bundle
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: ${{ secrets.AWS_REGION }}
S3_BUCKET: ${{ secrets.S3_BUCKET }}
SHORT_SHA: ${{ needs.prepare.outputs.short_sha }}
IMAGE: ${{ matrix.image }}
run: |
ZIP="$BUNDLE_CACHE/penpot-sha-${SHORT_SHA}.zip"
if [ ! -f "$ZIP" ]; then
mkdir -p "$BUNDLE_CACHE"
aws s3 cp "s3://${S3_BUCKET}/penpot-sha-${SHORT_SHA}.zip" "$ZIP.$$.tmp"
mv "$ZIP.$$.tmp" "$ZIP"
fi
pushd docker/images
unzip -q "$ZIP" "penpot/${IMAGE}/*"
mv "penpot/${IMAGE}" "bundle-${IMAGE}"
popd
- name: Set up QEMU
uses: docker/setup-qemu-action@99012661954931238ded8c8b007157a8430204e1 # v4.4.0
with:
platforms: linux/amd64,linux/arm64
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
- name: Build Docker image
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
with:
context: ./docker/images/
file: ./docker/images/Dockerfile.${{ matrix.image }}
platforms: linux/amd64,linux/arm64
push: false
cache-from: type=registry,ref=${{ secrets.DOCKER_REGISTRY }}/${{ matrix.image }}:buildcache
# ── 3. Devenv, only when the PR touches it ────────────────────────────
devenv:
name: Build devenv
runs-on: penpot-standar-runner
timeout-minutes: 90
needs: prepare
if: needs.prepare.outputs.devenv == 'true'
permissions:
contents: read
steps:
- name: Set common environment variables
run: |
echo "DOCKER_CONFIG=${RUNNER_TEMP}/.docker-${GITHUB_RUN_ID}-${GITHUB_JOB}" >> "$GITHUB_ENV"
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Login to DockerHub Registry
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
username: ${{ secrets.PUB_DOCKER_USERNAME }}
password: ${{ secrets.PUB_DOCKER_PASSWORD }}
- name: Login to Docker Hardened Images registry
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
registry: dhi.io
username: ${{ secrets.PUB_DOCKER_USERNAME }}
password: ${{ secrets.PUB_DOCKER_PASSWORD }}
- name: Set up QEMU
uses: docker/setup-qemu-action@99012661954931238ded8c8b007157a8430204e1 # v4.4.0
with:
platforms: linux/amd64,linux/arm64
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
- name: Build devenv image
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
with:
context: ./docker/devenv/
file: ./docker/devenv/Dockerfile
platforms: linux/amd64,linux/arm64
push: false
cache-from: type=registry,ref=penpotapp/devenv:buildcache
# ── 4. ImageMagick, only when the PR touches it ───────────────────────
# amd64 only: compiling ImageMagick under QEMU takes too long for a check.
imagemagick:
name: Build imagemagick
runs-on: penpot-standar-runner
timeout-minutes: 60
needs: prepare
if: needs.prepare.outputs.imagemagick == 'true'
permissions:
contents: read
steps:
- name: Set common environment variables
run: |
echo "DOCKER_CONFIG=${RUNNER_TEMP}/.docker-${GITHUB_RUN_ID}-${GITHUB_JOB}" >> "$GITHUB_ENV"
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Login to Docker Hardened Images registry
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
registry: dhi.io
username: ${{ secrets.PUB_DOCKER_USERNAME }}
password: ${{ secrets.PUB_DOCKER_PASSWORD }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
- name: Build imagemagick image
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
with:
context: ./docker/imagemagick/
file: ./docker/imagemagick/Dockerfile
platforms: linux/amd64
push: false