ci: Fix BuildKit cache invalidation and add Haswell-optimised builds

The workflow was rebuilding dependencies unnecessarily despite timelord
restoring timestamps because TARGET_CPU and RUST_PROFILE weren't passed
to Docker, creating inconsistent cache keys. Now passes both arguments
for proper cache reuse.

Adds Haswell-optimised builds alongside baseline builds using -march=haswell
for PCLMUL instruction support. Recent build improvements reducing compile
times from 15-20 minutes to ~5 minutes make this additional CPU variant
feasible. Users can pull optimised images with -haswell suffix.
This commit is contained in:
Tom Foster 2025-09-11 12:30:19 +01:00
commit 9c147b182f
2 changed files with 50 additions and 28 deletions

View file

@ -70,6 +70,7 @@ jobs:
})) }))
build-image: build-image:
name: "Build ${{ matrix.slug }}${{ matrix.target_cpu != '' && format('-{0}', matrix.target_cpu) || '' }}"
runs-on: dind runs-on: dind
needs: define-variables needs: define-variables
permissions: permissions:
@ -79,18 +80,29 @@ jobs:
id-token: write id-token: write
strategy: strategy:
matrix: matrix:
{ include:
"target_cpu": ["base"], - platform: "linux/amd64"
"profile": ["release"], slug: "linux-amd64"
"include": target_cpu: ""
[ profile: "release"
{ "platform": "linux/amd64", "slug": "linux-amd64" }, - platform: "linux/amd64"
{ "platform": "linux/arm64", "slug": "linux-arm64" }, slug: "linux-amd64"
], target_cpu: "haswell"
"platform": ["linux/amd64", "linux/arm64"], profile: "release-max-perf"
} - platform: "linux/arm64"
slug: "linux-arm64"
target_cpu: ""
profile: "release"
steps: 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 - name: Echo strategy
run: echo '${{ toJSON(fromJSON(needs.define-variables.outputs.build_matrix)) }}' run: echo '${{ toJSON(fromJSON(needs.define-variables.outputs.build_matrix)) }}'
- name: Echo matrix - name: Echo matrix
@ -168,8 +180,8 @@ jobs:
uses: actions/cache@v3 uses: actions/cache@v3
with: with:
path: | path: |
cargo-target-${{ matrix.target_cpu }}-${{ matrix.slug }}-${{ matrix.profile }} cargo-target${{ env.CPU_SUFFIX }}-${{ matrix.slug }}-${{ matrix.profile }}
key: cargo-target-${{ matrix.target_cpu }}-${{ matrix.slug }}-${{ matrix.profile }}-${{hashFiles('**/Cargo.lock') }}-${{steps.rust-toolchain.outputs.rustc_version}} key: cargo-target${{ env.CPU_SUFFIX }}-${{ matrix.slug }}-${{ matrix.profile }}-${{hashFiles('**/Cargo.lock') }}-${{steps.rust-toolchain.outputs.rustc_version}}
- name: Cache apt cache - name: Cache apt cache
if: ${{ env.BUILDKIT_ENDPOINT == '' }} if: ${{ env.BUILDKIT_ENDPOINT == '' }}
id: cache-apt id: cache-apt
@ -194,9 +206,9 @@ jobs:
{ {
".cargo/registry": "/usr/local/cargo/registry", ".cargo/registry": "/usr/local/cargo/registry",
".cargo/git/db": "/usr/local/cargo/git/db", ".cargo/git/db": "/usr/local/cargo/git/db",
"cargo-target-${{ matrix.target_cpu }}-${{ matrix.slug }}-${{ matrix.profile }}": { "cargo-target${{ env.CPU_SUFFIX }}-${{ matrix.slug }}-${{ matrix.profile }}": {
"target": "/app/target", "target": "/app/target",
"id": "cargo-target-${{ matrix.target_cpu }}-${{ matrix.slug }}-${{ matrix.profile }}" "id": "cargo-target${{ env.CPU_SUFFIX }}-${{ matrix.slug }}-${{ matrix.profile }}"
}, },
"var-cache-apt-${{ matrix.slug }}": "/var/cache/apt", "var-cache-apt-${{ matrix.slug }}": "/var/cache/apt",
"var-lib-apt-${{ matrix.slug }}": "/var/lib/apt", "var-lib-apt-${{ matrix.slug }}": "/var/lib/apt",
@ -216,6 +228,8 @@ jobs:
GIT_REMOTE_URL=${{github.event.repository.html_url }} GIT_REMOTE_URL=${{github.event.repository.html_url }}
GIT_REMOTE_COMMIT_URL=${{github.event.head_commit.url }} GIT_REMOTE_COMMIT_URL=${{github.event.head_commit.url }}
CARGO_INCREMENTAL=${{ env.BUILDKIT_ENDPOINT != '' && '1' || '0' }} CARGO_INCREMENTAL=${{ env.BUILDKIT_ENDPOINT != '' && '1' || '0' }}
TARGET_CPU=${{ matrix.target_cpu }}
RUST_PROFILE=${{ matrix.profile }}
platforms: ${{ matrix.platform }} platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }} labels: ${{ steps.meta.outputs.labels }}
annotations: ${{ steps.meta.outputs.annotations }} annotations: ${{ steps.meta.outputs.annotations }}
@ -248,34 +262,42 @@ jobs:
# Binary extracted via local output for all builds # Binary extracted via local output for all builds
- name: Rename extracted binary - name: Rename extracted binary
run: mv /tmp/binaries/sbin/conduwuit /tmp/binaries/conduwuit-${{ matrix.target_cpu }}-${{ matrix.slug }}-${{ matrix.profile }} run: mv /tmp/binaries/sbin/conduwuit /tmp/binaries/conduwuit${{ env.CPU_SUFFIX }}-${{ matrix.slug }}-${{ matrix.profile }}
- name: Upload binary artifact - name: Upload binary artifact
uses: forgejo/upload-artifact@v4 uses: forgejo/upload-artifact@v4
with: with:
name: conduwuit-${{ matrix.target_cpu }}-${{ matrix.slug }}-${{ matrix.profile }} name: conduwuit${{ env.CPU_SUFFIX }}-${{ matrix.slug }}-${{ matrix.profile }}
path: /tmp/binaries/conduwuit-${{ matrix.target_cpu }}-${{ matrix.slug }}-${{ matrix.profile }} path: /tmp/binaries/conduwuit${{ env.CPU_SUFFIX }}-${{ matrix.slug }}-${{ matrix.profile }}
if-no-files-found: error if-no-files-found: error
- name: Upload digest - name: Upload digest
if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }} if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
uses: forgejo/upload-artifact@v4 uses: forgejo/upload-artifact@v4
with: with:
name: digests-${{ matrix.slug }} name: digests-${{ matrix.slug }}${{ env.CPU_SUFFIX }}
path: /tmp/digests/* path: /tmp/digests/*
if-no-files-found: error if-no-files-found: error
retention-days: 5 retention-days: 5
merge: merge:
name: "Create ${{ matrix.target_cpu == '' && 'Multi-arch' || 'Haswell' }} Manifest"
runs-on: dind runs-on: dind
needs: [define-variables, build-image] needs: [define-variables, build-image]
strategy:
matrix:
include:
- target_cpu: ""
digest_pattern: "digests-linux-{amd64,arm64}"
- target_cpu: "haswell"
digest_pattern: "digests-linux-amd64-haswell"
steps: steps:
- name: Download digests - name: Download digests
if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }} if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
uses: forgejo/download-artifact@v4 uses: forgejo/download-artifact@v4
with: with:
path: /tmp/digests path: /tmp/digests
pattern: digests-* pattern: ${{ matrix.digest_pattern }}
merge-multiple: true 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. # 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 - name: Login to builtin registry
@ -300,13 +322,13 @@ jobs:
uses: docker/metadata-action@v5 uses: docker/metadata-action@v5
with: with:
tags: | tags: |
type=semver,pattern={{version}},prefix=v 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 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 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-' || '' }} 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 type=ref,event=pr,suffix=${{ matrix.target_cpu != '' && format('-{0}', matrix.target_cpu) || '' }}
type=sha,format=long type=sha,format=short,suffix=${{ matrix.target_cpu != '' && format('-{0}', matrix.target_cpu) || '' }}
type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') }} 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}} images: ${{needs.define-variables.outputs.images}}
# default labels & annotations: https://github.com/docker/metadata-action/blob/master/src/meta.ts#L509 # default labels & annotations: https://github.com/docker/metadata-action/blob/master/src/meta.ts#L509
env: env:

View file

@ -181,8 +181,8 @@ RUN --mount=type=cache,target=/usr/local/cargo/registry \
jq -r ".packages[] | select(.name == \"$PACKAGE\") | .targets[] | select( .kind | map(. == \"bin\") | any ) | .name")) jq -r ".packages[] | select(.name == \"$PACKAGE\") | .targets[] | select( .kind | map(. == \"bin\") | any ) | .name"))
for BINARY in "${BINARIES[@]}"; do for BINARY in "${BINARIES[@]}"; do
echo $BINARY echo $BINARY
xx-verify $TARGET_DIR/$(xx-cargo --print-target-triple)/release/$BINARY xx-verify $TARGET_DIR/$(xx-cargo --print-target-triple)/${RUST_PROFILE}/$BINARY
cp $TARGET_DIR/$(xx-cargo --print-target-triple)/release/$BINARY /out/sbin/$BINARY cp $TARGET_DIR/$(xx-cargo --print-target-triple)/${RUST_PROFILE}/$BINARY /out/sbin/$BINARY
done done
EOF EOF