Skip to content

Merge pull request #113 from Euro-Office/chore/nightly-submodule-bump #142

Merge pull request #113 from Euro-Office/chore/nightly-submodule-bump

Merge pull request #113 from Euro-Office/chore/nightly-submodule-bump #142

Workflow file for this run

name: Build and Push Docker Image
on:
push:
workflow_dispatch:
inputs:
core_branch:
description: 'Branch core'
required: false
default: ''
type: string
sdkjs_branch:
description: 'Branch for sdkjs'
required: false
default: ''
type: string
web_apps_branch:
description: 'Branch for web-apps'
required: false
default: ''
type: string
server_branch:
description: 'Branch for server'
required: false
default: ''
type: string
env:
REGISTRY: ghcr.io/euro-office
IMAGE_NAME: documentserver
CACHE_IMAGE_NAME: documentserver-build-cache
PRODUCT_VERSION: 9.2.1
BUILD_ROOT: /package
jobs:
clone:
runs-on: ubuntu-latest
steps:
- name: Checkout fork repository (with submodules)
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
path: .
submodules: recursive
token: ${{ secrets.EURO_OFFICE_MIRROR_TOKEN }}
- name: Align submodules to requested branches
shell: bash
env:
CORE_BRANCH: ${{ github.event.inputs.core_branch || '' }}
SDKJS_BRANCH: ${{ github.event.inputs.sdkjs_branch || '' }}
WEBAPPS_BRANCH: ${{ github.event.inputs.web_apps_branch || '' }}
SERVER_BRANCH: ${{ github.event.inputs.server_branch || '' }}
run: |
set -euo pipefail
checkout_submodule() {
local path=$1
local branch=$2
echo "πŸ”§ Updating $path β†’ $branch"
pushd "$path" > /dev/null
git fetch origin "${branch}:${branch}"
git checkout "$branch"
popd > /dev/null
}
[ -n "$CORE_BRANCH" ] && checkout_submodule core "$CORE_BRANCH"
[ -n "$SDKJS_BRANCH" ] && checkout_submodule sdkjs "$SDKJS_BRANCH"
[ -n "$WEBAPPS_BRANCH" ] && checkout_submodule web-apps "$WEBAPPS_BRANCH"
[ -n "$SERVER_BRANCH" ] && checkout_submodule server "$SERVER_BRANCH"
checkout_submodule dictionaries "main"
checkout_submodule document-templates "main"
echo "--- Submodule state after alignment ---"
git submodule status
- name: Cache clones
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: "${{ github.workspace }}"
key: ${{ runner.os }}-build-${{ github.sha }}
# ─────────────────────────────────────────────────────────────
# BUILD
#
# Single job that builds the full target graph in one bake
# invocation per arch: packages β†’ docker β†’ develop.
# Because develop depends on docker which depends on packages,
# bake resolves the shared graph and never rebuilds a layer twice.
#
# Pushing per target:
# docker β†’ pushed on default branch (:nightly) and git tags (:latest)
# develop β†’ pushed on default branch only (:latest-dev)
# packages β†’ never pushed; exported to local filesystem for release upload
# ─────────────────────────────────────────────────────────────
build:
runs-on: ${{ matrix.arch == 'arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }}
needs: clone
permissions:
contents: write
packages: write
strategy:
fail-fast: false
matrix:
arch:
- amd64
- arm64
steps:
- name: Restore cache
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: "${{ github.workspace }}"
key: ${{ runner.os }}-build-${{ github.sha }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
- name: Log in to GitHub Container Registry
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Compute tags and push flags
id: meta
run: |
REF_NAME=$(echo '${{ github.ref_name }}' | tr '/' '-')
echo "ref_name=${REF_NAME}" >> $GITHUB_OUTPUT
IS_DEFAULT=${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }}
IS_TAG=${{ startsWith(github.ref, 'refs/tags/') }}
# docker target: push on default branch and git tags
if [[ "$IS_DEFAULT" == "true" ]]; then
echo "docker_tag=nightly-${{ matrix.arch }}" >> $GITHUB_OUTPUT
echo "docker_push=true" >> $GITHUB_OUTPUT
elif [[ "$IS_TAG" == "true" ]]; then
echo "docker_tag=latest-${{ matrix.arch }}" >> $GITHUB_OUTPUT
echo "docker_push=true" >> $GITHUB_OUTPUT
else
echo "docker_tag=${REF_NAME}-${{ matrix.arch }}" >> $GITHUB_OUTPUT
echo "docker_push=false" >> $GITHUB_OUTPUT
fi
# develop target: push on default branch only
if [[ "$IS_DEFAULT" == "true" ]]; then
echo "develop_push=true" >> $GITHUB_OUTPUT
else
echo "develop_push=false" >> $GITHUB_OUTPUT
fi
- name: Build all targets (packages β†’ docker β†’ develop)
uses: docker/bake-action@4a9a8d494466d37134e2bfca2d3a8de8fb2681ad # v5.13.0
with:
workdir: ./build
files: ./docker-bake.hcl
# Build the full graph; bake deduplicates shared layers automatically.
# packages is included so its local filesystem export always runs,
# enabling the release upload step below.
targets: develop,packages
# push=false here; per-target pushing is controlled via tags below.
# Targets with empty tags= are not pushed regardless of this flag.
push: false
set: |
core.cache-from=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-core-buildcache-${{ matrix.arch }}
core.cache-to=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-core-buildcache-${{ matrix.arch }},mode=max
core.tags=
core-wasm.cache-from=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-core-wasm-buildcache-${{ matrix.arch }}
core-wasm.cache-to=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-core-wasm-buildcache-${{ matrix.arch }},mode=max
core-wasm.tags=
sdkjs.cache-from=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-sdkjs-buildcache-${{ matrix.arch }}
sdkjs.cache-to=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-sdkjs-buildcache-${{ matrix.arch }},mode=max
sdkjs.tags=
web-apps.cache-from=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-web-apps-buildcache-${{ matrix.arch }}
web-apps.cache-to=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-web-apps-buildcache-${{ matrix.arch }},mode=max
web-apps.tags=
server.cache-from=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-server-buildcache-${{ matrix.arch }}
server.cache-to=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-server-buildcache-${{ matrix.arch }},mode=max
server.tags=
example.cache-from=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-example-buildcache-${{ matrix.arch }}
example.cache-to=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-example-buildcache-${{ matrix.arch }},mode=max
example.tags=
bundle.cache-from=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-bundle-buildcache-${{ matrix.arch }}
bundle.cache-to=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-bundle-buildcache-${{ matrix.arch }},mode=max
bundle.tags=
packages.cache-from=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-packages-buildcache-${{ matrix.arch }}
packages.cache-to=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-packages-buildcache-${{ matrix.arch }},mode=max
packages.tags=
docker.cache-from=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-docker-buildcache-${{ matrix.arch }}
docker.cache-to=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-docker-buildcache-${{ matrix.arch }},mode=max
docker.tags=${{ steps.meta.outputs.docker_push == 'true' && format('{0}/{1}:{2}', env.REGISTRY, env.IMAGE_NAME, steps.meta.outputs.docker_tag) || '' }}
docker.output=${{ steps.meta.outputs.docker_push == 'true' && format('type=registry') || 'type=cacheonly' }}
develop.cache-from=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-develop-buildcache-${{ matrix.arch }}
develop.cache-to=type=registry,ref=${{ env.REGISTRY }}/${{ env.CACHE_IMAGE_NAME }}:${{ steps.meta.outputs.ref_name }}-develop-buildcache-${{ matrix.arch }},mode=max
develop.tags=${{ steps.meta.outputs.develop_push == 'true' && format('{0}/{1}:latest-dev-{2}', env.REGISTRY, env.IMAGE_NAME, matrix.arch) || '' }}
develop.output=${{ steps.meta.outputs.develop_push == 'true' && 'type=registry' || 'type=cacheonly' }}
env:
REGISTRY: ${{ env.REGISTRY }}
TAG: ${{ steps.meta.outputs.docker_tag }}
PRODUCT_VERSION: ${{ env.PRODUCT_VERSION }}
BUILD_ROOT: ${{ env.BUILD_ROOT }}
NUGET_CACHE: local
- name: Upload packages to GitHub Release
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/')
with:
files: |
build/deploy/packages/*.deb
build/deploy/packages/*.rpm
# ─────────────────────────────────────────────────────────────
# MANIFEST
#
# Merges the arch-specific documentserver images into a single
# multi-arch manifest. Runs on default branch (:nightly) and
# git tags (:latest + sanitised ref tag).
# ─────────────────────────────────────────────────────────────
manifest:
runs-on: ubuntu-latest
needs: build
if: github.ref == format('refs/heads/{0}', github.event.repository.default_branch) || startsWith(github.ref, 'refs/tags/')
permissions:
contents: read
packages: write
steps:
- name: Compute safe ref name
id: ref
run: echo "name=$(echo '${{ github.ref_name }}' | tr '/' '-')" >> $GITHUB_OUTPUT
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
- name: Log in to GitHub Container Registry
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create and push multi-arch manifests
run: |
REF="${{ steps.ref.outputs.name }}"
REPO="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}"
create_manifest() {
local tag="$1"
docker buildx imagetools create \
-t "${REPO}:${tag}" \
"${REPO}:${tag}-amd64" \
"${REPO}:${tag}-arm64"
}
if [[ "${{ github.ref_name }}" == "${{ github.event.repository.default_branch }}" ]]; then
create_manifest "nightly"
create_manifest "latest-dev"
fi
if [[ "${{ github.ref }}" == refs/tags/* ]]; then
create_manifest "latest"
create_manifest "${REF}"
fi