0
0
mirror of https://github.com/jellyfin/jellyfin-vue.git synced 2025-04-27 07:10:53 +00:00
Files
2025-01-25 13:55:29 +00:00

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-*