Files
donutbrowser/.github/workflows/docker-sync.yml
T
2026-10-25 14:49:46 +04:00

140 lines
4.5 KiB
YAML

name: Build and Push donut-sync Docker Image
on:
push:
branches: [main]
paths:
- "donut-sync/**"
workflow_call:
inputs:
tag:
description: "Docker tag (e.g., v1.0.0)"
required: true
type: string
secrets:
DOCKERHUB_USERNAME:
required: true
DOCKERHUB_TOKEN:
required: true
workflow_dispatch:
inputs:
tag:
description: "Docker tag (e.g., v1.0.0, latest)"
required: true
default: "latest"
permissions:
contents: read
env:
REGISTRY: docker.io
IMAGE_NAME: donutbrowser/donut-sync
jobs:
# donut-sync's own end-to-end suite covers which host it signs into presigned
# URLs. That is the whole of the self-hosted sync failure in issue 534: sign
# against an address only the server can reach and every client transfer dies
# at connect while /health and /readyz stay green. Run it here, before the
# image ships, because an image with broken presigning is the thing that
# reaches users.
#
# Ubuntu only: it needs Docker for the S3 test server.
test:
runs-on: ubuntu-latest
timeout-minutes: 20
defaults:
run:
working-directory: ./donut-sync
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 #v7.0.1
with:
persist-credentials: false
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 #master
with:
toolchain: stable
components: rustfmt, clippy
- name: Rust cache
uses: swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 #v2.9.3
with:
workspaces: "donut-sync -> target"
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Check formatting
run: cargo fmt --check
- name: Clippy
run: cargo clippy --all-targets --locked -- -D warnings -D clippy::all
# Publishes the S3 test server on 8987, the port the tests use.
- name: Start test storage
run: docker compose -f docker-compose.yml up -d --wait
- name: Run donut-sync tests
run: cargo test --locked
- name: Stop test storage
if: always()
run: docker compose -f docker-compose.yml down -v
build-and-push:
needs: test
# Forks have no Docker Hub credentials; skip instead of failing there.
if: github.repository == 'donutbrowser/donutbrowser'
runs-on: ubuntu-latest
# Both images are cross-compiled on the runner's own architecture, so
# nothing is emulated. The bound keeps a stuck build from burning hours.
timeout-minutes: 60
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 #v7.0.1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 #v4.4.1
- name: Log in to Docker Hub
uses: docker/login-action@81c6f93d4bc991e510b342a00b419b3bb4efc5c6 #v4.7.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Determine tags
id: tags
env:
INPUT_TAG: ${{ inputs.tag }}
EVENT_NAME: ${{ github.event_name }}
COMMIT_SHA: ${{ github.sha }}
run: |
TAGS=""
if [ -n "$INPUT_TAG" ]; then
# Called from release workflow or manual dispatch
if [[ ! "$INPUT_TAG" =~ ^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$ ]]; then
echo "Invalid Docker tag" >&2
exit 1
fi
TAGS="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${INPUT_TAG}"
TAGS="${TAGS},${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest"
elif [ "$EVENT_NAME" = "push" ]; then
# Push to main (nightly): tag with nightly and commit SHA
SHORT_SHA=${COMMIT_SHA:0:7}
TAGS="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:nightly"
TAGS="${TAGS},${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:nightly-${SHORT_SHA}"
fi
printf 'tags=%s\n' "$TAGS" >> "$GITHUB_OUTPUT"
- name: Build and push Docker image
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc #v7.4.0
with:
context: ./donut-sync
file: ./donut-sync/Dockerfile
push: true
tags: ${{ steps.tags.outputs.tags }}
cache-from: type=gha
cache-to: type=gha,mode=max
platforms: linux/amd64,linux/arm64