mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-10-07 21:13:18 +01:00
380 lines
12 KiB
Bash
Executable File
380 lines
12 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Exit early.
|
|
# See: https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#The-Set-Builtin.
|
|
set -e
|
|
|
|
# Source dot env file.
|
|
source .env
|
|
|
|
# Arguments.
|
|
version=""
|
|
platform=""
|
|
alternate_repository=""
|
|
dry_run=""
|
|
cache_writable=""
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
--version)
|
|
version="${2//v/}"
|
|
shift 2
|
|
;;
|
|
--platform)
|
|
platform="$2"
|
|
shift 2
|
|
;;
|
|
--alternate-repository)
|
|
alternate_repository="$2"
|
|
shift 2
|
|
;;
|
|
--dry-run)
|
|
dry_run="$2"
|
|
shift 2
|
|
;;
|
|
--cache-writable)
|
|
cache_writable="$2"
|
|
shift 2
|
|
;;
|
|
*)
|
|
echo "Unknown option $1"
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
echo "Build and push 👷"
|
|
echo
|
|
|
|
echo "Gotenberg version: $version"
|
|
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
|
|
DOCKER_REPOSITORY=$alternate_repository
|
|
echo "⚠️ Using $alternate_repository for DOCKER_REPOSITORY"
|
|
fi
|
|
|
|
echo "Build cache: $cache_image:buildcache-<target>-$cache_platform (write: $cache_to_enabled)"
|
|
echo "APT snapshot: $apt_snapshot"
|
|
|
|
if [ "$dry_run" = "true" ]; then
|
|
echo "🚧 Dry run"
|
|
fi
|
|
|
|
# Build tags arrays.
|
|
tags=()
|
|
tags_chromium=()
|
|
tags_libreoffice=()
|
|
tags_cloud_run=()
|
|
tags_cloud_run_chromium=()
|
|
tags_cloud_run_libreoffice=()
|
|
tags_aws_lambda=()
|
|
tags_aws_lambda_chromium=()
|
|
tags_aws_lambda_libreoffice=()
|
|
|
|
IFS='/' read -ra arch <<< "$platform"
|
|
IFS='.' read -ra semver <<< "$version"
|
|
|
|
if [ "${#semver[@]}" -eq 3 ]; then
|
|
echo
|
|
echo "Semver version detected"
|
|
|
|
major="${semver[0]}"
|
|
minor="${semver[1]}"
|
|
patch="${semver[2]}"
|
|
|
|
for suffix in "latest" "$major" "$major.$minor" "$major.$minor.$patch"; do
|
|
tags+=("$DOCKER_REGISTRY/$DOCKER_REPOSITORY:$suffix-${arch[1]}")
|
|
tags_chromium+=("$DOCKER_REGISTRY/$DOCKER_REPOSITORY:$suffix-chromium-${arch[1]}")
|
|
tags_libreoffice+=("$DOCKER_REGISTRY/$DOCKER_REPOSITORY:$suffix-libreoffice-${arch[1]}")
|
|
done
|
|
|
|
if [ "$platform" = "linux/amd64" ]; then
|
|
for suffix in "latest" "$major" "$major.$minor" "$major.$minor.$patch"; do
|
|
tags_cloud_run+=("$DOCKER_REGISTRY/$DOCKER_REPOSITORY:$suffix-cloudrun")
|
|
tags_cloud_run_chromium+=("$DOCKER_REGISTRY/$DOCKER_REPOSITORY:$suffix-chromium-cloudrun")
|
|
tags_cloud_run_libreoffice+=("$DOCKER_REGISTRY/$DOCKER_REPOSITORY:$suffix-libreoffice-cloudrun")
|
|
done
|
|
fi
|
|
|
|
if [ "$platform" = "linux/amd64" ] || [ "$platform" = "linux/arm64" ]; then
|
|
for suffix in "latest" "$major" "$major.$minor" "$major.$minor.$patch"; do
|
|
tags_aws_lambda+=("$DOCKER_REGISTRY/$DOCKER_REPOSITORY:$suffix-aws-lambda-${arch[1]}")
|
|
tags_aws_lambda_chromium+=("$DOCKER_REGISTRY/$DOCKER_REPOSITORY:$suffix-chromium-aws-lambda-${arch[1]}")
|
|
tags_aws_lambda_libreoffice+=("$DOCKER_REGISTRY/$DOCKER_REPOSITORY:$suffix-libreoffice-aws-lambda-${arch[1]}")
|
|
done
|
|
fi
|
|
else
|
|
echo
|
|
echo "Non-semver version detected, fallback to $version"
|
|
|
|
tags+=("$DOCKER_REGISTRY/$DOCKER_REPOSITORY:$version-${arch[1]}")
|
|
tags_chromium+=("$DOCKER_REGISTRY/$DOCKER_REPOSITORY:$version-chromium-${arch[1]}")
|
|
tags_libreoffice+=("$DOCKER_REGISTRY/$DOCKER_REPOSITORY:$version-libreoffice-${arch[1]}")
|
|
|
|
if [ "$platform" = "linux/amd64" ]; then
|
|
tags_cloud_run+=("$DOCKER_REGISTRY/$DOCKER_REPOSITORY:$version-cloudrun")
|
|
tags_cloud_run_chromium+=("$DOCKER_REGISTRY/$DOCKER_REPOSITORY:$version-chromium-cloudrun")
|
|
tags_cloud_run_libreoffice+=("$DOCKER_REGISTRY/$DOCKER_REPOSITORY:$version-libreoffice-cloudrun")
|
|
fi
|
|
|
|
if [ "$platform" = "linux/amd64" ] || [ "$platform" = "linux/arm64" ]; then
|
|
tags_aws_lambda+=("$DOCKER_REGISTRY/$DOCKER_REPOSITORY:$version-aws-lambda-${arch[1]}")
|
|
tags_aws_lambda_chromium+=("$DOCKER_REGISTRY/$DOCKER_REPOSITORY:$version-chromium-aws-lambda-${arch[1]}")
|
|
tags_aws_lambda_libreoffice+=("$DOCKER_REGISTRY/$DOCKER_REPOSITORY:$version-libreoffice-aws-lambda-${arch[1]}")
|
|
fi
|
|
fi
|
|
|
|
tags_flags=()
|
|
tags_chromium_flags=()
|
|
tags_libreoffice_flags=()
|
|
tags_cloud_run_flags=()
|
|
tags_cloud_run_chromium_flags=()
|
|
tags_cloud_run_libreoffice_flags=()
|
|
tags_aws_lambda_flags=()
|
|
tags_aws_lambda_chromium_flags=()
|
|
tags_aws_lambda_libreoffice_flags=()
|
|
|
|
echo "Will use the following tags:"
|
|
for tag in "${tags[@]}"; do
|
|
tags_flags+=("-t" "$tag")
|
|
echo "- $tag"
|
|
done
|
|
for tag in "${tags_chromium[@]}"; do
|
|
tags_chromium_flags+=("-t" "$tag")
|
|
echo "- $tag"
|
|
done
|
|
for tag in "${tags_libreoffice[@]}"; do
|
|
tags_libreoffice_flags+=("-t" "$tag")
|
|
echo "- $tag"
|
|
done
|
|
for tag in "${tags_cloud_run[@]}"; do
|
|
tags_cloud_run_flags+=("-t" "$tag")
|
|
echo "- $tag"
|
|
done
|
|
for tag in "${tags_cloud_run_chromium[@]}"; do
|
|
tags_cloud_run_chromium_flags+=("-t" "$tag")
|
|
echo "- $tag"
|
|
done
|
|
for tag in "${tags_cloud_run_libreoffice[@]}"; do
|
|
tags_cloud_run_libreoffice_flags+=("-t" "$tag")
|
|
echo "- $tag"
|
|
done
|
|
for tag in "${tags_aws_lambda[@]}"; do
|
|
tags_aws_lambda_flags+=("-t" "$tag")
|
|
echo "- $tag"
|
|
done
|
|
for tag in "${tags_aws_lambda_chromium[@]}"; do
|
|
tags_aws_lambda_chromium_flags+=("-t" "$tag")
|
|
echo "- $tag"
|
|
done
|
|
for tag in "${tags_aws_lambda_libreoffice[@]}"; do
|
|
tags_aws_lambda_libreoffice_flags+=("-t" "$tag")
|
|
echo "- $tag"
|
|
done
|
|
echo
|
|
|
|
# Build images.
|
|
run_cmd() {
|
|
local cmd="$1"
|
|
|
|
if [ "$dry_run" = "true" ]; then
|
|
echo "🚧 Dry run - would run the following command:"
|
|
echo "$cmd"
|
|
echo
|
|
else
|
|
echo "⚙️ Running command:"
|
|
echo "$cmd"
|
|
eval "$cmd"
|
|
echo
|
|
fi
|
|
}
|
|
|
|
join() {
|
|
local delimiter="$1"
|
|
shift
|
|
local IFS="$delimiter"
|
|
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"
|
|
|
|
# Full variant.
|
|
cmd="docker buildx build \
|
|
--target gotenberg \
|
|
--build-arg GOTENBERG_VERSION=$version \
|
|
--build-arg APT_SNAPSHOT=$apt_snapshot \
|
|
$(cache_flags gotenberg) \
|
|
--platform $platform \
|
|
--load \
|
|
${tags_flags[*]} \
|
|
-t $no_arch_tag \
|
|
-f $DOCKERFILE $DOCKER_BUILD_CONTEXT
|
|
"
|
|
run_cmd "$cmd"
|
|
|
|
# Chromium only variant.
|
|
cmd="docker buildx build \
|
|
--target gotenberg-chromium \
|
|
--build-arg GOTENBERG_VERSION=$version \
|
|
--build-arg APT_SNAPSHOT=$apt_snapshot \
|
|
$(cache_flags gotenberg-chromium) \
|
|
--platform $platform \
|
|
--load \
|
|
${tags_chromium_flags[*]} \
|
|
-f $DOCKERFILE $DOCKER_BUILD_CONTEXT
|
|
"
|
|
run_cmd "$cmd"
|
|
|
|
# LibreOffice only variant.
|
|
cmd="docker buildx build \
|
|
--target gotenberg-libreoffice \
|
|
--build-arg GOTENBERG_VERSION=$version \
|
|
--build-arg APT_SNAPSHOT=$apt_snapshot \
|
|
$(cache_flags gotenberg-libreoffice) \
|
|
--platform $platform \
|
|
--load \
|
|
${tags_libreoffice_flags[*]} \
|
|
-f $DOCKERFILE $DOCKER_BUILD_CONTEXT
|
|
"
|
|
run_cmd "$cmd"
|
|
|
|
# Cloud Run variants (amd64 only).
|
|
if [ "$platform" = "linux/amd64" ]; then
|
|
cmd="docker buildx build \
|
|
--target gotenberg-cloudrun \
|
|
--build-arg GOTENBERG_VERSION=$version \
|
|
--build-arg APT_SNAPSHOT=$apt_snapshot \
|
|
$(cache_flags gotenberg-cloudrun) \
|
|
--platform $platform \
|
|
--load \
|
|
${tags_cloud_run_flags[*]} \
|
|
-f $DOCKERFILE $DOCKER_BUILD_CONTEXT
|
|
"
|
|
run_cmd "$cmd"
|
|
|
|
cmd="docker buildx build \
|
|
--target gotenberg-cloudrun-chromium \
|
|
--build-arg GOTENBERG_VERSION=$version \
|
|
--build-arg APT_SNAPSHOT=$apt_snapshot \
|
|
$(cache_flags gotenberg-cloudrun-chromium) \
|
|
--platform $platform \
|
|
--load \
|
|
${tags_cloud_run_chromium_flags[*]} \
|
|
-f $DOCKERFILE $DOCKER_BUILD_CONTEXT
|
|
"
|
|
run_cmd "$cmd"
|
|
|
|
cmd="docker buildx build \
|
|
--target gotenberg-cloudrun-libreoffice \
|
|
--build-arg GOTENBERG_VERSION=$version \
|
|
--build-arg APT_SNAPSHOT=$apt_snapshot \
|
|
$(cache_flags gotenberg-cloudrun-libreoffice) \
|
|
--platform $platform \
|
|
--load \
|
|
${tags_cloud_run_libreoffice_flags[*]} \
|
|
-f $DOCKERFILE $DOCKER_BUILD_CONTEXT
|
|
"
|
|
run_cmd "$cmd"
|
|
fi
|
|
|
|
# AWS Lambda variants (amd64 + arm64 only).
|
|
if [ "$platform" = "linux/amd64" ] || [ "$platform" = "linux/arm64" ]; then
|
|
cmd="docker buildx build \
|
|
--target gotenberg-aws-lambda \
|
|
--build-arg GOTENBERG_VERSION=$version \
|
|
--build-arg APT_SNAPSHOT=$apt_snapshot \
|
|
$(cache_flags gotenberg-aws-lambda) \
|
|
--platform $platform \
|
|
--load \
|
|
${tags_aws_lambda_flags[*]} \
|
|
-f $DOCKERFILE $DOCKER_BUILD_CONTEXT
|
|
"
|
|
run_cmd "$cmd"
|
|
|
|
cmd="docker buildx build \
|
|
--target gotenberg-aws-lambda-chromium \
|
|
--build-arg GOTENBERG_VERSION=$version \
|
|
--build-arg APT_SNAPSHOT=$apt_snapshot \
|
|
$(cache_flags gotenberg-aws-lambda-chromium) \
|
|
--platform $platform \
|
|
--load \
|
|
${tags_aws_lambda_chromium_flags[*]} \
|
|
-f $DOCKERFILE $DOCKER_BUILD_CONTEXT
|
|
"
|
|
run_cmd "$cmd"
|
|
|
|
cmd="docker buildx build \
|
|
--target gotenberg-aws-lambda-libreoffice \
|
|
--build-arg GOTENBERG_VERSION=$version \
|
|
--build-arg APT_SNAPSHOT=$apt_snapshot \
|
|
$(cache_flags gotenberg-aws-lambda-libreoffice) \
|
|
--platform $platform \
|
|
--load \
|
|
${tags_aws_lambda_libreoffice_flags[*]} \
|
|
-f $DOCKERFILE $DOCKER_BUILD_CONTEXT
|
|
"
|
|
run_cmd "$cmd"
|
|
fi
|
|
|
|
echo "✅ Done!"
|
|
echo "tags=$(join "," "${tags[@]}")" >> "$GITHUB_OUTPUT"
|
|
echo "tags_chromium=$(join "," "${tags_chromium[@]}")" >> "$GITHUB_OUTPUT"
|
|
echo "tags_libreoffice=$(join "," "${tags_libreoffice[@]}")" >> "$GITHUB_OUTPUT"
|
|
echo "tags_cloud_run=$(join "," "${tags_cloud_run[@]}")" >> "$GITHUB_OUTPUT"
|
|
echo "tags_cloud_run_chromium=$(join "," "${tags_cloud_run_chromium[@]}")" >> "$GITHUB_OUTPUT"
|
|
echo "tags_cloud_run_libreoffice=$(join "," "${tags_cloud_run_libreoffice[@]}")" >> "$GITHUB_OUTPUT"
|
|
echo "tags_aws_lambda=$(join "," "${tags_aws_lambda[@]}")" >> "$GITHUB_OUTPUT"
|
|
echo "tags_aws_lambda_chromium=$(join "," "${tags_aws_lambda_chromium[@]}")" >> "$GITHUB_OUTPUT"
|
|
echo "tags_aws_lambda_libreoffice=$(join "," "${tags_aws_lambda_libreoffice[@]}")" >> "$GITHUB_OUTPUT"
|
|
exit 0
|