mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2025-09-15 17:26:58 +00:00
ci: Split Docker builds into sequential release and max-perf stages
Separate fast release builds from slow max-perf builds to optimise runner utilisation and provide quicker feedback. Release builds complete first with standard optimisations, followed by Haswell-optimised dragrace builds once the safe builds pass successfully. Extract build logic into focused composite actions for better log visibility in Forgejo UI. Split monolithic build action into prepare-docker-build, inline docker build step, and upload-docker-artifacts to ensure each phase completes independently and shows logs immediately. Creates separate manifests at each stage to avoid waiting for all builds before publishing.
This commit is contained in:
parent
9c147b182f
commit
542dff50bd
4 changed files with 461 additions and 249 deletions
104
.forgejo/actions/create-docker-manifest/action.yml
Normal file
104
.forgejo/actions/create-docker-manifest/action.yml
Normal file
|
@ -0,0 +1,104 @@
|
|||
name: create-manifest
|
||||
description: |
|
||||
Create and push a multi-platform Docker manifest from individual platform digests.
|
||||
Handles downloading digests, creating manifest lists, and pushing to registry.
|
||||
|
||||
inputs:
|
||||
digest_pattern:
|
||||
description: Glob pattern to match digest artifacts (e.g. "digests-linux-{amd64,arm64}")
|
||||
required: true
|
||||
tag_suffix:
|
||||
description: Suffix to add to all Docker tags (e.g. "-maxperf")
|
||||
required: false
|
||||
default: ""
|
||||
images:
|
||||
description: Container registry images (newline-separated)
|
||||
required: true
|
||||
registry_user:
|
||||
description: Registry username for authentication
|
||||
required: false
|
||||
registry_password:
|
||||
description: Registry password for authentication
|
||||
required: false
|
||||
|
||||
outputs:
|
||||
version:
|
||||
description: The version tag created for the manifest
|
||||
value: ${{ steps.meta.outputs.version }}
|
||||
tags:
|
||||
description: All tags created for the manifest
|
||||
value: ${{ steps.meta.outputs.tags }}
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Download digests
|
||||
if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
|
||||
uses: forgejo/download-artifact@v4
|
||||
with:
|
||||
path: /tmp/digests
|
||||
pattern: ${{ inputs.digest_pattern }}
|
||||
merge-multiple: true
|
||||
|
||||
- name: Login to builtin registry
|
||||
if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.BUILTIN_REGISTRY }}
|
||||
username: ${{ inputs.registry_user }}
|
||||
password: ${{ inputs.registry_password }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
# Use persistent BuildKit if BUILDKIT_ENDPOINT is set (e.g. tcp://buildkit:8125)
|
||||
driver: ${{ env.BUILDKIT_ENDPOINT != '' && 'remote' || 'docker-container' }}
|
||||
endpoint: ${{ env.BUILDKIT_ENDPOINT || '' }}
|
||||
|
||||
- name: Extract metadata (tags) for Docker
|
||||
if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
tags: |
|
||||
type=semver,pattern={{version}},prefix=v,suffix=${{ inputs.tag_suffix }}
|
||||
type=semver,pattern={{major}}.{{minor}},enable=${{ !startsWith(github.ref, 'refs/tags/v0.0.') }},prefix=v,suffix=${{ inputs.tag_suffix }}
|
||||
type=semver,pattern={{major}},enable=${{ !startsWith(github.ref, 'refs/tags/v0.') }},prefix=v,suffix=${{ inputs.tag_suffix }}
|
||||
type=ref,event=branch,prefix=${{ format('refs/heads/{0}', github.event.repository.default_branch) != github.ref && 'branch-' || '' }},suffix=${{ inputs.tag_suffix }}
|
||||
type=ref,event=pr,suffix=${{ inputs.tag_suffix }}
|
||||
type=sha,format=short,suffix=${{ inputs.tag_suffix }}
|
||||
type=raw,value=latest${{ inputs.tag_suffix }},enable=${{ startsWith(github.ref, 'refs/tags/v') }}
|
||||
images: ${{ inputs.images }}
|
||||
# default labels & annotations: https://github.com/docker/metadata-action/blob/master/src/meta.ts#L509
|
||||
env:
|
||||
DOCKER_METADATA_ANNOTATIONS_LEVELS: index
|
||||
|
||||
- name: Create manifest list and push
|
||||
if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
|
||||
working-directory: /tmp/digests
|
||||
shell: bash
|
||||
env:
|
||||
IMAGES: ${{ inputs.images }}
|
||||
run: |
|
||||
IFS=$'\n'
|
||||
IMAGES_LIST=($IMAGES)
|
||||
ANNOTATIONS_LIST=($DOCKER_METADATA_OUTPUT_ANNOTATIONS)
|
||||
TAGS_LIST=($DOCKER_METADATA_OUTPUT_TAGS)
|
||||
for REPO in "${IMAGES_LIST[@]}"; do
|
||||
docker buildx imagetools create \
|
||||
$(for tag in "${TAGS_LIST[@]}"; do echo "--tag"; echo "$tag"; done) \
|
||||
$(for annotation in "${ANNOTATIONS_LIST[@]}"; do echo "--annotation"; echo "$annotation"; done) \
|
||||
$(for reference in *; do printf "$REPO@sha256:%s\n" $reference; done)
|
||||
done
|
||||
|
||||
- name: Inspect image
|
||||
if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
|
||||
shell: bash
|
||||
env:
|
||||
IMAGES: ${{ inputs.images }}
|
||||
run: |
|
||||
IMAGES_LIST=($IMAGES)
|
||||
for REPO in "${IMAGES_LIST[@]}"; do
|
||||
docker buildx imagetools inspect $REPO:${{ steps.meta.outputs.version }}
|
||||
done
|
169
.forgejo/actions/prepare-docker-build/action.yml
Normal file
169
.forgejo/actions/prepare-docker-build/action.yml
Normal file
|
@ -0,0 +1,169 @@
|
|||
name: prepare-docker-build
|
||||
description: |
|
||||
Prepare the Docker build environment for Continuwuity builds.
|
||||
Sets up Rust toolchain, Docker Buildx, caching, and extracts metadata for Docker builds.
|
||||
|
||||
inputs:
|
||||
platform:
|
||||
description: Target platform (e.g. linux/amd64, linux/arm64)
|
||||
required: true
|
||||
slug:
|
||||
description: Platform slug for artifact naming (e.g. linux-amd64, linux-arm64)
|
||||
required: true
|
||||
target_cpu:
|
||||
description: Target CPU architecture (e.g. haswell, empty for base)
|
||||
required: false
|
||||
default: ""
|
||||
profile:
|
||||
description: Cargo build profile (release or release-max-perf)
|
||||
required: true
|
||||
images:
|
||||
description: Container registry images (newline-separated)
|
||||
required: true
|
||||
registry_user:
|
||||
description: Registry username for authentication
|
||||
required: false
|
||||
registry_password:
|
||||
description: Registry password for authentication
|
||||
required: false
|
||||
|
||||
outputs:
|
||||
cpu_suffix:
|
||||
description: CPU suffix for artifact naming
|
||||
value: ${{ steps.cpu-suffix.outputs.suffix }}
|
||||
metadata_labels:
|
||||
description: Docker labels for the image
|
||||
value: ${{ steps.meta.outputs.labels }}
|
||||
metadata_annotations:
|
||||
description: Docker annotations for the image
|
||||
value: ${{ steps.meta.outputs.annotations }}
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Set CPU suffix variable
|
||||
id: cpu-suffix
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ -n "${{ inputs.target_cpu }}" ]]; then
|
||||
echo "suffix=-${{ inputs.target_cpu }}" >> $GITHUB_OUTPUT
|
||||
echo "CPU_SUFFIX=-${{ inputs.target_cpu }}" >> $GITHUB_ENV
|
||||
else
|
||||
echo "suffix=" >> $GITHUB_OUTPUT
|
||||
echo "CPU_SUFFIX=" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Echo matrix configuration
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Platform: ${{ inputs.platform }}"
|
||||
echo "Slug: ${{ inputs.slug }}"
|
||||
echo "Target CPU: ${{ inputs.target_cpu }}"
|
||||
echo "Profile: ${{ inputs.profile }}"
|
||||
|
||||
- name: Install rust
|
||||
if: ${{ env.BUILDKIT_ENDPOINT == '' }}
|
||||
id: rust-toolchain
|
||||
uses: ./.forgejo/actions/rust-toolchain
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
# Use persistent BuildKit if BUILDKIT_ENDPOINT is set (e.g. tcp://buildkit:8125)
|
||||
driver: ${{ env.BUILDKIT_ENDPOINT != '' && 'remote' || 'docker-container' }}
|
||||
endpoint: ${{ env.BUILDKIT_ENDPOINT || '' }}
|
||||
|
||||
- name: Set up QEMU
|
||||
if: ${{ env.BUILDKIT_ENDPOINT == '' }}
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Login to builtin registry
|
||||
if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.BUILTIN_REGISTRY }}
|
||||
username: ${{ inputs.registry_user }}
|
||||
password: ${{ inputs.registry_password }}
|
||||
|
||||
- name: Extract metadata (labels, annotations) for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{ inputs.images }}
|
||||
# default labels & annotations: https://github.com/docker/metadata-action/blob/master/src/meta.ts#L509
|
||||
env:
|
||||
DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index
|
||||
|
||||
- name: Get short git commit SHA
|
||||
id: sha
|
||||
shell: bash
|
||||
run: |
|
||||
calculatedSha=$(git rev-parse --short ${{ github.sha }})
|
||||
echo "COMMIT_SHORT_SHA=$calculatedSha" >> $GITHUB_ENV
|
||||
echo "Short SHA: $calculatedSha"
|
||||
|
||||
- name: Get Git commit timestamps
|
||||
shell: bash
|
||||
run: |
|
||||
timestamp=$(git log -1 --pretty=%ct)
|
||||
echo "TIMESTAMP=$timestamp" >> $GITHUB_ENV
|
||||
echo "Commit timestamp: $timestamp"
|
||||
|
||||
- uses: ./.forgejo/actions/timelord
|
||||
id: timelord
|
||||
|
||||
- name: Cache Rust registry
|
||||
if: ${{ env.BUILDKIT_ENDPOINT == '' }}
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
.cargo/git
|
||||
.cargo/git/checkouts
|
||||
.cargo/registry
|
||||
.cargo/registry/src
|
||||
key: rust-registry-image-${{hashFiles('**/Cargo.lock') }}
|
||||
|
||||
- name: Cache cargo target
|
||||
if: ${{ env.BUILDKIT_ENDPOINT == '' }}
|
||||
id: cache-cargo-target
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
cargo-target${{ env.CPU_SUFFIX }}-${{ inputs.slug }}-${{ inputs.profile }}
|
||||
key: cargo-target${{ env.CPU_SUFFIX }}-${{ inputs.slug }}-${{ inputs.profile }}-${{hashFiles('**/Cargo.lock') }}-${{steps.rust-toolchain.outputs.rustc_version}}
|
||||
|
||||
- name: Cache apt cache
|
||||
if: ${{ env.BUILDKIT_ENDPOINT == '' }}
|
||||
id: cache-apt
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
var-cache-apt-${{ inputs.slug }}
|
||||
key: var-cache-apt-${{ inputs.slug }}
|
||||
|
||||
- name: Cache apt lib
|
||||
if: ${{ env.BUILDKIT_ENDPOINT == '' }}
|
||||
id: cache-apt-lib
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
var-lib-apt-${{ inputs.slug }}
|
||||
key: var-lib-apt-${{ inputs.slug }}
|
||||
|
||||
- name: inject cache into docker
|
||||
if: ${{ env.BUILDKIT_ENDPOINT == '' }}
|
||||
uses: https://github.com/reproducible-containers/buildkit-cache-dance@v3.3.0
|
||||
with:
|
||||
cache-map: |
|
||||
{
|
||||
".cargo/registry": "/usr/local/cargo/registry",
|
||||
".cargo/git/db": "/usr/local/cargo/git/db",
|
||||
"cargo-target${{ env.CPU_SUFFIX }}-${{ inputs.slug }}-${{ inputs.profile }}": {
|
||||
"target": "/app/target",
|
||||
"id": "cargo-target${{ env.CPU_SUFFIX }}-${{ inputs.slug }}-${{ inputs.profile }}"
|
||||
},
|
||||
"var-cache-apt-${{ inputs.slug }}": "/var/cache/apt",
|
||||
"var-lib-apt-${{ inputs.slug }}": "/var/lib/apt",
|
||||
"${{ steps.timelord.outputs.database-path }}":"/timelord"
|
||||
}
|
||||
skip-extraction: ${{ steps.cache.outputs.cache-hit }}
|
70
.forgejo/actions/upload-docker-artifacts/action.yml
Normal file
70
.forgejo/actions/upload-docker-artifacts/action.yml
Normal file
|
@ -0,0 +1,70 @@
|
|||
name: upload-docker-artifacts
|
||||
description: |
|
||||
Upload Docker build artifacts including binary and digest files.
|
||||
Handles artifact naming and conditional digest uploads for registry publishing.
|
||||
|
||||
inputs:
|
||||
slug:
|
||||
description: Platform slug for artifact naming (e.g. linux-amd64, linux-arm64)
|
||||
required: true
|
||||
cpu_suffix:
|
||||
description: CPU suffix for artifact naming (e.g. -haswell)
|
||||
required: false
|
||||
default: ""
|
||||
artifact_suffix:
|
||||
description: Suffix for binary artifacts (e.g. -maxperf)
|
||||
required: false
|
||||
default: ""
|
||||
digest_suffix:
|
||||
description: Suffix for digest artifacts (e.g. -maxperf)
|
||||
required: false
|
||||
default: ""
|
||||
digest:
|
||||
description: The digest of the built Docker image
|
||||
required: true
|
||||
|
||||
outputs:
|
||||
binary_artifact_name:
|
||||
description: The name of the uploaded binary artifact
|
||||
value: conduwuit${{ inputs.cpu_suffix }}-${{ inputs.slug }}${{ inputs.artifact_suffix }}
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Export digest
|
||||
if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p /tmp/digests
|
||||
digest="${{ inputs.digest }}"
|
||||
echo "🔍 Build step digest output: '$digest'"
|
||||
if [[ -z "$digest" ]]; then
|
||||
echo "❌ ERROR: No digest found from build step"
|
||||
exit 1
|
||||
fi
|
||||
digest_file="/tmp/digests/${digest#sha256:}"
|
||||
echo "📁 Creating digest file: $digest_file"
|
||||
touch "$digest_file"
|
||||
echo "✅ Digest file created successfully"
|
||||
echo "📋 Contents of /tmp/digests:"
|
||||
ls -la /tmp/digests/
|
||||
|
||||
- name: Rename extracted binary
|
||||
shell: bash
|
||||
run: mv /tmp/binaries/sbin/conduwuit /tmp/binaries/conduwuit${{ inputs.cpu_suffix }}-${{ inputs.slug }}${{ inputs.artifact_suffix }}
|
||||
|
||||
- name: Upload binary artifact
|
||||
uses: forgejo/upload-artifact@v4
|
||||
with:
|
||||
name: conduwuit${{ inputs.cpu_suffix }}-${{ inputs.slug }}${{ inputs.artifact_suffix }}
|
||||
path: /tmp/binaries/conduwuit${{ inputs.cpu_suffix }}-${{ inputs.slug }}${{ inputs.artifact_suffix }}
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload digest
|
||||
if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
|
||||
uses: forgejo/upload-artifact@v4
|
||||
with:
|
||||
name: digests${{ inputs.digest_suffix }}-${{ inputs.slug }}${{ inputs.cpu_suffix }}
|
||||
path: /tmp/digests/*
|
||||
if-no-files-found: error
|
||||
retention-days: 5
|
|
@ -32,12 +32,12 @@ env:
|
|||
|
||||
jobs:
|
||||
define-variables:
|
||||
name: "Setup Variables"
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
outputs:
|
||||
images: ${{ steps.var.outputs.images }}
|
||||
images_list: ${{ steps.var.outputs.images_list }}
|
||||
build_matrix: ${{ steps.var.outputs.build_matrix }}
|
||||
|
||||
steps:
|
||||
- name: Setting variables
|
||||
|
@ -59,18 +59,9 @@ jobs:
|
|||
}
|
||||
core.setOutput('images', images.join("\n"))
|
||||
core.setOutput('images_list', images.join(","))
|
||||
const platforms = ['linux/amd64', 'linux/arm64']
|
||||
core.setOutput('build_matrix', JSON.stringify({
|
||||
platform: platforms,
|
||||
target_cpu: ['base'],
|
||||
include: platforms.map(platform => { return {
|
||||
platform,
|
||||
slug: platform.replace('/', '-')
|
||||
}})
|
||||
}))
|
||||
|
||||
build-image:
|
||||
name: "Build ${{ matrix.slug }}${{ matrix.target_cpu != '' && format('-{0}', matrix.target_cpu) || '' }}"
|
||||
build-release:
|
||||
name: "Build ${{ matrix.slug }} (release)"
|
||||
runs-on: dind
|
||||
needs: define-variables
|
||||
permissions:
|
||||
|
@ -83,139 +74,25 @@ jobs:
|
|||
include:
|
||||
- platform: "linux/amd64"
|
||||
slug: "linux-amd64"
|
||||
target_cpu: ""
|
||||
profile: "release"
|
||||
- platform: "linux/amd64"
|
||||
slug: "linux-amd64"
|
||||
target_cpu: "haswell"
|
||||
profile: "release-max-perf"
|
||||
- platform: "linux/arm64"
|
||||
slug: "linux-arm64"
|
||||
target_cpu: ""
|
||||
profile: "release"
|
||||
|
||||
steps:
|
||||
- name: Set CPU suffix variable
|
||||
run: |
|
||||
if [[ -n "${{ matrix.target_cpu }}" ]]; then
|
||||
echo "CPU_SUFFIX=-${{ matrix.target_cpu }}" >> $GITHUB_ENV
|
||||
else
|
||||
echo "CPU_SUFFIX=" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Echo strategy
|
||||
run: echo '${{ toJSON(fromJSON(needs.define-variables.outputs.build_matrix)) }}'
|
||||
- name: Echo matrix
|
||||
run: echo '${{ toJSON(matrix) }}'
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Install rust
|
||||
if: ${{ env.BUILDKIT_ENDPOINT == '' }}
|
||||
id: rust-toolchain
|
||||
uses: ./.forgejo/actions/rust-toolchain
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Prepare Docker build environment
|
||||
id: prepare
|
||||
uses: ./.forgejo/actions/prepare-docker-build
|
||||
with:
|
||||
# Use persistent BuildKit if BUILDKIT_ENDPOINT is set (e.g. tcp://buildkit:8125)
|
||||
driver: ${{ env.BUILDKIT_ENDPOINT != '' && 'remote' || 'docker-container' }}
|
||||
endpoint: ${{ env.BUILDKIT_ENDPOINT || '' }}
|
||||
- name: Set up QEMU
|
||||
if: ${{ env.BUILDKIT_ENDPOINT == '' }}
|
||||
uses: docker/setup-qemu-action@v3
|
||||
# Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here.
|
||||
- name: Login to builtin registry
|
||||
if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.BUILTIN_REGISTRY }}
|
||||
username: ${{ vars.BUILTIN_REGISTRY_USER || github.actor }}
|
||||
password: ${{ secrets.BUILTIN_REGISTRY_PASSWORD || secrets.GITHUB_TOKEN }}
|
||||
|
||||
# This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image. The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels.
|
||||
- name: Extract metadata (labels, annotations) for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{needs.define-variables.outputs.images}}
|
||||
# default labels & annotations: https://github.com/docker/metadata-action/blob/master/src/meta.ts#L509
|
||||
env:
|
||||
DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index
|
||||
|
||||
# This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages.
|
||||
# It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see "[Usage](https://github.com/docker/build-push-action#usage)" in the README of the `docker/build-push-action` repository.
|
||||
# It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step.
|
||||
# It will not push images generated from a pull request
|
||||
- name: Get short git commit SHA
|
||||
id: sha
|
||||
run: |
|
||||
calculatedSha=$(git rev-parse --short ${{ github.sha }})
|
||||
echo "COMMIT_SHORT_SHA=$calculatedSha" >> $GITHUB_ENV
|
||||
echo "Short SHA: $calculatedSha"
|
||||
- name: Get Git commit timestamps
|
||||
run: |
|
||||
timestamp=$(git log -1 --pretty=%ct)
|
||||
echo "TIMESTAMP=$timestamp" >> $GITHUB_ENV
|
||||
echo "Commit timestamp: $timestamp"
|
||||
|
||||
- uses: ./.forgejo/actions/timelord
|
||||
id: timelord
|
||||
|
||||
- name: Cache Rust registry
|
||||
if: ${{ env.BUILDKIT_ENDPOINT == '' }}
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
.cargo/git
|
||||
.cargo/git/checkouts
|
||||
.cargo/registry
|
||||
.cargo/registry/src
|
||||
key: rust-registry-image-${{hashFiles('**/Cargo.lock') }}
|
||||
- name: Cache cargo target
|
||||
if: ${{ env.BUILDKIT_ENDPOINT == '' }}
|
||||
id: cache-cargo-target
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
cargo-target${{ env.CPU_SUFFIX }}-${{ matrix.slug }}-${{ matrix.profile }}
|
||||
key: cargo-target${{ env.CPU_SUFFIX }}-${{ matrix.slug }}-${{ matrix.profile }}-${{hashFiles('**/Cargo.lock') }}-${{steps.rust-toolchain.outputs.rustc_version}}
|
||||
- name: Cache apt cache
|
||||
if: ${{ env.BUILDKIT_ENDPOINT == '' }}
|
||||
id: cache-apt
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
var-cache-apt-${{ matrix.slug }}
|
||||
key: var-cache-apt-${{ matrix.slug }}
|
||||
- name: Cache apt lib
|
||||
if: ${{ env.BUILDKIT_ENDPOINT == '' }}
|
||||
id: cache-apt-lib
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
var-lib-apt-${{ matrix.slug }}
|
||||
key: var-lib-apt-${{ matrix.slug }}
|
||||
- name: inject cache into docker
|
||||
if: ${{ env.BUILDKIT_ENDPOINT == '' }}
|
||||
uses: https://github.com/reproducible-containers/buildkit-cache-dance@v3.3.0
|
||||
with:
|
||||
cache-map: |
|
||||
{
|
||||
".cargo/registry": "/usr/local/cargo/registry",
|
||||
".cargo/git/db": "/usr/local/cargo/git/db",
|
||||
"cargo-target${{ env.CPU_SUFFIX }}-${{ matrix.slug }}-${{ matrix.profile }}": {
|
||||
"target": "/app/target",
|
||||
"id": "cargo-target${{ env.CPU_SUFFIX }}-${{ matrix.slug }}-${{ matrix.profile }}"
|
||||
},
|
||||
"var-cache-apt-${{ matrix.slug }}": "/var/cache/apt",
|
||||
"var-lib-apt-${{ matrix.slug }}": "/var/lib/apt",
|
||||
"{{ steps.timelord.outputs.database-path }}":"/timelord"
|
||||
}
|
||||
skip-extraction: ${{ steps.cache.outputs.cache-hit }}
|
||||
|
||||
platform: ${{ matrix.platform }}
|
||||
slug: ${{ matrix.slug }}
|
||||
target_cpu: ""
|
||||
profile: "release"
|
||||
images: ${{ needs.define-variables.outputs.images }}
|
||||
registry_user: ${{ vars.BUILTIN_REGISTRY_USER || github.actor }}
|
||||
registry_password: ${{ secrets.BUILTIN_REGISTRY_PASSWORD || secrets.GITHUB_TOKEN }}
|
||||
- name: Build and push Docker image by digest
|
||||
id: build
|
||||
uses: docker/build-push-action@v6
|
||||
|
@ -228,11 +105,11 @@ jobs:
|
|||
GIT_REMOTE_URL=${{github.event.repository.html_url }}
|
||||
GIT_REMOTE_COMMIT_URL=${{github.event.head_commit.url }}
|
||||
CARGO_INCREMENTAL=${{ env.BUILDKIT_ENDPOINT != '' && '1' || '0' }}
|
||||
TARGET_CPU=${{ matrix.target_cpu }}
|
||||
RUST_PROFILE=${{ matrix.profile }}
|
||||
TARGET_CPU=
|
||||
RUST_PROFILE=release
|
||||
platforms: ${{ matrix.platform }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
annotations: ${{ steps.meta.outputs.annotations }}
|
||||
labels: ${{ steps.prepare.outputs.metadata_labels }}
|
||||
annotations: ${{ steps.prepare.outputs.metadata_annotations }}
|
||||
cache-from: type=gha
|
||||
# cache-to: type=gha,mode=max
|
||||
sbom: true
|
||||
|
@ -241,124 +118,116 @@ jobs:
|
|||
type=local,dest=/tmp/binaries
|
||||
env:
|
||||
SOURCE_DATE_EPOCH: ${{ env.TIMESTAMP }}
|
||||
|
||||
# For publishing multi-platform manifests
|
||||
- name: Export digest
|
||||
if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
|
||||
run: |
|
||||
mkdir -p /tmp/digests
|
||||
digest="${{ steps.build.outputs.digest }}"
|
||||
echo "🔍 Build step digest output: '$digest'"
|
||||
if [[ -z "$digest" ]]; then
|
||||
echo "❌ ERROR: No digest found from build step"
|
||||
exit 1
|
||||
fi
|
||||
digest_file="/tmp/digests/${digest#sha256:}"
|
||||
echo "📁 Creating digest file: $digest_file"
|
||||
touch "$digest_file"
|
||||
echo "✅ Digest file created successfully"
|
||||
echo "📋 Contents of /tmp/digests:"
|
||||
ls -la /tmp/digests/
|
||||
|
||||
# Binary extracted via local output for all builds
|
||||
- name: Rename extracted binary
|
||||
run: mv /tmp/binaries/sbin/conduwuit /tmp/binaries/conduwuit${{ env.CPU_SUFFIX }}-${{ matrix.slug }}-${{ matrix.profile }}
|
||||
|
||||
- name: Upload binary artifact
|
||||
uses: forgejo/upload-artifact@v4
|
||||
- name: Upload Docker artifacts
|
||||
uses: ./.forgejo/actions/upload-docker-artifacts
|
||||
with:
|
||||
name: conduwuit${{ env.CPU_SUFFIX }}-${{ matrix.slug }}-${{ matrix.profile }}
|
||||
path: /tmp/binaries/conduwuit${{ env.CPU_SUFFIX }}-${{ matrix.slug }}-${{ matrix.profile }}
|
||||
if-no-files-found: error
|
||||
slug: ${{ matrix.slug }}
|
||||
cpu_suffix: ${{ steps.prepare.outputs.cpu_suffix }}
|
||||
artifact_suffix: ""
|
||||
digest_suffix: ""
|
||||
digest: ${{ steps.build.outputs.digest }}
|
||||
|
||||
- name: Upload digest
|
||||
if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
|
||||
uses: forgejo/upload-artifact@v4
|
||||
with:
|
||||
name: digests-${{ matrix.slug }}${{ env.CPU_SUFFIX }}
|
||||
path: /tmp/digests/*
|
||||
if-no-files-found: error
|
||||
retention-days: 5
|
||||
|
||||
merge:
|
||||
name: "Create ${{ matrix.target_cpu == '' && 'Multi-arch' || 'Haswell' }} Manifest"
|
||||
merge-release:
|
||||
name: "Create Multi-arch Release Manifest"
|
||||
runs-on: dind
|
||||
needs: [define-variables, build-image]
|
||||
needs: [define-variables, build-release]
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Create multi-platform manifest
|
||||
uses: ./.forgejo/actions/create-docker-manifest
|
||||
with:
|
||||
digest_pattern: "digests-linux-{amd64,arm64}"
|
||||
tag_suffix: ""
|
||||
images: ${{ needs.define-variables.outputs.images }}
|
||||
registry_user: ${{ vars.BUILTIN_REGISTRY_USER || github.actor }}
|
||||
registry_password: ${{ secrets.BUILTIN_REGISTRY_PASSWORD || secrets.GITHUB_TOKEN }}
|
||||
|
||||
build-maxperf:
|
||||
name: "Build ${{ matrix.slug }} (max-perf)"
|
||||
runs-on: dind
|
||||
needs: [define-variables, build-release]
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
attestations: write
|
||||
id-token: write
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- target_cpu: ""
|
||||
digest_pattern: "digests-linux-{amd64,arm64}"
|
||||
- target_cpu: "haswell"
|
||||
digest_pattern: "digests-linux-amd64-haswell"
|
||||
- platform: "linux/amd64"
|
||||
slug: "linux-amd64"
|
||||
target_cpu: "haswell"
|
||||
- platform: "linux/arm64"
|
||||
slug: "linux-arm64"
|
||||
target_cpu: ""
|
||||
|
||||
steps:
|
||||
- name: Download digests
|
||||
if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
|
||||
uses: forgejo/download-artifact@v4
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
path: /tmp/digests
|
||||
pattern: ${{ matrix.digest_pattern }}
|
||||
merge-multiple: true
|
||||
# Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here.
|
||||
- name: Login to builtin registry
|
||||
if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
|
||||
uses: docker/login-action@v3
|
||||
persist-credentials: false
|
||||
- name: Prepare max-perf Docker build environment
|
||||
id: prepare
|
||||
uses: ./.forgejo/actions/prepare-docker-build
|
||||
with:
|
||||
registry: ${{ env.BUILTIN_REGISTRY }}
|
||||
username: ${{ vars.BUILTIN_REGISTRY_USER || github.actor }}
|
||||
password: ${{ secrets.BUILTIN_REGISTRY_PASSWORD || secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
|
||||
uses: docker/setup-buildx-action@v3
|
||||
platform: ${{ matrix.platform }}
|
||||
slug: ${{ matrix.slug }}
|
||||
target_cpu: ${{ matrix.target_cpu }}
|
||||
profile: "release-max-perf"
|
||||
images: ${{ needs.define-variables.outputs.images }}
|
||||
registry_user: ${{ vars.BUILTIN_REGISTRY_USER || github.actor }}
|
||||
registry_password: ${{ secrets.BUILTIN_REGISTRY_PASSWORD || secrets.GITHUB_TOKEN }}
|
||||
- name: Build and push max-perf Docker image by digest
|
||||
id: build
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
# Use persistent BuildKit if BUILDKIT_ENDPOINT is set (e.g. tcp://buildkit:8125)
|
||||
driver: ${{ env.BUILDKIT_ENDPOINT != '' && 'remote' || 'docker-container' }}
|
||||
endpoint: ${{ env.BUILDKIT_ENDPOINT || '' }}
|
||||
|
||||
- name: Extract metadata (tags) for Docker
|
||||
if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
tags: |
|
||||
type=semver,pattern={{version}},prefix=v,suffix=${{ matrix.target_cpu != '' && format('-{0}', matrix.target_cpu) || '' }}
|
||||
type=semver,pattern={{major}}.{{minor}},enable=${{ !startsWith(github.ref, 'refs/tags/v0.0.') }},prefix=v,suffix=${{ matrix.target_cpu != '' && format('-{0}', matrix.target_cpu) || '' }}
|
||||
type=semver,pattern={{major}},enable=${{ !startsWith(github.ref, 'refs/tags/v0.') }},prefix=v,suffix=${{ matrix.target_cpu != '' && format('-{0}', matrix.target_cpu) || '' }}
|
||||
type=ref,event=branch,prefix=${{ format('refs/heads/{0}', github.event.repository.default_branch) != github.ref && 'branch-' || '' }},suffix=${{ matrix.target_cpu != '' && format('-{0}', matrix.target_cpu) || '' }}
|
||||
type=ref,event=pr,suffix=${{ matrix.target_cpu != '' && format('-{0}', matrix.target_cpu) || '' }}
|
||||
type=sha,format=short,suffix=${{ matrix.target_cpu != '' && format('-{0}', matrix.target_cpu) || '' }}
|
||||
type=raw,value=latest${{ matrix.target_cpu != '' && format('-{0}', matrix.target_cpu) || '' }},enable=${{ startsWith(github.ref, 'refs/tags/v') }}
|
||||
images: ${{needs.define-variables.outputs.images}}
|
||||
# default labels & annotations: https://github.com/docker/metadata-action/blob/master/src/meta.ts#L509
|
||||
context: .
|
||||
file: "docker/Dockerfile"
|
||||
build-args: |
|
||||
GIT_COMMIT_HASH=${{ github.sha }}
|
||||
GIT_COMMIT_HASH_SHORT=${{ env.COMMIT_SHORT_SHA }}
|
||||
GIT_REMOTE_URL=${{github.event.repository.html_url }}
|
||||
GIT_REMOTE_COMMIT_URL=${{github.event.head_commit.url }}
|
||||
CARGO_INCREMENTAL=${{ env.BUILDKIT_ENDPOINT != '' && '1' || '0' }}
|
||||
TARGET_CPU=${{ matrix.target_cpu }}
|
||||
RUST_PROFILE=release-max-perf
|
||||
platforms: ${{ matrix.platform }}
|
||||
labels: ${{ steps.prepare.outputs.metadata_labels }}
|
||||
annotations: ${{ steps.prepare.outputs.metadata_annotations }}
|
||||
cache-from: type=gha
|
||||
# cache-to: type=gha,mode=max
|
||||
sbom: true
|
||||
outputs: |
|
||||
${{ env.BUILTIN_REGISTRY_ENABLED == 'true' && format('type=image,"name={0}",push-by-digest=true,name-canonical=true,push=true', needs.define-variables.outputs.images_list) || format('type=image,"name={0}",push=false', needs.define-variables.outputs.images_list) }}
|
||||
type=local,dest=/tmp/binaries
|
||||
env:
|
||||
DOCKER_METADATA_ANNOTATIONS_LEVELS: index
|
||||
SOURCE_DATE_EPOCH: ${{ env.TIMESTAMP }}
|
||||
- name: Upload max-perf Docker artifacts
|
||||
uses: ./.forgejo/actions/upload-docker-artifacts
|
||||
with:
|
||||
slug: ${{ matrix.slug }}
|
||||
cpu_suffix: ${{ steps.prepare.outputs.cpu_suffix }}
|
||||
artifact_suffix: "-maxperf"
|
||||
digest_suffix: "-maxperf"
|
||||
digest: ${{ steps.build.outputs.digest }}
|
||||
|
||||
- name: Create manifest list and push
|
||||
if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
|
||||
working-directory: /tmp/digests
|
||||
env:
|
||||
IMAGES: ${{needs.define-variables.outputs.images}}
|
||||
shell: bash
|
||||
run: |
|
||||
IFS=$'\n'
|
||||
IMAGES_LIST=($IMAGES)
|
||||
ANNOTATIONS_LIST=($DOCKER_METADATA_OUTPUT_ANNOTATIONS)
|
||||
TAGS_LIST=($DOCKER_METADATA_OUTPUT_TAGS)
|
||||
for REPO in "${IMAGES_LIST[@]}"; do
|
||||
docker buildx imagetools create \
|
||||
$(for tag in "${TAGS_LIST[@]}"; do echo "--tag"; echo "$tag"; done) \
|
||||
$(for annotation in "${ANNOTATIONS_LIST[@]}"; do echo "--annotation"; echo "$annotation"; done) \
|
||||
$(for reference in *; do printf "$REPO@sha256:%s\n" $reference; done)
|
||||
done
|
||||
|
||||
- name: Inspect image
|
||||
if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
|
||||
env:
|
||||
IMAGES: ${{needs.define-variables.outputs.images}}
|
||||
shell: bash
|
||||
run: |
|
||||
IMAGES_LIST=($IMAGES)
|
||||
for REPO in "${IMAGES_LIST[@]}"; do
|
||||
docker buildx imagetools inspect $REPO:${{ steps.meta.outputs.version }}
|
||||
done
|
||||
merge-maxperf:
|
||||
name: "Create Max-Perf Manifest"
|
||||
runs-on: dind
|
||||
needs: [define-variables, build-maxperf]
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Create max-perf manifest
|
||||
uses: ./.forgejo/actions/create-docker-manifest
|
||||
with:
|
||||
digest_pattern: "digests-maxperf-linux-{amd64-haswell,arm64}"
|
||||
tag_suffix: "-maxperf"
|
||||
images: ${{ needs.define-variables.outputs.images }}
|
||||
registry_user: ${{ vars.BUILTIN_REGISTRY_USER || github.actor }}
|
||||
registry_password: ${{ secrets.BUILTIN_REGISTRY_PASSWORD || secrets.GITHUB_TOKEN }}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue