Skip to content
Merged
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
11 changes: 1 addition & 10 deletions .github/workflows/docker-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,7 @@ on:
- "Cargo.lock"
- "**/*.rs"
- ".github/workflows/docker-ci.yml"
pull_request:
paths:
- "Dockerfile"
- "compose/**"
- "d-lmdb/**"
- "d-lmdb-server/**"
- "Cargo.toml"
- "Cargo.lock"
- "**/*.rs"
- ".github/workflows/docker-ci.yml"
pull_request: {}

permissions:
contents: read
Expand Down
92 changes: 67 additions & 25 deletions .github/workflows/docker-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,63 @@ on:
permissions:
contents: read

concurrency:
group: docker-release
cancel-in-progress: false
Comment thread
JoshuaChi marked this conversation as resolved.

env:
IMAGE: deventlab/d-lmdb

jobs:
check-version:
name: Check version and reject duplicates
runs-on: ubuntu-latest
outputs:
stripped_version: ${{ steps.resolve.outputs.stripped_version }}

steps:
- name: Resolve version
id: resolve
shell: bash
env:
VERSION_INPUT: ${{ inputs.version }}
RELEASE_TAG: ${{ github.event.release.tag_name }}
run: |
VERSION="${VERSION_INPUT:-$RELEASE_TAG}"
[ -n "$VERSION" ] || { echo "ERROR: no version resolved from input or release tag"; exit 1; }
echo "stripped_version=${VERSION#v}" >> "$GITHUB_OUTPUT"

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

- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}

- name: Reject if version tag already exists
shell: bash
env:
IMAGE: ${{ env.IMAGE }}
STRIPPED_VERSION: ${{ steps.resolve.outputs.stripped_version }}
run: |
ERR=$(docker buildx imagetools inspect "docker.io/${IMAGE}:${STRIPPED_VERSION}" 2>&1 >/dev/null)
RC=$?
if [ $RC -eq 0 ]; then
echo "ERROR: ${STRIPPED_VERSION} already exists — will not overwrite"
exit 1
elif echo "$ERR" | grep -qi 'not found\|manifest unknown'; then
echo "OK: ${STRIPPED_VERSION} is available"
else
echo "ERROR: inspect failed for an unrelated reason:"
echo "$ERR"
exit 1
fi

build-test-push:
name: Build, test, push (${{ matrix.platform }})
needs: check-version
runs-on: ${{ matrix.runs-on }}
strategy:
fail-fast: false
Expand Down Expand Up @@ -67,15 +118,21 @@ jobs:
run: |
TARGET="docker.io/${IMAGE}:${{ github.sha }}-${{ env.PLATFORM_PAIR }}"
docker tag d-lmdb-server:compose "$TARGET"
docker push "$TARGET"
DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' "$TARGET" | grep -o 'sha256:[a-f0-9]\{64\}')
PUSH_OUTPUT=$(docker push "$TARGET" | tee /dev/stderr)
mapfile -t DIGESTS < <(printf '%s\n' "$PUSH_OUTPUT" | grep -oE 'sha256:[a-f0-9]{64}')
if [ "${#DIGESTS[@]}" -ne 1 ]; then
echo "ERROR: expected exactly 1 digest from docker push output, got ${#DIGESTS[@]}"
exit 1
fi
DIGEST="${DIGESTS[0]}"
echo "digest=$DIGEST" >> "$GITHUB_OUTPUT"

- name: Export digest
shell: bash
run: |
mkdir -p /tmp/digests
DIGEST="${{ steps.push.outputs.digest }}"
[ -n "$DIGEST" ] || { echo "ERROR: empty digest from push step"; exit 1; }
touch "/tmp/digests/${DIGEST#sha256:}"

- name: Upload digest
Expand All @@ -89,18 +146,11 @@ jobs:
merge:
name: Merge multi-platform manifest
runs-on: ubuntu-latest
needs: build-test-push
needs: [check-version, build-test-push]
env:
STRIPPED_VERSION: ${{ needs.check-version.outputs.stripped_version }}

steps:
- name: Resolve version
shell: bash
env:
VERSION_INPUT: ${{ inputs.version }}
RELEASE_TAG: ${{ github.event.release.tag_name }}
run: |
VERSION="${VERSION_INPUT:-$RELEASE_TAG}"
printf 'STRIPPED_VERSION=%s\n' "${VERSION#v}" >> "$GITHUB_ENV"

- name: Download digests
uses: actions/download-artifact@v4
with:
Expand All @@ -117,28 +167,20 @@ jobs:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}

- name: Reject if version tag already exists
shell: bash
env:
IMAGE: ${{ env.IMAGE }}
run: |
if docker buildx imagetools inspect "docker.io/${IMAGE}:${STRIPPED_VERSION}" >/dev/null 2>&1; then
echo "ERROR: ${STRIPPED_VERSION} already exists — will not overwrite"
exit 1
fi
echo "OK: ${STRIPPED_VERSION} is available"

- name: Create and push manifest list
shell: bash
working-directory: /tmp/digests
env:
IMAGE: ${{ env.IMAGE }}
run: |
# shellcheck disable=SC2046 # intentional word-splitting
REFS=()
for f in *; do
REFS+=("docker.io/${IMAGE}@sha256:${f}")
done
docker buildx imagetools create \
-t "docker.io/${IMAGE}:${STRIPPED_VERSION}" \
-t "docker.io/${IMAGE}:latest" \
$(printf 'docker.io/%s@sha256:%s ' "${IMAGE}" *)
"${REFS[@]}"

- name: Verify manifest
shell: bash
Expand Down
Loading