mirror of
https://github.com/jellyfin/jellyfin-vue.git
synced 2025-04-27 07:10:53 +00:00
341 lines
12 KiB
YAML
341 lines
12 KiB
YAML
name: Packaging 📦
|
|
|
|
on:
|
|
workflow_call:
|
|
inputs:
|
|
commit:
|
|
required: false
|
|
type: string
|
|
tag_name:
|
|
required: false
|
|
type: string
|
|
is_prerelease:
|
|
required: false
|
|
type: boolean
|
|
push:
|
|
required: false
|
|
type: boolean
|
|
architectures:
|
|
description: As GitHub Actions doesn't support globals and/or arrays, you must pass this as an string, like '["amd64", "arm64"]'
|
|
required: false
|
|
type: string
|
|
default: '["amd64", "arm64"]'
|
|
|
|
env:
|
|
REGISTRY_IMAGE: jellyfin/jellyfin-vue
|
|
RELEASE_TAG: stable
|
|
PRERELEASE_TAG: stable-rc
|
|
COMMIT_TAG: unstable
|
|
DOCKER_BUILD_RECORD_UPLOAD: false
|
|
|
|
defaults:
|
|
run:
|
|
shell: bash
|
|
|
|
jobs:
|
|
tauri:
|
|
name: Tauri for ${{ matrix.platform }} 🖥️
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
platform:
|
|
- MacOS
|
|
- Ubuntu
|
|
- Windows
|
|
defaults:
|
|
run:
|
|
working-directory: ${{ env.WORKING_DIR }}
|
|
|
|
env:
|
|
WORKING_DIR: packaging/tauri
|
|
ARTIFACT_NAME: jellyfin-vue_${{ matrix.platform }}
|
|
ARTIFACTS_PATH: ${{
|
|
format('target/release/{0}', matrix.platform == 'windows' && 'jellyfin-vue-tauri.exe' ||
|
|
format('bundle/*/*.{0}', matrix.platform == 'macos' && 'dmg' || 'AppImage'))
|
|
}}
|
|
|
|
runs-on: ${{ matrix.platform }}-latest
|
|
steps:
|
|
- name: Checkout ⬇️
|
|
uses: actions/checkout@v4.2.2
|
|
with:
|
|
ref: ${{ inputs.commit || github.sha }}
|
|
show-progress: false
|
|
|
|
- name: Setup node environment ⚙️
|
|
uses: actions/setup-node@v4.1.0
|
|
with:
|
|
node-version: lts/*
|
|
check-latest: true
|
|
cache: 'npm'
|
|
|
|
- name: Setup Rust Toolchain and cache 🦀
|
|
uses: actions-rust-lang/setup-rust-toolchain@v1.10.1
|
|
with:
|
|
cache-key: tauri-${{ runner.os }}
|
|
cache-workspaces: ${{ env.WORKING_DIR }}
|
|
|
|
- name: Install npm dependencies 📦
|
|
run: npm ci --no-audit
|
|
|
|
- name: Install Linux dependencies 📦🐧
|
|
if: ${{ matrix.platform == 'ubuntu' }}
|
|
run: |
|
|
sudo apt update -qq
|
|
sudo apt install -y --no-install-recommends $(cat apt_packages)
|
|
|
|
- name: Build application 🛠️
|
|
run: npm run build
|
|
|
|
- name: Upload built application artifact ⬆️🐧🍎🪟
|
|
uses: actions/upload-artifact@v4.6.0
|
|
id: artifact
|
|
with:
|
|
compression-level: 0
|
|
name: ${{ env.ARTIFACT_NAME }}
|
|
path: ${{ env.WORKING_DIR }}/${{ env.ARTIFACTS_PATH }}
|
|
|
|
- name: Create provenance attestation 🔏
|
|
uses: actions/attest-build-provenance@v2.2.0
|
|
continue-on-error: true
|
|
with:
|
|
subject-name: ${{ env.ARTIFACT_NAME }}
|
|
subject-digest: sha256:${{ steps.artifact.outputs.artifact-digest }}
|
|
|
|
docker_inputs:
|
|
name: Prepare Docker build variables 🏷️🐳
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
tags: ${{ env.tags }}
|
|
platforms: ${{ env.platforms }}
|
|
caches: ${{ env.caches }}
|
|
|
|
# EOF is needed for multiline environment variables in a GitHub Actions context
|
|
steps:
|
|
- name: Get current date ⌛
|
|
id: date
|
|
run: echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
|
|
|
|
- name: Parse commit hash ⚙️
|
|
if: ${{ inputs.commit != '' }}
|
|
id: sha
|
|
run: |
|
|
PARSEABLE_SHA='${{ inputs.commit }}'
|
|
echo "sha=${PARSEABLE_SHA::7}" >> $GITHUB_OUTPUT
|
|
|
|
## How tags are assigned:
|
|
## - 1º block: Handle 'stable' release: No commit, is_prerelease=false
|
|
## - 2º block: Handle 'stable-rc' release: No commit, is_prerelease=true
|
|
## - 3º block: Handle 'unstable' release: Has commit hash
|
|
#
|
|
## Before setting as output, we remove the blank lines
|
|
- name: Generate tags 🏷️
|
|
run: |
|
|
TG='${{ inputs.commit == '' && !inputs.is_prerelease && format('{0}:{1}', env.REGISTRY_IMAGE, 'latest') || '' }}\n'
|
|
TG+='${{ inputs.commit == '' && !inputs.is_prerelease && format('{0}:{1}', env.REGISTRY_IMAGE, env.RELEASE_TAG) || '' }}\n'
|
|
TG+='${{ inputs.commit == '' && !inputs.is_prerelease && inputs.tag_name && format('{0}:{1}.{2}', env.REGISTRY_IMAGE, env.RELEASE_TAG, inputs.tag_name) || '' }}\n'
|
|
TG+='${{ inputs.commit == '' && !inputs.is_prerelease && format('ghcr.io/{0}:{1}', env.REGISTRY_IMAGE, 'latest') || '' }}\n'
|
|
TG+='${{ inputs.commit == '' && !inputs.is_prerelease && format('ghcr.io/{0}:{1}', env.REGISTRY_IMAGE, env.RELEASE_TAG) || '' }}\n'
|
|
TG+='${{ inputs.commit == '' && !inputs.is_prerelease && inputs.tag_name && format('ghcr.io/{0}:{1}.{2}', env.REGISTRY_IMAGE, env.RELEASE_TAG, inputs.tag_name) || '' }}\n'
|
|
|
|
TG+='${{ inputs.commit == '' && inputs.is_prerelease && format('{0}:{1}', env.REGISTRY_IMAGE, env.PRERELEASE_TAG) || '' }}\n'
|
|
TG+='${{ inputs.commit == '' && inputs.is_prerelease && inputs.tag_name && format('{0}:{1}.{2}', env.REGISTRY_IMAGE, env.PRERELEASE_TAG, inputs.tag_name) || '' }}\n'
|
|
TG+='${{ inputs.commit == '' && inputs.is_prerelease && format('ghcr.io/{0}:{1}', env.REGISTRY_IMAGE, env.PRERELEASE_TAG) || '' }}\n'
|
|
TG+='${{ inputs.commit == '' && inputs.is_prerelease && inputs.tag_name && format('ghcr.io/{0}:{1}.{2}', env.REGISTRY_IMAGE, env.PRERELEASE_TAG, inputs.tag_name) || '' }}\n'
|
|
|
|
TG+='${{ inputs.commit != '' && format('{0}:{1}', env.REGISTRY_IMAGE, env.COMMIT_TAG) || '' }}\n'
|
|
TG+='${{ inputs.commit != '' && format('{0}:{1}.{2}.{3}', env.REGISTRY_IMAGE, env.COMMIT_TAG, steps.date.outputs.date, steps.sha.outputs.sha) || '' }}\n'
|
|
TG+='${{ inputs.commit != '' && format('ghcr.io/{0}:{1}', env.REGISTRY_IMAGE, env.COMMIT_TAG) || '' }}\n'
|
|
TG+='${{ inputs.commit != '' && format('ghcr.io/{0}:{1}.{2}.{3}', env.REGISTRY_IMAGE, env.COMMIT_TAG, steps.date.outputs.date, steps.sha.outputs.sha) || '' }}'
|
|
echo "tags<<EOF" >> $GITHUB_ENV
|
|
echo -e "$TG" | tr -s '\n' >> $GITHUB_ENV
|
|
echo "EOF" >> $GITHUB_ENV
|
|
|
|
- name: Generate platform array 🖥️📝
|
|
run: |
|
|
PARSED_ARRAY=$(echo '${{ inputs.architectures }}' | jq '. | map("linux/" + .) | .[]' | tr -d '"')
|
|
echo "platforms<<EOF" >> $GITHUB_ENV
|
|
echo "$PARSED_ARRAY" >> $GITHUB_ENV
|
|
echo "EOF" >> $GITHUB_ENV
|
|
|
|
- name: Generate cache array 💾📝
|
|
run: |
|
|
PARSED_ARRAY=$(echo '${{ inputs.architectures }}' | jq '. | map("type=local,mode=min,src=/tmp/${{ env.REGISTRY_IMAGE }}/cache/buildx-" + .) | .[]' | tr -d '"')
|
|
echo "caches<<EOF" >> $GITHUB_ENV
|
|
echo "$PARSED_ARRAY" >> $GITHUB_ENV
|
|
echo "EOF" >> $GITHUB_ENV
|
|
|
|
docker:
|
|
name: Docker image for ${{ matrix.platform }} 💿🐳
|
|
runs-on: ${{ contains(matrix.platform, 'arm') && 'ubuntu-24.04-arm' || 'ubuntu-latest' }}
|
|
needs: docker_inputs
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
platform: ${{ fromJson(inputs.architectures) }}
|
|
|
|
env:
|
|
ARTIFACT_NAME: docker_image-linux_${{ matrix.platform }}
|
|
|
|
steps:
|
|
- name: Checkout ⬇️
|
|
uses: actions/checkout@v4.2.2
|
|
with:
|
|
ref: ${{ inputs.commit || github.sha }}
|
|
show-progress: false
|
|
|
|
- name: Configure QEMU ⚙️
|
|
uses: docker/setup-qemu-action@v3.3.0
|
|
|
|
- name: Configure Docker Buildx ⚙️
|
|
uses: docker/setup-buildx-action@v3.8.0
|
|
with:
|
|
cleanup: false
|
|
version: latest
|
|
|
|
- name: Build images 🛠️
|
|
uses: docker/build-push-action@v6.13.0
|
|
id: image
|
|
with:
|
|
context: .
|
|
file: packaging/docker/Dockerfile
|
|
platforms: ${{ format('linux/{0}', matrix.platform) }}
|
|
no-cache: true
|
|
cache-to: |
|
|
type=local,mode=min,dest=/tmp/${{ env.REGISTRY_IMAGE }}/cache/${{ matrix.platform }}
|
|
outputs: type=docker,dest=docker_image.tar
|
|
build-args: |
|
|
${{ inputs.commit == '' && 'IS_STABLE=1' || '' }}
|
|
${{ inputs.commit != '' && format('COMMIT_HASH={0}', inputs.commit) || '' }}
|
|
tags: |
|
|
${{ needs.docker_inputs.outputs.tags }}
|
|
|
|
- name: Upload Docker image as artifact ⬆️📦
|
|
uses: actions/upload-artifact@v4.6.0
|
|
id: artifact
|
|
with:
|
|
compression-level: 0
|
|
name: ${{ env.ARTIFACT_NAME }}
|
|
path: docker_image.tar
|
|
|
|
- name: Create provenance attestation 🔏
|
|
uses: actions/attest-build-provenance@v2.2.0
|
|
continue-on-error: true
|
|
with:
|
|
subject-name: ${{ env.ARTIFACT_NAME }}
|
|
subject-digest: sha256:${{ steps.artifact.outputs.artifact-digest }}
|
|
|
|
- name: Upload cache artifact ⬆️⚙️
|
|
uses: actions/upload-artifact@v4.6.0
|
|
if: ${{ inputs.push }}
|
|
with:
|
|
compression-level: 0
|
|
name: buildx-${{ matrix.platform }}
|
|
path: |
|
|
/tmp/${{ env.REGISTRY_IMAGE }}/cache/${{ matrix.platform }}
|
|
|
|
frontend:
|
|
name: Publish frontend artifact 🚀
|
|
runs-on: ubuntu-latest
|
|
needs: docker
|
|
|
|
env:
|
|
ARTIFACT_NAME: frontend
|
|
|
|
steps:
|
|
- name: Download Docker image artifact 📦⬇️
|
|
uses: actions/download-artifact@v4.1.8
|
|
with:
|
|
name: docker_image-linux_amd64
|
|
|
|
- name: Extract built client from Docker image 🗜️
|
|
run: |
|
|
docker load < docker_image.tar
|
|
IMAGE_SHA=$(docker images --filter=reference='${{ env.REGISTRY_IMAGE }}' -q | head -n 1)
|
|
ASSETS=$(docker inspect $IMAGE_SHA --format='{{range .Config.Env}}{{println .}}{{end}}' | grep ^ASSETS= | cut -d '=' -f2-)
|
|
docker cp $(docker create --name jf $IMAGE_SHA):$ASSETS/ ./dist
|
|
|
|
- name: Upload client artifact ⬆️💻
|
|
uses: actions/upload-artifact@v4.6.0
|
|
id: artifact
|
|
with:
|
|
compression-level: 0
|
|
name: ${{ env.ARTIFACT_NAME }}
|
|
path: dist
|
|
|
|
- name: Create provenance attestation 🔏
|
|
uses: actions/attest-build-provenance@v2.2.0
|
|
continue-on-error: true
|
|
with:
|
|
subject-name: ${{ env.ARTIFACT_NAME }}
|
|
subject-digest: sha256:${{ steps.artifact.outputs.artifact-digest }}
|
|
|
|
docker_merge:
|
|
name: Merge Docker images 💿🐳
|
|
runs-on: ubuntu-latest
|
|
if: ${{ inputs.push }}
|
|
needs:
|
|
- docker
|
|
- docker_inputs
|
|
|
|
steps:
|
|
- name: Download cache artifacts 📦⬇️
|
|
uses: actions/download-artifact@v4.1.8
|
|
with:
|
|
pattern: buildx-*
|
|
path: /tmp/${{ env.REGISTRY_IMAGE }}/cache/
|
|
|
|
- name: Checkout ⬇️
|
|
uses: actions/checkout@v4.2.2
|
|
with:
|
|
ref: ${{ inputs.commit || github.sha }}
|
|
show-progress: false
|
|
|
|
- name: Configure QEMU ⚙️
|
|
uses: docker/setup-qemu-action@v3.3.0
|
|
|
|
- name: Configure Docker Buildx ⚙️
|
|
uses: docker/setup-buildx-action@v3.8.0
|
|
with:
|
|
cleanup: false
|
|
version: latest
|
|
|
|
- name: Login to Docker Hub 🔑
|
|
uses: docker/login-action@v3.3.0
|
|
with:
|
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
|
|
- name: Login to GitHub Container Registry 🔑
|
|
uses: docker/login-action@v3.3.0
|
|
with:
|
|
registry: ghcr.io
|
|
username: ${{ github.repository_owner }}
|
|
password: ${{ secrets.JF_BOT_TOKEN }}
|
|
|
|
- name: Create multiplatform image ${{ inputs.push && 'and push 🛠️⬆️' || '🛠️' }}
|
|
uses: docker/build-push-action@v6.13.0
|
|
id: image
|
|
with:
|
|
context: .
|
|
file: packaging/docker/Dockerfile
|
|
push: true
|
|
provenance: mode=max
|
|
sbom: true
|
|
cache-from: |
|
|
${{ needs.docker_inputs.outputs.caches }}
|
|
platforms: |
|
|
${{ needs.docker_inputs.outputs.platforms }}
|
|
build-args: |
|
|
${{ inputs.commit == '' && 'IS_STABLE=1' || '' }}
|
|
${{ inputs.commit != '' && format('COMMIT_HASH={0}', inputs.commit) || '' }}
|
|
tags: |
|
|
${{ needs.docker_inputs.outputs.tags }}
|
|
|
|
- name: Remove cache artifacts 🗑️
|
|
uses: geekyeggo/delete-artifact@v5.1.0
|
|
continue-on-error: true
|
|
with:
|
|
name: |
|
|
buildx-*
|