name: Build & Publish Images on: push: branches: [ main, dev ] tags: [ '*' ] workflow_dispatch: env: REGISTRY: ghcr.io IMAGE_BACKEND: papercrate-dms/papercrate-backend IMAGE_FRONTEND: papercrate-dms/papercrate-frontend jobs: publish: runs-on: ubuntu-latest permissions: contents: read packages: write steps: - name: Check out repository uses: actions/checkout@v4 - name: Cache Cargo uses: actions/cache@v3 with: path: | ~/.cargo/registry ~/.cargo/git backend/target key: ${{ runner.os }}-cargo-${{ hashFiles('backend/Cargo.lock') }} restore-keys: | ${{ runner.os }}-cargo- - name: Install system dependencies run: | sudo apt-get update sudo apt-get install -y pkg-config libssl-dev libpq-dev zig - name: Install Rust targets and tools run: | rustup target add aarch64-unknown-linux-gnu cargo install cargo-zigbuild cross - name: Build backend binaries (amd64) working-directory: backend run: | cargo build --release --bin backend --bin worker --bin webdav --bin admin cargo install diesel_cli --no-default-features --features postgres --root target/diesel-amd64 - name: Build backend binaries (arm64) working-directory: backend run: | cargo zigbuild --target aarch64-unknown-linux-gnu --release --bin backend --bin worker --bin webdav --bin admin cross install diesel_cli --no-default-features --features postgres --target aarch64-unknown-linux-gnu --root target/diesel-arm64 - name: Prepare backend artifacts run: | set -eux mkdir -p build-artifacts/backend/amd64 build-artifacts/backend/arm64 cp backend/target/release/backend build-artifacts/backend/amd64/papercrate-backend cp backend/target/release/worker build-artifacts/backend/amd64/papercrate-worker cp backend/target/release/webdav build-artifacts/backend/amd64/papercrate-webdav cp backend/target/release/admin build-artifacts/backend/amd64/papercrate-admin cp backend/target/diesel-amd64/bin/diesel build-artifacts/backend/amd64/diesel cp backend/target/aarch64-unknown-linux-gnu/release/backend build-artifacts/backend/arm64/papercrate-backend cp backend/target/aarch64-unknown-linux-gnu/release/worker build-artifacts/backend/arm64/papercrate-worker cp backend/target/aarch64-unknown-linux-gnu/release/webdav build-artifacts/backend/arm64/papercrate-webdav cp backend/target/aarch64-unknown-linux-gnu/release/admin build-artifacts/backend/arm64/papercrate-admin cp backend/target/diesel-arm64/bin/diesel build-artifacts/backend/arm64/diesel chmod +x build-artifacts/backend/*/* - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: 20 cache: 'npm' cache-dependency-path: frontend/package-lock.json - name: Install frontend dependencies working-directory: frontend run: npm ci --no-audit --no-fund - name: Build frontend working-directory: frontend run: npm run build - name: Compute image tags id: tags env: GITHUB_SHA: ${{ github.sha }} GITHUB_REF: ${{ github.ref }} REGISTRY: ${{ env.REGISTRY }} run: | SHORT_SHA=${GITHUB_SHA::7} TAGS=("$SHORT_SHA") BRANCH=${GITHUB_REF##*/} if [ "$BRANCH" = "dev" ]; then TAGS+=("${SHORT_SHA}-dev") fi if [[ "$GITHUB_REF" == refs/tags/* ]]; then TAGS+=("${GITHUB_REF#refs/tags/}") fi UNIQUE=() for tag in "${TAGS[@]}"; do [[ -z "$tag" ]] && continue skip=false for seen in "${UNIQUE[@]}"; do if [ "$tag" = "$seen" ]; then skip=true break fi done if [ "$skip" = false ]; then UNIQUE+=("$tag") fi done { echo "BASE_TAGS<> "$GITHUB_ENV" - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to GHCR uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: papercrate-dms password: ${{ secrets.GHCR_PAT }} - name: Build & push backend image uses: docker/build-push-action@v5 with: context: . file: backend/Dockerfile push: true platforms: linux/amd64,linux/arm64 tags: ${{ env.BACKEND_TAGS }} cache-from: type=gha,scope=backend cache-to: type=gha,scope=backend,mode=max - name: Build & push frontend image uses: docker/build-push-action@v5 with: context: . file: frontend/Dockerfile push: true platforms: linux/amd64,linux/arm64 tags: ${{ env.FRONTEND_TAGS }} cache-from: type=gha,scope=frontend cache-to: type=gha,scope=frontend,mode=max