diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8189522f0..54569fa93 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,6 +7,14 @@ on: push: branches: - develop + workflow_dispatch: +permissions: + contents: read + packages: write + +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true jobs: test: @@ -44,111 +52,109 @@ jobs: run: pnpm build build: - name: Build & Publish Docker Images + name: Build (per-arch, native runners) if: github.ref == 'refs/heads/develop' && !contains(github.event.head_commit.message, '[skip ci]') strategy: matrix: include: - runner: ubuntu-24.04 platform: linux/amd64 + arch: amd64 - runner: ubuntu-24.04-arm platform: linux/arm64 + arch: arm64 runs-on: ${{ matrix.runner }} - outputs: - digest-amd64: ${{ steps.set_outputs.outputs.digest-amd64 }} - digest-arm64: ${{ steps.set_outputs.outputs.digest-arm64 }} steps: - name: Checkout uses: actions/checkout@v4 + + - name: Deterministic timestamp + id: ts + run: echo "now=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$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_TOKEN }} - - name: Log in to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.repository_owner }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Set lower case owner name - run: | - echo "OWNER_LC=${OWNER,,}" >>${GITHUB_ENV} - env: - OWNER: ${{ github.repository_owner }} - - name: Docker metadata - id: meta - uses: docker/metadata-action@v4 - with: - images: | - fallenbagel/jellyseerr - ghcr.io/${{ env.OWNER_LC }}/jellyseerr - tags: | - type=ref,event=branch - type=sha,prefix=,suffix=,format=short - - name: Build and push by digest - id: build - uses: docker/build-push-action@v5 + + - name: Warm cache (no push) — ${{ matrix.platform }} + uses: docker/build-push-action@v6 with: context: . file: ./Dockerfile platforms: ${{ matrix.platform }} - push: true + push: false build-args: | COMMIT_TAG=${{ github.sha }} BUILD_VERSION=develop - BUILD_DATE=${{ github.event.repository.updated_at }} - outputs: | - type=image,push-by-digest=true,name=fallenbagel/jellyseerr,push=true - type=image,push-by-digest=true,name=ghcr.io/${{ env.OWNER_LC }}/jellyseerr,push=true + BUILD_DATE=${{ steps.ts.outputs.now }} cache-from: type=gha,scope=${{ matrix.platform }} cache-to: type=gha,mode=max,scope=${{ matrix.platform }} provenance: false - - name: Set outputs - id: set_outputs - run: | - platform="${{ matrix.platform == 'linux/amd64' && 'amd64' || 'arm64' }}" - echo "digest-${platform}=${{ steps.build.outputs.digest }}" >> $GITHUB_OUTPUT - merge_and_push: - name: Create and Push Multi-arch Manifest + publish: + name: Publish multi-arch image needs: build runs-on: ubuntu-24.04 steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Deterministic timestamp + id: ts + run: echo "now=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$GITHUB_OUTPUT" + + - name: Set up QEMU (enable ARM emulation) + uses: docker/setup-qemu-action@v3 + + - 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_TOKEN }} + - name: Log in to GitHub Container Registry uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Set lower case owner name - run: | - echo "OWNER_LC=${OWNER,,}" >>${GITHUB_ENV} + + - name: Lower-case owner + run: echo "OWNER_LC=${OWNER,,}" >> "$GITHUB_ENV" env: OWNER: ${{ github.repository_owner }} - - name: Create and push manifest - run: | - docker manifest create fallenbagel/jellyseerr:develop \ - --amend fallenbagel/jellyseerr@${{ needs.build.outputs.digest-amd64 }} \ - --amend fallenbagel/jellyseerr@${{ needs.build.outputs.digest-arm64 }} - docker manifest push fallenbagel/jellyseerr:develop - # GHCR manifest - docker manifest create ghcr.io/${{ env.OWNER_LC }}/jellyseerr:develop \ - --amend ghcr.io/${{ env.OWNER_LC }}/jellyseerr@${{ needs.build.outputs.digest-amd64 }} \ - --amend ghcr.io/${{ env.OWNER_LC }}/jellyseerr@${{ needs.build.outputs.digest-arm64 }} - docker manifest push ghcr.io/${{ env.OWNER_LC }}/jellyseerr:develop + - name: Build & Push (multi-arch, single tag) + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + platforms: linux/amd64,linux/arm64 + push: true + build-args: | + COMMIT_TAG=${{ github.sha }} + BUILD_VERSION=develop + BUILD_DATE=${{ steps.ts.outputs.now }} + labels: | + org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }} + org.opencontainers.image.revision=${{ github.sha }} + org.opencontainers.image.version=develop + tags: | + fallenbagel/jellyseerr:develop + fallenbagel/jellyseerr:${{ github.sha }} + ghcr.io/${{ env.OWNER_LC }}/jellyseerr:develop + ghcr.io/${{ env.OWNER_LC }}/jellyseerr:${{ github.sha }} + cache-from: | + type=gha,scope=linux/amd64 + type=gha,scope=linux/arm64 + cache-to: type=gha,mode=max + provenance: false discord: name: Send Discord Notification - needs: merge_and_push + needs: publish if: always() && github.event_name != 'pull_request' && !contains(github.event.head_commit.message, '[skip ci]') runs-on: ubuntu-24.04 steps: diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 0084f27b4..93d906565 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -4,28 +4,113 @@ on: push: tags: - 'preview-*' + workflow_dispatch: + +permissions: + contents: read + packages: write + +concurrency: + group: preview-${{ github.ref }} + cancel-in-progress: true jobs: - build_and_push: - name: Build & Publish Docker Preview Images - runs-on: ubuntu-22.04 + build: + name: Build (per-arch, native runners) + strategy: + matrix: + include: + - runner: ubuntu-24.04 + platform: linux/amd64 + arch: amd64 + - runner: ubuntu-24.04-arm + platform: linux/arm64 + arch: arm64 + runs-on: ${{ matrix.runner }} steps: - name: Checkout uses: actions/checkout@v4 - - name: Get the version - id: get_version - run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + + - name: Deterministic timestamp + id: ts + run: echo "now=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$GITHUB_OUTPUT" + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 + + - name: Derive preview version from tag + id: ver + shell: bash + run: | + TAG="${GITHUB_REF_NAME}" + VER="${TAG#preview-}" + VER="${VER#v}" + echo "version=${VER}" >> "$GITHUB_OUTPUT" + echo "Building preview version: ${VER}" + + - name: Warm cache (no push) — ${{ matrix.platform }} + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + platforms: ${{ matrix.platform }} + push: false + build-args: | + COMMIT_TAG=${{ github.sha }} + BUILD_VERSION=${{ steps.ver.outputs.version }} + BUILD_DATE=${{ steps.ts.outputs.now }} + cache-from: type=gha,scope=${{ matrix.platform }} + cache-to: type=gha,mode=max,scope=${{ matrix.platform }} + provenance: false + + publish: + name: Publish multi-arch image + needs: build + runs-on: ubuntu-24.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Deterministic timestamp + id: ts + run: echo "now=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$GITHUB_OUTPUT" + + - name: Set up QEMU (enable ARM emulation) + uses: docker/setup-qemu-action@v3 + + - 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_TOKEN }} - - name: Build and push - uses: docker/build-push-action@v5 + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Lower-case owner + run: echo "OWNER_LC=${OWNER,,}" >> "$GITHUB_ENV" + env: + OWNER: ${{ github.repository_owner }} + + - name: Derive preview version from tag + id: ver + shell: bash + run: | + TAG="${GITHUB_REF_NAME}" + VER="${TAG#preview-}" + VER="${VER#v}" + echo "version=${VER}" >> "$GITHUB_OUTPUT" + echo "Publishing preview version: ${VER}" + + - name: Build & Push (multi-arch, single tag) + uses: docker/build-push-action@v6 with: context: . file: ./Dockerfile @@ -33,7 +118,17 @@ jobs: push: true build-args: | COMMIT_TAG=${{ github.sha }} - BUILD_VERSION=${{ steps.get_version.outputs.VERSION }} - BUILD_DATE=${{ github.event.repository.updated_at }} + BUILD_VERSION=${{ steps.ver.outputs.version }} + BUILD_DATE=${{ steps.ts.outputs.now }} + labels: | + org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }} + org.opencontainers.image.revision=${{ github.sha }} + org.opencontainers.image.version=preview-${{ steps.ver.outputs.version }} tags: | - fallenbagel/jellyseerr:${{ steps.get_version.outputs.VERSION }} + fallenbagel/jellyseerr:preview-${{ steps.ver.outputs.version }} + ghcr.io/${{ env.OWNER_LC }}/jellyseerr:preview-${{ steps.ver.outputs.version }} + cache-from: | + type=gha,scope=linux/amd64 + type=gha,scope=linux/arm64 + cache-to: type=gha,mode=max + provenance: false diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d0c36976d..452dede9d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,6 +1,15 @@ -name: Jellyseer Release +name: Jellyseerr Release -on: workflow_dispatch +on: + workflow_dispatch: + +permissions: + contents: read + packages: write + +concurrency: + group: release-${{ github.ref }} + cancel-in-progress: true jobs: semantic-release: @@ -8,38 +17,30 @@ jobs: runs-on: ubuntu-22.04 env: HUSKY: 0 + outputs: + new_release_published: ${{ steps.release.outputs.new_release_published }} + new_release_version: ${{ steps.release.outputs.new_release_version }} steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 + - name: Set up Node.js uses: actions/setup-node@v4 with: node-version: 22 - - 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 Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_TOKEN }} - - name: Log in to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.repository_owner }} - password: ${{ secrets.GH_TOKEN }} + - name: Pnpm Setup uses: pnpm/action-setup@v4 with: version: 9 + - name: Get pnpm store directory shell: sh run: | echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV + - name: Setup pnpm cache uses: actions/cache@v4 with: @@ -47,74 +48,135 @@ jobs: key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} restore-keys: | ${{ runner.os }}-pnpm-store- + - name: Install dependencies run: pnpm install + - name: Release + id: release + uses: cycjimmy/semantic-release-action@v4 env: GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - run: npx semantic-release - # build-snap: - # name: Build Snap Package (${{ matrix.architecture }}) - # needs: semantic-release - # runs-on: ubuntu-22.04 - # strategy: - # fail-fast: false - # matrix: - # architecture: - # - amd64 - # - arm64 - # steps: - # - name: Checkout Code - # uses: actions/checkout@v4 - # with: - # fetch-depth: 0 - # - name: Switch to main branch - # run: git checkout main - # - name: Pull latest changes - # run: git pull - # - name: Prepare - # id: prepare - # run: | - # git fetch --prune --tags - # if [[ $GITHUB_REF == refs/tags/* || $GITHUB_REF == refs/heads/master ]]; then - # echo "RELEASE=stable" >> $GITHUB_OUTPUT - # else - # echo "RELEASE=edge" >> $GITHUB_OUTPUT - # fi - # - name: Set Up QEMU - # uses: docker/setup-qemu-action@v3 - # with: - # image: tonistiigi/binfmt@sha256:df15403e06a03c2f461c1f7938b171fda34a5849eb63a70e2a2109ed5a778bde - # - name: Build Snap Package - # uses: diddlesnaps/snapcraft-multiarch-action@v1 - # id: build - # with: - # architecture: ${{ matrix.architecture }} - # - name: Upload Snap Package - # uses: actions/upload-artifact@v4 - # with: - # name: jellyseerr-snap-package-${{ matrix.architecture }} - # path: ${{ steps.build.outputs.snap }} - # - name: Review Snap Package - # uses: diddlesnaps/snapcraft-review-tools-action@v1 - # with: - # snap: ${{ steps.build.outputs.snap }} - # - name: Publish Snap Package - # uses: snapcore/action-publish@v1 - # env: - # SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAP_LOGIN }} - # with: - # snap: ${{ steps.build.outputs.snap }} - # release: ${{ steps.prepare.outputs.RELEASE }} + build: + name: Build (per-arch, native runners) + needs: semantic-release + if: needs.semantic-release.outputs.new_release_published == 'true' + strategy: + matrix: + include: + - runner: ubuntu-24.04 + platform: linux/amd64 + arch: amd64 + - runner: ubuntu-24.04-arm + platform: linux/arm64 + arch: arm64 + runs-on: ${{ matrix.runner }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Deterministic timestamp + id: ts + run: echo "now=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$GITHUB_OUTPUT" + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Warm cache (no push) — ${{ matrix.platform }} + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + platforms: ${{ matrix.platform }} + push: false + build-args: | + COMMIT_TAG=${{ github.sha }} + BUILD_VERSION=${{ needs.semantic-release.outputs.new_release_version }} + BUILD_DATE=${{ steps.ts.outputs.now }} + cache-from: type=gha,scope=${{ matrix.platform }} + cache-to: type=gha,mode=max,scope=${{ matrix.platform }} + provenance: false + + publish: + name: Publish multi-arch image + needs: [semantic-release, build] + if: needs.semantic-release.outputs.new_release_published == 'true' + runs-on: ubuntu-24.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Deterministic timestamp + id: ts + run: echo "now=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$GITHUB_OUTPUT" + + - name: Set up QEMU (enable ARM emulation) + uses: docker/setup-qemu-action@v3 + + - 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_TOKEN }} + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Lower-case owner + run: echo "OWNER_LC=${OWNER,,}" >> "$GITHUB_ENV" + env: + OWNER: ${{ github.repository_owner }} + + - name: Build & Push (multi-arch, single tag) + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + platforms: linux/amd64,linux/arm64 + push: true + build-args: | + COMMIT_TAG=${{ github.sha }} + BUILD_VERSION=${{ needs.semantic-release.outputs.new_release_version }} + BUILD_DATE=${{ steps.ts.outputs.now }} + labels: | + org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }} + org.opencontainers.image.revision=${{ github.sha }} + org.opencontainers.image.version=${{ needs.semantic-release.outputs.new_release_version }} + tags: | + fallenbagel/jellyseerr:${{ needs.semantic-release.outputs.new_release_version }} + ghcr.io/${{ env.OWNER_LC }}/jellyseerr:${{ needs.semantic-release.outputs.new_release_version }} + cache-from: | + type=gha,scope=linux/amd64 + type=gha,scope=linux/arm64 + cache-to: type=gha,mode=max + provenance: false + + - name: Also tag :latest (non-pre-release only) + shell: bash + run: | + VER="${{ needs.semantic-release.outputs.new_release_version }}" + if [[ "$VER" != *"-"* ]]; then + docker buildx imagetools create \ + -t fallenbagel/jellyseerr:latest \ + fallenbagel/jellyseerr:${VER} + docker buildx imagetools create \ + -t ghcr.io/${{ env.OWNER_LC }}/jellyseerr:latest \ + ghcr.io/${{ env.OWNER_LC }}/jellyseerr:${VER} + fi discord: name: Send Discord Notification - needs: semantic-release + needs: publish if: always() - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Get Build Job Status uses: technote-space/workflow-conclusion-action@v3