Skip to content

Build relay/main (6a7e6ce) #71

Build relay/main (6a7e6ce)

Build relay/main (6a7e6ce) #71

Workflow file for this run

# Build and push the chatmail-relay Docker image (ghcr.io/chatmail/docker).
#
# Triggers:
# 1. Push/PR to this repo (Dockerfile changes) -- builds relay@main
# 2. repository_dispatch from chatmail/relay -- builds the dispatched relay ref
# 3. workflow_dispatch -- manual build of any relay branch/tag
#
# Tags: sha-<relay-7char>, branch name, semver (on release tags)
# PRs: build only, no push
name: Build and push chatmail-relay image
run-name: >-
${{ github.event_name == 'repository_dispatch'
&& format('Build relay/{0} ({1})',
github.event.client_payload.relay_ref,
github.event.client_payload.relay_sha_short)
|| github.event_name == 'workflow_dispatch'
&& format('Build relay/{0}',
github.event.inputs.relay_ref || 'main')
|| format('Build docker/{0}', github.ref_name) }}
on:
push:
branches: [main]
pull_request:
paths-ignore:
- '**/README.md'
- 'CHANGELOG.md'
- 'LICENSE'
repository_dispatch:
types: [relay-updated]
workflow_dispatch:
inputs:
relay_ref:
description: 'Relay branch or tag to build (default: main)'
default: 'main'
relay_sha:
description: 'Relay commit SHA (leave empty for HEAD of ref)'
default: ''
permissions: {}
env:
REGISTRY: ghcr.io
IMAGE_NAME: chatmail/docker
jobs:
build:
name: Build Docker image
runs-on: ubuntu-latest
outputs:
image_tag: ${{ steps.meta.outputs.tag }}
relay_ref: ${{ steps.meta.outputs.relay_ref }}
permissions:
contents: read
packages: write
steps:
- name: Compute relay ref
id: relay
env:
PAYLOAD_REF: ${{ github.event.client_payload.relay_ref }}
PAYLOAD_SHA: ${{ github.event.client_payload.relay_sha }}
INPUT_REF: ${{ github.event.inputs.relay_ref }}
INPUT_SHA: ${{ github.event.inputs.relay_sha }}
run: |
REF="${PAYLOAD_REF:-${INPUT_REF:-main}}"
SHA="${PAYLOAD_SHA:-${INPUT_SHA:-}}"
echo "ref=${REF}" >> "$GITHUB_OUTPUT"
echo "sha=${SHA}" >> "$GITHUB_OUTPUT"
- name: Checkout relay repo as build context
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
repository: chatmail/relay
ref: ${{ steps.relay.outputs.sha || steps.relay.outputs.ref }}
persist-credentials: false
- name: Checkout docker repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
path: docker
persist-credentials: false
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4
- name: Login to GHCR
if: github.event_name != 'pull_request'
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Compute build metadata
id: meta
env:
RELAY_REF_INPUT: ${{ steps.relay.outputs.ref }}
EVENT_NAME: ${{ github.event_name }}
REF_NAME: ${{ github.ref_name }}
run: |
IMAGE="${REGISTRY}/${IMAGE_NAME}"
RELAY_REF="${RELAY_REF_INPUT}"
# Relay SHA comes from the relay checkout at workspace root
RELAY_SHA=$(git rev-parse HEAD)
RELAY_SHA_SHORT="${RELAY_SHA:0:7}"
BUILD_DATE=$(git log -1 --format=%cI)
COMMIT_MSG=$(git log -1 --format=%s)
echo "relay_sha=${RELAY_SHA}" >> "$GITHUB_OUTPUT"
echo "relay_sha_short=${RELAY_SHA_SHORT}" >> "$GITHUB_OUTPUT"
echo "relay_ref=${RELAY_REF}" >> "$GITHUB_OUTPUT"
echo "build_date=${BUILD_DATE}" >> "$GITHUB_OUTPUT"
echo "tag=sha-${RELAY_SHA_SHORT}" >> "$GITHUB_OUTPUT"
# -- Tags --
# Always: relay SHA tag
TAGS="${IMAGE}:sha-${RELAY_SHA_SHORT}"
if [ "$EVENT_NAME" = "push" ] || \
[ "$EVENT_NAME" = "pull_request" ]; then
# Docker-repo push/PR: add docker branch tag
TAGS="${TAGS}"$'\n'"${IMAGE}:${REF_NAME}"
else
# Dispatch: tags based on relay ref
BRANCH_TAG=$(echo "${RELAY_REF}" | sed 's|/|-|g')
TAGS="${TAGS}"$'\n'"${IMAGE}:${BRANCH_TAG}"
if [[ "${RELAY_REF}" =~ ^v?([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
VERSION="${BASH_REMATCH[1]}.${BASH_REMATCH[2]}.${BASH_REMATCH[3]}"
MINOR="${BASH_REMATCH[1]}.${BASH_REMATCH[2]}"
TAGS="${TAGS}"$'\n'"${IMAGE}:${VERSION}"
TAGS="${TAGS}"$'\n'"${IMAGE}:${MINOR}"
TAGS="${TAGS}"$'\n'"${IMAGE}:latest"
fi
fi
echo "tags<<EOF" >> "$GITHUB_OUTPUT"
echo "${TAGS}" >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"
# -- Changes: commit list since last image (stored in custom label) --
BASE_SHA=""
if [ "${RELAY_REF}" = "main" ]; then
BASE_SHA=$(gh api "orgs/chatmail/packages/container/docker/versions?per_page=50" \
--jq '[.[]
| select(.metadata.container.tags | any(. == "main"))
| .metadata.container.tags[] | select(startswith("sha-"))
| ltrimstr("sha-")] | .[0] // empty' 2>/dev/null) || true
else
BASE_SHA=$(gh api "repos/chatmail/relay/commits/main" --jq '.sha[:7]' 2>/dev/null) || true
fi
CHANGES=""
if [ -n "$BASE_SHA" ] && [ "$BASE_SHA" != "$RELAY_SHA_SHORT" ]; then
CHANGES=$(gh api "repos/chatmail/relay/compare/${BASE_SHA}...${RELAY_SHA}" \
--jq '.commits[] | .sha[:7] + " " + (.commit.message | split("\n")[0])' 2>/dev/null) || true
fi
if [ -z "$CHANGES" ]; then
CHANGES="${RELAY_SHA_SHORT} ${COMMIT_MSG}"
fi
# Static description for GHCR package page (512 char limit, text-only)
DESC="Chatmail Relay Server"
{
echo "labels<<EOF"
echo "org.opencontainers.image.title=chatmail-relay"
echo "org.opencontainers.image.description=${DESC}"
echo "org.opencontainers.image.revision=${RELAY_SHA}"
echo "org.opencontainers.image.source=https://github.com/chatmail/relay"
echo "org.opencontainers.image.created=${BUILD_DATE}"
echo "com.chatmail.source.ref=${RELAY_REF}"
echo "com.chatmail.changes=${CHANGES}"
echo "EOF"
} >> "$GITHUB_OUTPUT"
# Annotations on the OCI image index so GHCR shows the description.
# "index:" prefix = top-level index object annotations.
# "manifest-descriptor:" = per-entry inside the index (not what GHCR reads).
# No prefix = per-platform image manifest.
{
echo "annotations<<EOF"
echo "index:org.opencontainers.image.title=chatmail-relay"
echo "index:org.opencontainers.image.description=${DESC}"
echo "EOF"
} >> "$GITHUB_OUTPUT"
- name: Copy .dockerignore to build context
run: cp docker/.dockerignore .dockerignore
- name: Build and push
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7
with:
context: .
file: docker/chatmail_relay.dockerfile
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
annotations: ${{ steps.meta.outputs.annotations }}
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
GIT_HASH=${{ steps.meta.outputs.relay_sha }}
SOURCE_REF=${{ steps.meta.outputs.relay_ref }}
BUILD_DATE=${{ steps.meta.outputs.build_date }}
test:
name: Integration test
needs: build
permissions: {}
if: github.event_name != 'pull_request'
# TODO: revert to @main once cmlxc docker support is merged
uses: chatmail/cmlxc/.github/workflows/lxc-test.yml@j4n/docker-support
with:
# TODO: revert to main once cmlxc docker support is merged
cmlxc_ref: j4n/docker-support
cmlxc_commands: |
cmlxc init
cmlxc docker deploy dock0 --source ghcr:${{ needs.build.outputs.image_tag }}
RELAY_REF=${{ needs.build.outputs.relay_ref }} cmlxc test-cmdeploy dock0