From a19477c42412835cabf1d63d6f6d846c7675a9c3 Mon Sep 17 00:00:00 2001 From: DevITWay Date: Mon, 26 Jan 2026 00:34:00 +0000 Subject: [PATCH] ci: add GitHub Actions workflow for Docker releases - Run tests on PR and push - Build multi-arch images (amd64, arm64) - Push to ghcr.io on main branch and tags - Auto-create GitHub Release on version tags - Use BuildKit cache for faster builds --- .github/workflows/release.yml | 102 ++++++++++++++++++++++++++++++++++ Dockerfile | 21 +++++-- 2 files changed, 117 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..ba9b0a2 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,102 @@ +name: Release + +on: + push: + branches: [main] + tags: ['v*'] + pull_request: + branches: [main] + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + test: + name: Test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install Rust + uses: dtolnay/rust-action@stable + + - name: Cache cargo + uses: Swatinem/rust-cache@v2 + + - name: Run tests + run: cargo test --package nora-registry + + build: + name: Build & Push + runs-on: ubuntu-latest + needs: test + if: github.event_name != 'pull_request' + permissions: + contents: read + packages: write + + steps: + - uses: actions/checkout@v4 + + - 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 Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=ref,event=branch + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=sha,prefix= + + - name: Build and push + uses: docker/build-push-action@v5 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + + release: + name: GitHub Release + runs-on: ubuntu-latest + needs: build + if: startsWith(github.ref, 'refs/tags/v') + permissions: + contents: write + + steps: + - uses: actions/checkout@v4 + + - name: Create Release + uses: softprops/action-gh-release@v1 + with: + generate_release_notes: true + body: | + ## Docker + + ```bash + docker pull ghcr.io/${{ github.repository }}:${{ github.ref_name }} + ``` + + ## Changelog + + See [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/main/CHANGELOG.md) diff --git a/Dockerfile b/Dockerfile index 2a4b9c8..4f6470f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1.4 + # Build stage FROM rust:1.83-alpine AS builder @@ -17,8 +19,11 @@ RUN mkdir -p nora-registry/src nora-storage/src nora-cli/src && \ echo "fn main() {}" > nora-storage/src/main.rs && \ echo "fn main() {}" > nora-cli/src/main.rs -# Build dependencies only -RUN cargo build --release --package nora-registry && \ +# Build dependencies only (with cache) +RUN --mount=type=cache,target=/usr/local/cargo/registry \ + --mount=type=cache,target=/usr/local/cargo/git \ + --mount=type=cache,target=/app/target \ + cargo build --release --package nora-registry && \ rm -rf nora-registry/src nora-storage/src nora-cli/src # Copy real sources @@ -26,9 +31,13 @@ COPY nora-registry/src nora-registry/src COPY nora-storage/src nora-storage/src COPY nora-cli/src nora-cli/src -# Build release binary -RUN touch nora-registry/src/main.rs && \ - cargo build --release --package nora-registry +# Build release binary (with cache) +RUN --mount=type=cache,target=/usr/local/cargo/registry \ + --mount=type=cache,target=/usr/local/cargo/git \ + --mount=type=cache,target=/app/target \ + touch nora-registry/src/main.rs && \ + cargo build --release --package nora-registry && \ + cp /app/target/release/nora /usr/local/bin/nora # Runtime stage FROM alpine:3.20 @@ -38,7 +47,7 @@ RUN apk add --no-cache ca-certificates WORKDIR /app # Copy binary -COPY --from=builder /app/target/release/nora /usr/local/bin/nora +COPY --from=builder /usr/local/bin/nora /usr/local/bin/nora # Create data directory RUN mkdir -p /data