mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-08-29 03:56:43 +08:00
341 lines
15 KiB
YAML
341 lines
15 KiB
YAML
name: MoviePilot Builder Beta
|
|
on:
|
|
workflow_dispatch:
|
|
|
|
permissions:
|
|
contents: read
|
|
packages: write
|
|
|
|
jobs:
|
|
Docker-build:
|
|
runs-on: ubuntu-latest
|
|
name: Build Docker Image
|
|
env:
|
|
TRIVY_SKIP_DIRS: /usr/share/java
|
|
TRIVY_SKIP_JAVA_DB_UPDATE: "true"
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up uv
|
|
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
with:
|
|
version: '0.12.5'
|
|
|
|
- name: Verify dependency lock
|
|
run: uv lock --check
|
|
|
|
- name: Audit locked Python dependencies
|
|
run: |
|
|
uv export --quiet --locked --no-default-groups --group runtime-standard \
|
|
--no-emit-project --output-file /tmp/moviepilot-audit-standard.txt
|
|
uvx --from pip-audit==2.10.1 pip-audit \
|
|
--require-hashes --disable-pip --strict --progress-spinner off \
|
|
--requirement /tmp/moviepilot-audit-standard.txt
|
|
|
|
uv export --quiet --locked --no-default-groups --group runtime-free-threaded \
|
|
--no-emit-project --no-hashes \
|
|
--output-file /tmp/moviepilot-audit-free-threaded.txt
|
|
python3 scripts/normalize_audit_requirements.py \
|
|
--lock uv.lock \
|
|
--input /tmp/moviepilot-audit-free-threaded.txt \
|
|
--output /tmp/moviepilot-audit-free-threaded-normalized.txt
|
|
uvx --from pip-audit==2.10.1 pip-audit \
|
|
--no-deps --disable-pip --strict --progress-spinner off \
|
|
--requirement /tmp/moviepilot-audit-free-threaded-normalized.txt
|
|
|
|
- name: Release version
|
|
id: release_version
|
|
run: |
|
|
app_version=$(cat version.py |sed -ne "s/APP_VERSION\s=\s'v\(.*\)'/\1/gp")
|
|
frontend_version=$(sed -ne "s/FRONTEND_VERSION\s*=\s*'\([^']*\)'/\1/gp" version.py)
|
|
echo "app_version=$app_version" >> $GITHUB_ENV
|
|
echo "SOURCE_COMMIT=$(git rev-parse HEAD)" >> $GITHUB_ENV
|
|
echo "frontend_version=$frontend_version" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Resolve External Payload Revisions
|
|
id: payloads
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
FRONTEND_VERSION: ${{ steps.release_version.outputs.frontend_version }}
|
|
run: |
|
|
plugins_revision=$(git ls-remote https://github.com/jxxghp/MoviePilot-Plugins.git refs/heads/main | awk '{print $1}')
|
|
resources_revision=$(git ls-remote https://github.com/jxxghp/MoviePilot-Resources.git refs/heads/main | awk '{print $1}')
|
|
frontend_digest=$(gh api "repos/jxxghp/MoviePilot-Frontend/releases/tags/${FRONTEND_VERSION}" \
|
|
--jq '.assets[] | select(.name == "dist.zip") | .digest')
|
|
|
|
[[ "$plugins_revision" =~ ^[0-9a-f]{40}$ ]]
|
|
[[ "$resources_revision" =~ ^[0-9a-f]{40}$ ]]
|
|
case "$frontend_digest" in
|
|
sha256:*) frontend_sha256=${frontend_digest#sha256:} ;;
|
|
*) echo "dist.zip 缺少 SHA-256 摘要" >&2; exit 1 ;;
|
|
esac
|
|
[[ "$frontend_sha256" =~ ^[0-9a-f]{64}$ ]]
|
|
|
|
echo "plugins_revision=$plugins_revision" >> "$GITHUB_OUTPUT"
|
|
echo "resources_revision=$resources_revision" >> "$GITHUB_OUTPUT"
|
|
echo "frontend_digest=$frontend_digest" >> "$GITHUB_OUTPUT"
|
|
echo "frontend_sha256=$frontend_sha256" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Checkout Wiki Plugin Market
|
|
uses: actions/checkout@v4
|
|
with:
|
|
repository: jxxghp/MoviePilot-Wiki
|
|
ref: main
|
|
path: .build/moviepilot-wiki
|
|
sparse-checkout: plugin.md
|
|
sparse-checkout-cone-mode: false
|
|
persist-credentials: false
|
|
|
|
- name: Generate Plugin Market Default
|
|
id: plugin_market
|
|
run: |
|
|
python3 -m scripts.generate_plugin_market_default \
|
|
--wiki-file .build/moviepilot-wiki/plugin.md \
|
|
--config-file app/runtime/config.py
|
|
wiki_commit=$(git -C .build/moviepilot-wiki rev-parse HEAD)
|
|
echo "wiki_commit=$wiki_commit" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Download models.dev catalog
|
|
id: models_catalog
|
|
run: |
|
|
temp_file=$(mktemp app/agent/llm/models.json.XXXXXX)
|
|
trap 'rm -f "$temp_file"' EXIT
|
|
curl --fail --show-error --silent --location --retry 3 \
|
|
--connect-timeout 10 --max-time 120 \
|
|
"https://models.dev/api.json" -o "$temp_file"
|
|
jq -e 'type == "object"' "$temp_file" >/dev/null
|
|
# Git keeps only a small placeholder; the beta image receives the current catalog.
|
|
chmod 644 "$temp_file"
|
|
mv "$temp_file" app/agent/llm/models.json
|
|
echo "digest=sha256:$(sha256sum app/agent/llm/models.json | awk '{print $1}')" >> "$GITHUB_OUTPUT"
|
|
echo "Downloaded models.dev catalog ($(wc -c < app/agent/llm/models.json) bytes)"
|
|
|
|
- name: Docker Meta
|
|
id: meta
|
|
uses: docker/metadata-action@v5
|
|
with:
|
|
images: |
|
|
${{ secrets.DOCKER_USERNAME }}/moviepilot-v3
|
|
ghcr.io/${{ github.repository }}-v3
|
|
tags: |
|
|
type=raw,value=beta
|
|
|
|
- name: Docker Meta free-threaded
|
|
id: meta_ft
|
|
uses: docker/metadata-action@v5
|
|
with:
|
|
images: |
|
|
${{ secrets.DOCKER_USERNAME }}/moviepilot-v3t
|
|
ghcr.io/${{ github.repository }}-v3t
|
|
tags: |
|
|
type=raw,value=beta
|
|
|
|
- name: Set Up QEMU
|
|
uses: docker/setup-qemu-action@v3
|
|
|
|
- name: Set Up Buildx
|
|
uses: docker/setup-buildx-action@v3
|
|
|
|
- name: Build standard amd64 candidate
|
|
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
|
|
with:
|
|
context: .
|
|
file: docker/Dockerfile
|
|
platforms: linux/amd64
|
|
load: true
|
|
push: false
|
|
pull: true
|
|
tags: moviepilot-v3-candidate:linux-amd64
|
|
build-args: |
|
|
MOVIEPILOT_FRONTEND_VERSION=${{ steps.release_version.outputs.frontend_version }}
|
|
MOVIEPILOT_FRONTEND_SHA256=${{ steps.payloads.outputs.frontend_sha256 }}
|
|
MOVIEPILOT_PLUGINS_REF=${{ steps.payloads.outputs.plugins_revision }}
|
|
MOVIEPILOT_RESOURCES_REF=${{ steps.payloads.outputs.resources_revision }}
|
|
MOVIEPILOT_PYTHON_VARIANT=standard
|
|
cache-from: type=gha,scope=moviepilot-v3-standard-docker-amd64,version=2
|
|
cache-to: type=gha,scope=moviepilot-v3-standard-docker-amd64,mode=max,version=2
|
|
|
|
- name: Scan standard amd64 candidate vulnerabilities
|
|
uses: aquasecurity/trivy-action@a9c7b0f06e461e9d4b4d1711f154ee024b8d7ab8 # v0.36.0
|
|
with:
|
|
image-ref: moviepilot-v3-candidate:linux-amd64
|
|
version: v0.70.0
|
|
cache-dir: ${{ runner.temp }}/trivy
|
|
scanners: vuln
|
|
vuln-type: os,library
|
|
severity: HIGH,CRITICAL
|
|
ignore-unfixed: true
|
|
trivyignores: .trivyignore.yaml
|
|
exit-code: 1
|
|
|
|
- name: Build standard arm64 candidate
|
|
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
|
|
with:
|
|
context: .
|
|
file: docker/Dockerfile
|
|
platforms: linux/arm64/v8
|
|
load: true
|
|
push: false
|
|
pull: true
|
|
tags: moviepilot-v3-candidate:linux-arm64
|
|
build-args: |
|
|
MOVIEPILOT_FRONTEND_VERSION=${{ steps.release_version.outputs.frontend_version }}
|
|
MOVIEPILOT_FRONTEND_SHA256=${{ steps.payloads.outputs.frontend_sha256 }}
|
|
MOVIEPILOT_PLUGINS_REF=${{ steps.payloads.outputs.plugins_revision }}
|
|
MOVIEPILOT_RESOURCES_REF=${{ steps.payloads.outputs.resources_revision }}
|
|
MOVIEPILOT_PYTHON_VARIANT=standard
|
|
cache-from: type=gha,scope=moviepilot-v3-standard-docker-arm64,version=2
|
|
cache-to: type=gha,scope=moviepilot-v3-standard-docker-arm64,mode=max,version=2
|
|
|
|
- name: Scan standard arm64 candidate vulnerabilities
|
|
uses: aquasecurity/trivy-action@a9c7b0f06e461e9d4b4d1711f154ee024b8d7ab8 # v0.36.0
|
|
with:
|
|
image-ref: moviepilot-v3-candidate:linux-arm64
|
|
version: v0.70.0
|
|
cache-dir: ${{ runner.temp }}/trivy
|
|
scanners: vuln
|
|
vuln-type: os,library
|
|
severity: HIGH,CRITICAL
|
|
ignore-unfixed: true
|
|
trivyignores: .trivyignore.yaml
|
|
exit-code: 1
|
|
|
|
- name: Build free-threaded amd64 candidate
|
|
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
|
|
with:
|
|
context: .
|
|
file: docker/Dockerfile
|
|
platforms: linux/amd64
|
|
load: true
|
|
push: false
|
|
pull: true
|
|
tags: moviepilot-v3t-candidate:linux-amd64
|
|
build-args: |
|
|
MOVIEPILOT_FRONTEND_VERSION=${{ steps.release_version.outputs.frontend_version }}
|
|
MOVIEPILOT_FRONTEND_SHA256=${{ steps.payloads.outputs.frontend_sha256 }}
|
|
MOVIEPILOT_PLUGINS_REF=${{ steps.payloads.outputs.plugins_revision }}
|
|
MOVIEPILOT_RESOURCES_REF=${{ steps.payloads.outputs.resources_revision }}
|
|
MOVIEPILOT_PYTHON_VARIANT=free-threaded
|
|
cache-from: type=gha,scope=moviepilot-v3t-docker-amd64,version=2
|
|
cache-to: type=gha,scope=moviepilot-v3t-docker-amd64,mode=max,version=2
|
|
|
|
- name: Scan free-threaded amd64 candidate vulnerabilities
|
|
uses: aquasecurity/trivy-action@a9c7b0f06e461e9d4b4d1711f154ee024b8d7ab8 # v0.36.0
|
|
with:
|
|
image-ref: moviepilot-v3t-candidate:linux-amd64
|
|
version: v0.70.0
|
|
cache-dir: ${{ runner.temp }}/trivy
|
|
scanners: vuln
|
|
vuln-type: os,library
|
|
severity: HIGH,CRITICAL
|
|
ignore-unfixed: true
|
|
trivyignores: .trivyignore.yaml
|
|
exit-code: 1
|
|
|
|
- name: Build free-threaded arm64 candidate
|
|
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
|
|
with:
|
|
context: .
|
|
file: docker/Dockerfile
|
|
platforms: linux/arm64/v8
|
|
load: true
|
|
push: false
|
|
pull: true
|
|
tags: moviepilot-v3t-candidate:linux-arm64
|
|
build-args: |
|
|
MOVIEPILOT_FRONTEND_VERSION=${{ steps.release_version.outputs.frontend_version }}
|
|
MOVIEPILOT_FRONTEND_SHA256=${{ steps.payloads.outputs.frontend_sha256 }}
|
|
MOVIEPILOT_PLUGINS_REF=${{ steps.payloads.outputs.plugins_revision }}
|
|
MOVIEPILOT_RESOURCES_REF=${{ steps.payloads.outputs.resources_revision }}
|
|
MOVIEPILOT_PYTHON_VARIANT=free-threaded
|
|
cache-from: type=gha,scope=moviepilot-v3t-docker-arm64,version=2
|
|
cache-to: type=gha,scope=moviepilot-v3t-docker-arm64,mode=max,version=2
|
|
|
|
- name: Scan free-threaded arm64 candidate vulnerabilities
|
|
uses: aquasecurity/trivy-action@a9c7b0f06e461e9d4b4d1711f154ee024b8d7ab8 # v0.36.0
|
|
with:
|
|
image-ref: moviepilot-v3t-candidate:linux-arm64
|
|
version: v0.70.0
|
|
cache-dir: ${{ runner.temp }}/trivy
|
|
scanners: vuln
|
|
vuln-type: os,library
|
|
severity: HIGH,CRITICAL
|
|
ignore-unfixed: true
|
|
trivyignores: .trivyignore.yaml
|
|
exit-code: 1
|
|
|
|
- name: Login DockerHub
|
|
uses: docker/login-action@v3
|
|
with:
|
|
username: ${{ secrets.DOCKER_USERNAME }}
|
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
|
|
|
- name: Login GitHub Container Registry
|
|
uses: docker/login-action@v3
|
|
with:
|
|
registry: ghcr.io
|
|
username: ${{ github.actor }}
|
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Publish standard multi-architecture image
|
|
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
|
|
with:
|
|
context: .
|
|
file: docker/Dockerfile
|
|
platforms: |
|
|
linux/amd64
|
|
linux/arm64/v8
|
|
push: true
|
|
tags: ${{ steps.meta.outputs.tags }}
|
|
build-args: |
|
|
MOVIEPILOT_FRONTEND_VERSION=${{ steps.release_version.outputs.frontend_version }}
|
|
MOVIEPILOT_FRONTEND_SHA256=${{ steps.payloads.outputs.frontend_sha256 }}
|
|
MOVIEPILOT_PLUGINS_REF=${{ steps.payloads.outputs.plugins_revision }}
|
|
MOVIEPILOT_RESOURCES_REF=${{ steps.payloads.outputs.resources_revision }}
|
|
MOVIEPILOT_PYTHON_VARIANT=standard
|
|
labels: |
|
|
${{ steps.meta.outputs.labels }}
|
|
org.opencontainers.image.revision=${{ env.SOURCE_COMMIT }}
|
|
org.moviepilot.source-revision=${{ env.SOURCE_COMMIT }}
|
|
org.moviepilot.frontend-version=${{ steps.release_version.outputs.frontend_version }}
|
|
org.moviepilot.frontend-digest=${{ steps.payloads.outputs.frontend_digest }}
|
|
org.moviepilot.plugins-revision=${{ steps.payloads.outputs.plugins_revision }}
|
|
org.moviepilot.resources-revision=${{ steps.payloads.outputs.resources_revision }}
|
|
org.moviepilot.plugin-market-wiki-revision=${{ steps.plugin_market.outputs.wiki_commit }}
|
|
org.moviepilot.models-catalog-digest=${{ steps.models_catalog.outputs.digest }}
|
|
cache-from: |
|
|
type=gha,scope=moviepilot-v3-standard-docker-amd64,version=2
|
|
type=gha,scope=moviepilot-v3-standard-docker-arm64,version=2
|
|
|
|
- name: Publish free-threaded multi-architecture image
|
|
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
|
|
with:
|
|
context: .
|
|
file: docker/Dockerfile
|
|
platforms: |
|
|
linux/amd64
|
|
linux/arm64/v8
|
|
push: true
|
|
pull: false
|
|
tags: ${{ steps.meta_ft.outputs.tags }}
|
|
build-args: |
|
|
MOVIEPILOT_FRONTEND_VERSION=${{ steps.release_version.outputs.frontend_version }}
|
|
MOVIEPILOT_FRONTEND_SHA256=${{ steps.payloads.outputs.frontend_sha256 }}
|
|
MOVIEPILOT_PLUGINS_REF=${{ steps.payloads.outputs.plugins_revision }}
|
|
MOVIEPILOT_RESOURCES_REF=${{ steps.payloads.outputs.resources_revision }}
|
|
MOVIEPILOT_PYTHON_VARIANT=free-threaded
|
|
labels: |
|
|
${{ steps.meta_ft.outputs.labels }}
|
|
org.opencontainers.image.revision=${{ env.SOURCE_COMMIT }}
|
|
org.moviepilot.source-revision=${{ env.SOURCE_COMMIT }}
|
|
org.moviepilot.frontend-version=${{ steps.release_version.outputs.frontend_version }}
|
|
org.moviepilot.frontend-digest=${{ steps.payloads.outputs.frontend_digest }}
|
|
org.moviepilot.plugins-revision=${{ steps.payloads.outputs.plugins_revision }}
|
|
org.moviepilot.resources-revision=${{ steps.payloads.outputs.resources_revision }}
|
|
org.moviepilot.plugin-market-wiki-revision=${{ steps.plugin_market.outputs.wiki_commit }}
|
|
org.moviepilot.models-catalog-digest=${{ steps.models_catalog.outputs.digest }}
|
|
cache-from: |
|
|
type=gha,scope=moviepilot-v3t-docker-amd64,version=2
|
|
type=gha,scope=moviepilot-v3t-docker-arm64,version=2
|