Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions .github/actions/build-rust-target/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Build Rust target
description: Install a Rust toolchain and build release binaries for one target.

inputs:
target:
description: Rust target triple.
required: true
toolchain:
description: Rust toolchain version.
required: true
use-cross:
description: Use cross instead of cargo for the build.
required: false
default: "false"
working-directory:
description: Directory where cargo or cross should run.
required: false
default: "."

runs:
using: composite
steps:
- name: Install toolchain
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ inputs.toolchain }}
components: rustfmt
targets: ${{ inputs.target }}

- name: Install cross
if: inputs.use-cross == 'true'
uses: taiki-e/install-action@cross

- name: Build with cross
if: inputs.use-cross == 'true'
shell: bash
working-directory: ${{ inputs.working-directory }}
run: cross build --release --all-features --target=${{ inputs.target }}

- name: Build with cargo
if: inputs.use-cross != 'true'
shell: bash
working-directory: ${{ inputs.working-directory }}
run: cargo build --release --all-features --target=${{ inputs.target }}
148 changes: 148 additions & 0 deletions .github/actions/docker-build-and-push/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
name: Build and push Docker image
description: Build a single-architecture Docker image from downloaded Rust binaries.

inputs:
artifact-name:
description: GitHub artifact name containing the binaries.
required: true
artifact-path:
description: Directory where the binaries should be downloaded.
required: true
context:
description: Docker build context.
required: true
docker-platform:
description: Docker platform to build.
required: true
docker-hub-image:
description: Docker Hub image name.
required: true
ghcr-image:
description: GHCR image name.
required: true
image-title:
description: Human-readable image title used in OCI metadata.
required: true
image-description:
description: Human-readable image description used in OCI metadata.
required: true
project-url:
description: Project homepage URL used in OCI metadata.
required: true
documentation-url:
description: Documentation URL used in OCI metadata.
required: true
arch-name:
description: Architecture suffix used in tags.
required: true
s6-arch:
description: s6-overlay architecture build argument. Leave empty for classic images.
required: false
default: ""
version-tag:
description: Exact version tag for immutable image tags.
required: true
major-tag:
description: Major version tag without a leading v.
required: true
latest-tag:
description: Floating release tag.
required: true
docker-hub-username:
description: Docker Hub username.
required: true
docker-hub-password:
description: Docker Hub token.
required: true
ghcr-username:
description: GHCR username.
required: true
ghcr-token:
description: GHCR token.
required: true

runs:
using: composite
steps:
- name: Download binaries
uses: actions/download-artifact@v6
with:
name: ${{ inputs.artifact-name }}
path: ${{ inputs.artifact-path }}

- name: Make binaries executable
shell: bash
run: chmod -v a+x "${{ inputs.artifact-path }}"/*

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4

- name: Log in to Docker Hub
uses: docker/login-action@v4
with:
username: ${{ inputs.docker-hub-username }}
password: ${{ inputs.docker-hub-password }}

- name: Log in to GHCR
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ inputs.ghcr-username }}
password: ${{ inputs.ghcr-token }}

- name: Resolve source revision
id: revision
shell: bash
run: |
source_dir="$(dirname "${{ inputs.context }}")"
echo "sha=$(git -C "${source_dir}" rev-parse HEAD)" >> "${GITHUB_OUTPUT}"

- name: Resolve created timestamp
id: created
shell: bash
run: |
echo "value=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "${GITHUB_OUTPUT}"

- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v6
with:
images: registry.hub.docker.com/${{ inputs.docker-hub-image }}
labels: |
org.opencontainers.image.title=${{ inputs.image-title }}
org.opencontainers.image.description=${{ inputs.image-description }}
org.opencontainers.image.url=${{ inputs.project-url }}
org.opencontainers.image.source=${{ inputs.project-url }}
org.opencontainers.image.version=${{ inputs.version-tag }}
org.opencontainers.image.revision=${{ steps.revision.outputs.sha }}
org.opencontainers.image.created=${{ steps.created.outputs.value }}
org.opencontainers.image.licenses=AGPL-3.0-or-later
org.opencontainers.image.documentation=${{ inputs.documentation-url }}

- name: Resolve build args
id: build-args
shell: bash
run: |
if [ -n "${{ inputs.s6-arch }}" ]; then
echo "value=S6_ARCH=${{ inputs.s6-arch }}" >> "${GITHUB_OUTPUT}"
fi

- name: Build and push Docker image
uses: docker/build-push-action@v7
with:
context: ${{ inputs.context }}
platforms: ${{ inputs.docker-platform }}
push: true
provenance: false
build-args: ${{ steps.build-args.outputs.value }}
tags: |
${{ inputs.docker-hub-image }}:${{ inputs.latest-tag }}-${{ inputs.arch-name }}
${{ inputs.docker-hub-image }}:${{ inputs.version-tag }}-${{ inputs.arch-name }}
${{ inputs.docker-hub-image }}:${{ inputs.major-tag }}-${{ inputs.arch-name }}
${{ inputs.ghcr-image }}:${{ inputs.latest-tag }}-${{ inputs.arch-name }}
${{ inputs.ghcr-image }}:${{ inputs.version-tag }}-${{ inputs.arch-name }}
${{ inputs.ghcr-image }}:${{ inputs.major-tag }}-${{ inputs.arch-name }}
labels: ${{ steps.meta.outputs.labels }}
126 changes: 126 additions & 0 deletions .github/actions/docker-manifest/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
name: Create Docker manifests
description: Create Docker Hub and GHCR multi-architecture manifests.

inputs:
docker-hub-image:
description: Docker Hub image name.
required: true
ghcr-image:
description: GHCR image name.
required: true
source-path:
description: Checked out repository path used to resolve the image revision.
required: true
image-title:
description: Human-readable image title used in OCI metadata.
required: true
image-description:
description: Human-readable image description used in OCI metadata.
required: true
project-url:
description: Project homepage URL used in OCI metadata.
required: true
documentation-url:
description: Documentation URL used in OCI metadata.
required: true
arch-suffixes:
description: Space-separated architecture suffixes.
required: true
version-tag:
description: Exact version tag for immutable image tags.
required: true
major-tag:
description: Major version tag without a leading v.
required: true
latest-tag:
description: Floating release tag.
required: true
docker-hub-username:
description: Docker Hub username.
required: true
docker-hub-password:
description: Docker Hub token.
required: true
ghcr-username:
description: GHCR username.
required: true
ghcr-token:
description: GHCR token.
required: true

runs:
using: composite
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4

- name: Log in to Docker Hub
uses: docker/login-action@v4
with:
username: ${{ inputs.docker-hub-username }}
password: ${{ inputs.docker-hub-password }}

- name: Log in to GHCR
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ inputs.ghcr-username }}
password: ${{ inputs.ghcr-token }}

- name: Resolve source revision
id: revision
shell: bash
run: |
echo "sha=$(git -C "${{ inputs.source-path }}" rev-parse HEAD)" >> "${GITHUB_OUTPUT}"

- name: Resolve created timestamp
id: created
shell: bash
run: |
echo "value=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "${GITHUB_OUTPUT}"

- name: Create manifests
shell: bash
env:
DOCKER_HUB_IMAGE: ${{ inputs.docker-hub-image }}
GHCR_IMAGE: ${{ inputs.ghcr-image }}
IMAGE_TITLE: ${{ inputs.image-title }}
IMAGE_DESCRIPTION: ${{ inputs.image-description }}
PROJECT_URL: ${{ inputs.project-url }}
DOCUMENTATION_URL: ${{ inputs.documentation-url }}
ARCH_SUFFIXES: ${{ inputs.arch-suffixes }}
VERSION_TAG: ${{ inputs.version-tag }}
MAJOR_TAG: ${{ inputs.major-tag }}
LATEST_TAG: ${{ inputs.latest-tag }}
REVISION: ${{ steps.revision.outputs.sha }}
CREATED: ${{ steps.created.outputs.value }}
run: |
create_manifest() {
local image="$1"
local tag="$2"
local sources=""

for arch in ${ARCH_SUFFIXES}; do
sources="${sources} ${image}:${tag}-${arch}"
done

docker buildx imagetools create \
--tag "${image}:${tag}" \
--annotation "index:org.opencontainers.image.title=${IMAGE_TITLE}" \
--annotation "index:org.opencontainers.image.description=${IMAGE_DESCRIPTION}" \
--annotation "index:org.opencontainers.image.url=${PROJECT_URL}" \
--annotation "index:org.opencontainers.image.source=${PROJECT_URL}" \
--annotation "index:org.opencontainers.image.version=${VERSION_TAG}" \
--annotation "index:org.opencontainers.image.revision=${REVISION}" \
--annotation "index:org.opencontainers.image.created=${CREATED}" \
--annotation "index:org.opencontainers.image.licenses=AGPL-3.0-or-later" \
--annotation "index:org.opencontainers.image.documentation=${DOCUMENTATION_URL}" \
${sources}
}

create_manifest "${DOCKER_HUB_IMAGE}" "${VERSION_TAG}"
create_manifest "${GHCR_IMAGE}" "${VERSION_TAG}"
create_manifest "${DOCKER_HUB_IMAGE}" "${MAJOR_TAG}"
create_manifest "${GHCR_IMAGE}" "${MAJOR_TAG}"
create_manifest "${DOCKER_HUB_IMAGE}" "${LATEST_TAG}"
create_manifest "${GHCR_IMAGE}" "${LATEST_TAG}"
Loading