mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-10-07 21:13:18 +01:00
ci(build): reuse the Docker build cache across runs
This commit is contained in:
6
.github/actions/build-test-push/action.yml
vendored
6
.github/actions/build-test-push/action.yml
vendored
@@ -83,12 +83,16 @@ runs:
|
|||||||
INPUT_PLATFORM: ${{ inputs.platform }}
|
INPUT_PLATFORM: ${{ inputs.platform }}
|
||||||
INPUT_ALTERNATE_REPOSITORY: ${{ inputs.alternate_repository }}
|
INPUT_ALTERNATE_REPOSITORY: ${{ inputs.alternate_repository }}
|
||||||
INPUT_DRY_RUN: ${{ inputs.dry_run }}
|
INPUT_DRY_RUN: ${{ inputs.dry_run }}
|
||||||
|
# Exporting the build cache needs a registry login. Forks run without
|
||||||
|
# credentials, so they import the cache but never export it.
|
||||||
|
INPUT_CACHE_WRITABLE: ${{ inputs.docker_hub_username != '' }}
|
||||||
run: |
|
run: |
|
||||||
.github/actions/build-test-push/build.sh \
|
.github/actions/build-test-push/build.sh \
|
||||||
--version "$INPUT_VERSION" \
|
--version "$INPUT_VERSION" \
|
||||||
--platform "$INPUT_PLATFORM" \
|
--platform "$INPUT_PLATFORM" \
|
||||||
--alternate-repository "$INPUT_ALTERNATE_REPOSITORY" \
|
--alternate-repository "$INPUT_ALTERNATE_REPOSITORY" \
|
||||||
--dry-run "$INPUT_DRY_RUN"
|
--dry-run "$INPUT_DRY_RUN" \
|
||||||
|
--cache-writable "$INPUT_CACHE_WRITABLE"
|
||||||
|
|
||||||
- name: Run integration tests
|
- name: Run integration tests
|
||||||
if: inputs.skip_integrations_tests != 'true'
|
if: inputs.skip_integrations_tests != 'true'
|
||||||
|
|||||||
75
.github/actions/build-test-push/build.sh
vendored
75
.github/actions/build-test-push/build.sh
vendored
@@ -12,6 +12,7 @@ version=""
|
|||||||
platform=""
|
platform=""
|
||||||
alternate_repository=""
|
alternate_repository=""
|
||||||
dry_run=""
|
dry_run=""
|
||||||
|
cache_writable=""
|
||||||
|
|
||||||
while [[ $# -gt 0 ]]; do
|
while [[ $# -gt 0 ]]; do
|
||||||
case $1 in
|
case $1 in
|
||||||
@@ -31,6 +32,10 @@ while [[ $# -gt 0 ]]; do
|
|||||||
dry_run="$2"
|
dry_run="$2"
|
||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
|
--cache-writable)
|
||||||
|
cache_writable="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Unknown option $1"
|
echo "Unknown option $1"
|
||||||
exit 1
|
exit 1
|
||||||
@@ -44,11 +49,41 @@ echo
|
|||||||
echo "Gotenberg version: $version"
|
echo "Gotenberg version: $version"
|
||||||
echo "Target platform: $platform"
|
echo "Target platform: $platform"
|
||||||
|
|
||||||
|
# The build cache lives under the canonical repository, captured before the
|
||||||
|
# alternate-repository override below. Pull requests build into "snapshot", so
|
||||||
|
# deriving the cache ref after the override would give them a cache namespace
|
||||||
|
# of their own and they would never import what main published, which is the
|
||||||
|
# population that benefits most.
|
||||||
|
cache_image="$DOCKER_REGISTRY/$DOCKER_REPOSITORY"
|
||||||
|
|
||||||
|
# Layers are per-architecture, so each platform keeps its own cache manifest.
|
||||||
|
cache_platform="${platform//\//-}"
|
||||||
|
|
||||||
|
# Layers running "apt-get upgrade" install whatever versions are current at
|
||||||
|
# build time, and the packages are deliberately not pinned. A persistent cache
|
||||||
|
# would turn those into hits and freeze security patches into a published
|
||||||
|
# image until debian:13-slim itself changes digest. Keying them on the ISO week
|
||||||
|
# bounds that staleness to seven days while leaving every build within a week
|
||||||
|
# free to reuse the cache.
|
||||||
|
apt_snapshot="$(date -u +%G-W%V)"
|
||||||
|
|
||||||
|
# Only a build that is not redirected to an alternate repository writes the
|
||||||
|
# cache, so a pull request cannot make its own state the baseline for main.
|
||||||
|
# Reading stays enabled everywhere, including forks, since the cache ref is
|
||||||
|
# public and needs no credentials.
|
||||||
|
cache_to_enabled="false"
|
||||||
|
if [ "$cache_writable" = "true" ] && [ -z "$alternate_repository" ]; then
|
||||||
|
cache_to_enabled="true"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -n "$alternate_repository" ]; then
|
if [ -n "$alternate_repository" ]; then
|
||||||
DOCKER_REPOSITORY=$alternate_repository
|
DOCKER_REPOSITORY=$alternate_repository
|
||||||
echo "⚠️ Using $alternate_repository for DOCKER_REPOSITORY"
|
echo "⚠️ Using $alternate_repository for DOCKER_REPOSITORY"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo "Build cache: $cache_image:buildcache-<target>-$cache_platform (write: $cache_to_enabled)"
|
||||||
|
echo "APT snapshot: $apt_snapshot"
|
||||||
|
|
||||||
if [ "$dry_run" = "true" ]; then
|
if [ "$dry_run" = "true" ]; then
|
||||||
echo "🚧 Dry run"
|
echo "🚧 Dry run"
|
||||||
fi
|
fi
|
||||||
@@ -189,12 +224,36 @@ join() {
|
|||||||
echo "$*"
|
echo "$*"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# cache_flags echoes the buildx cache arguments for a build target. Each target
|
||||||
|
# keeps its own manifest so that the Chromium and LibreOffice variants, which
|
||||||
|
# branch from common-stage rather than from each other, do not overwrite one
|
||||||
|
# another's entry.
|
||||||
|
#
|
||||||
|
# mode=max exports intermediate stages too, not just the final layers, which is
|
||||||
|
# what makes the expensive apt and jlink stages reusable. type=registry, not
|
||||||
|
# type=gha: the GitHub Actions cache is capped at 10 GB per repository and is
|
||||||
|
# already carrying the Go and golangci-lint caches that the lint and test jobs
|
||||||
|
# depend on. Multi-GB image layers across five platforms would evict them.
|
||||||
|
cache_flags() {
|
||||||
|
local target="$1"
|
||||||
|
local ref="$cache_image:buildcache-$target-$cache_platform"
|
||||||
|
local flags="--cache-from type=registry,ref=$ref"
|
||||||
|
|
||||||
|
if [ "$cache_to_enabled" = "true" ]; then
|
||||||
|
flags="$flags --cache-to type=registry,ref=$ref,mode=max"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$flags"
|
||||||
|
}
|
||||||
|
|
||||||
no_arch_tag="$DOCKER_REGISTRY/$DOCKER_REPOSITORY:$version"
|
no_arch_tag="$DOCKER_REGISTRY/$DOCKER_REPOSITORY:$version"
|
||||||
|
|
||||||
# Full variant.
|
# Full variant.
|
||||||
cmd="docker buildx build \
|
cmd="docker buildx build \
|
||||||
--target gotenberg \
|
--target gotenberg \
|
||||||
--build-arg GOTENBERG_VERSION=$version \
|
--build-arg GOTENBERG_VERSION=$version \
|
||||||
|
--build-arg APT_SNAPSHOT=$apt_snapshot \
|
||||||
|
$(cache_flags gotenberg) \
|
||||||
--platform $platform \
|
--platform $platform \
|
||||||
--load \
|
--load \
|
||||||
${tags_flags[*]} \
|
${tags_flags[*]} \
|
||||||
@@ -207,6 +266,8 @@ run_cmd "$cmd"
|
|||||||
cmd="docker buildx build \
|
cmd="docker buildx build \
|
||||||
--target gotenberg-chromium \
|
--target gotenberg-chromium \
|
||||||
--build-arg GOTENBERG_VERSION=$version \
|
--build-arg GOTENBERG_VERSION=$version \
|
||||||
|
--build-arg APT_SNAPSHOT=$apt_snapshot \
|
||||||
|
$(cache_flags gotenberg-chromium) \
|
||||||
--platform $platform \
|
--platform $platform \
|
||||||
--load \
|
--load \
|
||||||
${tags_chromium_flags[*]} \
|
${tags_chromium_flags[*]} \
|
||||||
@@ -218,6 +279,8 @@ run_cmd "$cmd"
|
|||||||
cmd="docker buildx build \
|
cmd="docker buildx build \
|
||||||
--target gotenberg-libreoffice \
|
--target gotenberg-libreoffice \
|
||||||
--build-arg GOTENBERG_VERSION=$version \
|
--build-arg GOTENBERG_VERSION=$version \
|
||||||
|
--build-arg APT_SNAPSHOT=$apt_snapshot \
|
||||||
|
$(cache_flags gotenberg-libreoffice) \
|
||||||
--platform $platform \
|
--platform $platform \
|
||||||
--load \
|
--load \
|
||||||
${tags_libreoffice_flags[*]} \
|
${tags_libreoffice_flags[*]} \
|
||||||
@@ -230,6 +293,8 @@ if [ "$platform" = "linux/amd64" ]; then
|
|||||||
cmd="docker buildx build \
|
cmd="docker buildx build \
|
||||||
--target gotenberg-cloudrun \
|
--target gotenberg-cloudrun \
|
||||||
--build-arg GOTENBERG_VERSION=$version \
|
--build-arg GOTENBERG_VERSION=$version \
|
||||||
|
--build-arg APT_SNAPSHOT=$apt_snapshot \
|
||||||
|
$(cache_flags gotenberg-cloudrun) \
|
||||||
--platform $platform \
|
--platform $platform \
|
||||||
--load \
|
--load \
|
||||||
${tags_cloud_run_flags[*]} \
|
${tags_cloud_run_flags[*]} \
|
||||||
@@ -240,6 +305,8 @@ if [ "$platform" = "linux/amd64" ]; then
|
|||||||
cmd="docker buildx build \
|
cmd="docker buildx build \
|
||||||
--target gotenberg-cloudrun-chromium \
|
--target gotenberg-cloudrun-chromium \
|
||||||
--build-arg GOTENBERG_VERSION=$version \
|
--build-arg GOTENBERG_VERSION=$version \
|
||||||
|
--build-arg APT_SNAPSHOT=$apt_snapshot \
|
||||||
|
$(cache_flags gotenberg-cloudrun-chromium) \
|
||||||
--platform $platform \
|
--platform $platform \
|
||||||
--load \
|
--load \
|
||||||
${tags_cloud_run_chromium_flags[*]} \
|
${tags_cloud_run_chromium_flags[*]} \
|
||||||
@@ -250,6 +317,8 @@ if [ "$platform" = "linux/amd64" ]; then
|
|||||||
cmd="docker buildx build \
|
cmd="docker buildx build \
|
||||||
--target gotenberg-cloudrun-libreoffice \
|
--target gotenberg-cloudrun-libreoffice \
|
||||||
--build-arg GOTENBERG_VERSION=$version \
|
--build-arg GOTENBERG_VERSION=$version \
|
||||||
|
--build-arg APT_SNAPSHOT=$apt_snapshot \
|
||||||
|
$(cache_flags gotenberg-cloudrun-libreoffice) \
|
||||||
--platform $platform \
|
--platform $platform \
|
||||||
--load \
|
--load \
|
||||||
${tags_cloud_run_libreoffice_flags[*]} \
|
${tags_cloud_run_libreoffice_flags[*]} \
|
||||||
@@ -263,6 +332,8 @@ if [ "$platform" = "linux/amd64" ] || [ "$platform" = "linux/arm64" ]; then
|
|||||||
cmd="docker buildx build \
|
cmd="docker buildx build \
|
||||||
--target gotenberg-aws-lambda \
|
--target gotenberg-aws-lambda \
|
||||||
--build-arg GOTENBERG_VERSION=$version \
|
--build-arg GOTENBERG_VERSION=$version \
|
||||||
|
--build-arg APT_SNAPSHOT=$apt_snapshot \
|
||||||
|
$(cache_flags gotenberg-aws-lambda) \
|
||||||
--platform $platform \
|
--platform $platform \
|
||||||
--load \
|
--load \
|
||||||
${tags_aws_lambda_flags[*]} \
|
${tags_aws_lambda_flags[*]} \
|
||||||
@@ -273,6 +344,8 @@ if [ "$platform" = "linux/amd64" ] || [ "$platform" = "linux/arm64" ]; then
|
|||||||
cmd="docker buildx build \
|
cmd="docker buildx build \
|
||||||
--target gotenberg-aws-lambda-chromium \
|
--target gotenberg-aws-lambda-chromium \
|
||||||
--build-arg GOTENBERG_VERSION=$version \
|
--build-arg GOTENBERG_VERSION=$version \
|
||||||
|
--build-arg APT_SNAPSHOT=$apt_snapshot \
|
||||||
|
$(cache_flags gotenberg-aws-lambda-chromium) \
|
||||||
--platform $platform \
|
--platform $platform \
|
||||||
--load \
|
--load \
|
||||||
${tags_aws_lambda_chromium_flags[*]} \
|
${tags_aws_lambda_chromium_flags[*]} \
|
||||||
@@ -283,6 +356,8 @@ if [ "$platform" = "linux/amd64" ] || [ "$platform" = "linux/arm64" ]; then
|
|||||||
cmd="docker buildx build \
|
cmd="docker buildx build \
|
||||||
--target gotenberg-aws-lambda-libreoffice \
|
--target gotenberg-aws-lambda-libreoffice \
|
||||||
--build-arg GOTENBERG_VERSION=$version \
|
--build-arg GOTENBERG_VERSION=$version \
|
||||||
|
--build-arg APT_SNAPSHOT=$apt_snapshot \
|
||||||
|
$(cache_flags gotenberg-aws-lambda-libreoffice) \
|
||||||
--platform $platform \
|
--platform $platform \
|
||||||
--load \
|
--load \
|
||||||
${tags_aws_lambda_libreoffice_flags[*]} \
|
${tags_aws_lambda_libreoffice_flags[*]} \
|
||||||
|
|||||||
@@ -59,7 +59,14 @@ RUN go build -o gotenberg -ldflags "-s -w -X 'github.com/gotenberg/gotenberg/v8/
|
|||||||
# ----------------------------------------------
|
# ----------------------------------------------
|
||||||
FROM debian:13-slim AS custom-jre-stage
|
FROM debian:13-slim AS custom-jre-stage
|
||||||
|
|
||||||
RUN apt-get update -qq \
|
# APT_SNAPSHOT busts every layer below it when CI rotates the value, weekly.
|
||||||
|
# Without it a persistent build cache turns the unpinned "apt-get upgrade" into
|
||||||
|
# a cache hit and the published image keeps shipping the package versions that
|
||||||
|
# were current when the cache was first populated.
|
||||||
|
ARG APT_SNAPSHOT=""
|
||||||
|
|
||||||
|
RUN echo "apt snapshot: $APT_SNAPSHOT" \
|
||||||
|
&& apt-get update -qq \
|
||||||
&& apt-get upgrade -yqq \
|
&& apt-get upgrade -yqq \
|
||||||
&& DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends default-jdk-headless binutils
|
&& DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends default-jdk-headless binutils
|
||||||
|
|
||||||
@@ -114,9 +121,15 @@ FROM base-image-stage AS common-stage
|
|||||||
ARG GOTENBERG_USER_GID=1001
|
ARG GOTENBERG_USER_GID=1001
|
||||||
ARG GOTENBERG_USER_UID=1001
|
ARG GOTENBERG_USER_UID=1001
|
||||||
|
|
||||||
|
# See the note on APT_SNAPSHOT in custom-jre-stage. Declaring it here covers
|
||||||
|
# every "apt-get upgrade" in the gotenberg, gotenberg-chromium and
|
||||||
|
# gotenberg-libreoffice targets too, since all three branch from this stage.
|
||||||
|
ARG APT_SNAPSHOT=""
|
||||||
|
|
||||||
# Create a non-root user.
|
# Create a non-root user.
|
||||||
# All processes in the Docker container will run with this dedicated user.
|
# All processes in the Docker container will run with this dedicated user.
|
||||||
RUN groupadd --gid "$GOTENBERG_USER_GID" gotenberg \
|
RUN echo "apt snapshot: $APT_SNAPSHOT" \
|
||||||
|
&& groupadd --gid "$GOTENBERG_USER_GID" gotenberg \
|
||||||
&& useradd --uid "$GOTENBERG_USER_UID" --gid gotenberg --shell /bin/bash --home /home/gotenberg --no-create-home gotenberg \
|
&& useradd --uid "$GOTENBERG_USER_UID" --gid gotenberg --shell /bin/bash --home /home/gotenberg --no-create-home gotenberg \
|
||||||
&& mkdir /home/gotenberg \
|
&& mkdir /home/gotenberg \
|
||||||
&& chown gotenberg: /home/gotenberg
|
&& chown gotenberg: /home/gotenberg
|
||||||
|
|||||||
Reference in New Issue
Block a user