Compare commits

...

1 Commits

Author SHA1 Message Date
sudo-kraken
0504603809 feat: native ARM builds + updated workflow architecture
- Replace QEMU emulation with native ARM runners for performance reasons,
- Standardise all workflows with cache-warming, deterministic timestamps,
- Added more container metadata while maintaining clean registries
2025-09-14 14:35:29 +01:00
3 changed files with 311 additions and 148 deletions

View File

@@ -7,6 +7,14 @@ on:
push: push:
branches: branches:
- develop - develop
workflow_dispatch:
permissions:
contents: read
packages: write
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs: jobs:
test: test:
@@ -44,111 +52,109 @@ jobs:
run: pnpm build run: pnpm build
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]') if: github.ref == 'refs/heads/develop' && !contains(github.event.head_commit.message, '[skip ci]')
strategy: strategy:
matrix: matrix:
include: include:
- runner: ubuntu-24.04 - runner: ubuntu-24.04
platform: linux/amd64 platform: linux/amd64
arch: amd64
- runner: ubuntu-24.04-arm - runner: ubuntu-24.04-arm
platform: linux/arm64 platform: linux/arm64
arch: arm64
runs-on: ${{ matrix.runner }} runs-on: ${{ matrix.runner }}
outputs:
digest-amd64: ${{ steps.set_outputs.outputs.digest-amd64 }}
digest-arm64: ${{ steps.set_outputs.outputs.digest-arm64 }}
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 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 - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@v3 - name: Warm cache (no push) — ${{ matrix.platform }}
with: uses: docker/build-push-action@v6
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
with: with:
context: . context: .
file: ./Dockerfile file: ./Dockerfile
platforms: ${{ matrix.platform }} platforms: ${{ matrix.platform }}
push: true push: false
build-args: | build-args: |
COMMIT_TAG=${{ github.sha }} COMMIT_TAG=${{ github.sha }}
BUILD_VERSION=develop BUILD_VERSION=develop
BUILD_DATE=${{ github.event.repository.updated_at }} BUILD_DATE=${{ steps.ts.outputs.now }}
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
cache-from: type=gha,scope=${{ matrix.platform }} cache-from: type=gha,scope=${{ matrix.platform }}
cache-to: type=gha,mode=max,scope=${{ matrix.platform }} cache-to: type=gha,mode=max,scope=${{ matrix.platform }}
provenance: false 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: publish:
name: Create and Push Multi-arch Manifest name: Publish multi-arch image
needs: build needs: build
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: 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 - name: Log in to Docker Hub
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
username: ${{ secrets.DOCKER_USERNAME }} username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }} password: ${{ secrets.DOCKER_TOKEN }}
- name: Log in to GitHub Container Registry - name: Log in to GitHub Container Registry
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.repository_owner }} username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Set lower case owner name
run: | - name: Lower-case owner
echo "OWNER_LC=${OWNER,,}" >>${GITHUB_ENV} run: echo "OWNER_LC=${OWNER,,}" >> "$GITHUB_ENV"
env: env:
OWNER: ${{ github.repository_owner }} 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 - name: Build & Push (multi-arch, single tag)
docker manifest create ghcr.io/${{ env.OWNER_LC }}/jellyseerr:develop \ uses: docker/build-push-action@v6
--amend ghcr.io/${{ env.OWNER_LC }}/jellyseerr@${{ needs.build.outputs.digest-amd64 }} \ with:
--amend ghcr.io/${{ env.OWNER_LC }}/jellyseerr@${{ needs.build.outputs.digest-arm64 }} context: .
docker manifest push ghcr.io/${{ env.OWNER_LC }}/jellyseerr:develop 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: discord:
name: Send Discord Notification 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]') if: always() && github.event_name != 'pull_request' && !contains(github.event.head_commit.message, '[skip ci]')
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:

View File

@@ -4,28 +4,113 @@ on:
push: push:
tags: tags:
- 'preview-*' - 'preview-*'
workflow_dispatch:
permissions:
contents: read
packages: write
concurrency:
group: preview-${{ github.ref }}
cancel-in-progress: true
jobs: jobs:
build_and_push: build:
name: Build & Publish Docker Preview Images name: Build (per-arch, native runners)
runs-on: ubuntu-22.04 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: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Get the version
id: get_version - name: Deterministic timestamp
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT id: ts
- name: Set up QEMU run: echo "now=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$GITHUB_OUTPUT"
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 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 - name: Log in to Docker Hub
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
username: ${{ secrets.DOCKER_USERNAME }} username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }} 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: with:
context: . context: .
file: ./Dockerfile file: ./Dockerfile
@@ -33,7 +118,17 @@ jobs:
push: true push: true
build-args: | build-args: |
COMMIT_TAG=${{ github.sha }} COMMIT_TAG=${{ github.sha }}
BUILD_VERSION=${{ steps.get_version.outputs.VERSION }} BUILD_VERSION=${{ steps.ver.outputs.version }}
BUILD_DATE=${{ github.event.repository.updated_at }} 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: | 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

View File

@@ -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: jobs:
semantic-release: semantic-release:
@@ -8,38 +17,30 @@ jobs:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
env: env:
HUSKY: 0 HUSKY: 0
outputs:
new_release_published: ${{ steps.release.outputs.new_release_published }}
new_release_version: ${{ steps.release.outputs.new_release_version }}
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Set up Node.js - name: Set up Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: 22 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 - name: Pnpm Setup
uses: pnpm/action-setup@v4 uses: pnpm/action-setup@v4
with: with:
version: 9 version: 9
- name: Get pnpm store directory - name: Get pnpm store directory
shell: sh shell: sh
run: | run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Setup pnpm cache - name: Setup pnpm cache
uses: actions/cache@v4 uses: actions/cache@v4
with: with:
@@ -47,74 +48,135 @@ jobs:
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: | restore-keys: |
${{ runner.os }}-pnpm-store- ${{ runner.os }}-pnpm-store-
- name: Install dependencies - name: Install dependencies
run: pnpm install run: pnpm install
- name: Release - name: Release
id: release
uses: cycjimmy/semantic-release-action@v4
env: env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
run: npx semantic-release
# build-snap: build:
# name: Build Snap Package (${{ matrix.architecture }}) name: Build (per-arch, native runners)
# needs: semantic-release needs: semantic-release
# runs-on: ubuntu-22.04 if: needs.semantic-release.outputs.new_release_published == 'true'
# strategy: strategy:
# fail-fast: false matrix:
# matrix: include:
# architecture: - runner: ubuntu-24.04
# - amd64 platform: linux/amd64
# - arm64 arch: amd64
# steps: - runner: ubuntu-24.04-arm
# - name: Checkout Code platform: linux/arm64
# uses: actions/checkout@v4 arch: arm64
# with: runs-on: ${{ matrix.runner }}
# fetch-depth: 0 steps:
# - name: Switch to main branch - name: Checkout
# run: git checkout main uses: actions/checkout@v4
# - name: Pull latest changes
# run: git pull - name: Deterministic timestamp
# - name: Prepare id: ts
# id: prepare run: echo "now=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$GITHUB_OUTPUT"
# run: |
# git fetch --prune --tags - name: Set up Docker Buildx
# if [[ $GITHUB_REF == refs/tags/* || $GITHUB_REF == refs/heads/master ]]; then uses: docker/setup-buildx-action@v3
# echo "RELEASE=stable" >> $GITHUB_OUTPUT
# else - name: Warm cache (no push) — ${{ matrix.platform }}
# echo "RELEASE=edge" >> $GITHUB_OUTPUT uses: docker/build-push-action@v6
# fi with:
# - name: Set Up QEMU context: .
# uses: docker/setup-qemu-action@v3 file: ./Dockerfile
# with: platforms: ${{ matrix.platform }}
# image: tonistiigi/binfmt@sha256:df15403e06a03c2f461c1f7938b171fda34a5849eb63a70e2a2109ed5a778bde push: false
# - name: Build Snap Package build-args: |
# uses: diddlesnaps/snapcraft-multiarch-action@v1 COMMIT_TAG=${{ github.sha }}
# id: build BUILD_VERSION=${{ needs.semantic-release.outputs.new_release_version }}
# with: BUILD_DATE=${{ steps.ts.outputs.now }}
# architecture: ${{ matrix.architecture }} cache-from: type=gha,scope=${{ matrix.platform }}
# - name: Upload Snap Package cache-to: type=gha,mode=max,scope=${{ matrix.platform }}
# uses: actions/upload-artifact@v4 provenance: false
# with:
# name: jellyseerr-snap-package-${{ matrix.architecture }} publish:
# path: ${{ steps.build.outputs.snap }} name: Publish multi-arch image
# - name: Review Snap Package needs: [semantic-release, build]
# uses: diddlesnaps/snapcraft-review-tools-action@v1 if: needs.semantic-release.outputs.new_release_published == 'true'
# with: runs-on: ubuntu-24.04
# snap: ${{ steps.build.outputs.snap }} steps:
# - name: Publish Snap Package - name: Checkout
# uses: snapcore/action-publish@v1 uses: actions/checkout@v4
# env:
# SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAP_LOGIN }} - name: Deterministic timestamp
# with: id: ts
# snap: ${{ steps.build.outputs.snap }} run: echo "now=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$GITHUB_OUTPUT"
# release: ${{ steps.prepare.outputs.RELEASE }}
- 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: discord:
name: Send Discord Notification name: Send Discord Notification
needs: semantic-release needs: publish
if: always() if: always()
runs-on: ubuntu-22.04 runs-on: ubuntu-24.04
steps: steps:
- name: Get Build Job Status - name: Get Build Job Status
uses: technote-space/workflow-conclusion-action@v3 uses: technote-space/workflow-conclusion-action@v3