mirror of
https://github.com/jellyfin/jellyfin-packaging.git
synced 2026-09-03 03:29:58 +03:00
Split Docker builds for parallelization
The previous pattern built the amd64 and arm64 Docker images sequentially and then build and pushed manifests as one single long task under build.py. Split this up so the two architectures can be built in parallel, and then handle manifests as a separate step in the GitHub Actions workflow. Also split out the pushes from build.py, and remove --local since no manual runs of this script should ever need this.
This commit is contained in:
@@ -22,9 +22,15 @@ permissions:
|
||||
jobs:
|
||||
Docker:
|
||||
runs-on: ubuntu-24.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
arch:
|
||||
- amd64
|
||||
- arm64
|
||||
continue-on-error: false # true in prod, false for testing
|
||||
steps:
|
||||
- name: "Set dated version for unstable builds"
|
||||
- name: "Set version"
|
||||
id: version
|
||||
run: |-
|
||||
echo "JELLYFIN_VERSION=${{ inputs.version }}-rc${{ inputs.preview_id }}" >> $GITHUB_ENV
|
||||
@@ -43,14 +49,74 @@ jobs:
|
||||
run: |-
|
||||
./checkout.py ${{ inputs.version }}-rc${{ inputs.preview_id }}
|
||||
|
||||
- name: "Run builder for Docker containers"
|
||||
env:
|
||||
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
|
||||
DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }}
|
||||
GHCR_USERNAME: ${{ secrets.GHCR_USERNAME }}
|
||||
GHCR_TOKEN: ${{ secrets.GHCR_TOKEN }}
|
||||
- name: "Run builder for Docker ${{ matrix.arch }}"
|
||||
run: |-
|
||||
sudo --preserve-env ./build.py ${{ env.JELLYFIN_VERSION }} docker ${{ env.DEBUG_FLAG }}
|
||||
sudo ./build.py ${{ env.JELLYFIN_VERSION }} docker ${{ matrix.arch }} ${{ env.DEBUG_FLAG }}
|
||||
|
||||
- name: "Push Docker image to registries"
|
||||
run: |-
|
||||
VERSION="${{ env.JELLYFIN_VERSION }}"
|
||||
CLEAN_VERSION="${VERSION#v}"
|
||||
IMAGE="jellyfin/jellyfin:${CLEAN_VERSION}-${{ matrix.arch }}"
|
||||
GHCR_IMAGE="ghcr.io/jellyfin/jellyfin:${CLEAN_VERSION}-${{ matrix.arch }}"
|
||||
docker image tag ${IMAGE} ${GHCR_IMAGE}
|
||||
docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_TOKEN }} 2>&1
|
||||
docker push ${IMAGE}
|
||||
docker logout
|
||||
docker login -u ${{ secrets.GHCR_USERNAME }} -p ${{ secrets.GHCR_TOKEN }} ghcr.io 2>&1
|
||||
docker push ${GHCR_IMAGE}
|
||||
docker logout ghcr.io
|
||||
|
||||
DockerManifest:
|
||||
needs:
|
||||
- Docker
|
||||
runs-on: ubuntu-24.04
|
||||
continue-on-error: false # true in prod, false for testing
|
||||
steps:
|
||||
- name: "Set version"
|
||||
id: version
|
||||
run: |-
|
||||
echo "JELLYFIN_VERSION=${{ inputs.version }}-rc${{ inputs.preview_id }}" >> $GITHUB_ENV
|
||||
|
||||
- name: "Log in to Docker Hub"
|
||||
run: |-
|
||||
docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_TOKEN }} 2>&1
|
||||
|
||||
- name: "Log in to GHCR"
|
||||
run: |-
|
||||
docker login -u ${{ secrets.GHCR_USERNAME }} -p ${{ secrets.GHCR_TOKEN }} ghcr.io 2>&1
|
||||
|
||||
- name: "Create and push manifests"
|
||||
run: |-
|
||||
VERSION="${{ env.JELLYFIN_VERSION }}"
|
||||
CLEAN_VERSION="${VERSION#v}"
|
||||
DATE=$(date +'%Y%m%d-%H%M%S')
|
||||
HUB="jellyfin/jellyfin"
|
||||
GHCR="ghcr.io/jellyfin/jellyfin"
|
||||
HUB_SOURCES="${HUB}:${CLEAN_VERSION}-amd64 ${HUB}:${CLEAN_VERSION}-arm64"
|
||||
GHCR_SOURCES="${GHCR}:${CLEAN_VERSION}-amd64 ${GHCR}:${CLEAN_VERSION}-arm64"
|
||||
|
||||
# Dated X.Y.Z-rcN manifest
|
||||
docker manifest create ${HUB}:${CLEAN_VERSION}.${DATE} ${HUB_SOURCES}
|
||||
docker manifest push --purge ${HUB}:${CLEAN_VERSION}.${DATE}
|
||||
docker manifest create ${GHCR}:${CLEAN_VERSION}.${DATE} ${GHCR_SOURCES}
|
||||
docker manifest push --purge ${GHCR}:${CLEAN_VERSION}.${DATE}
|
||||
# X.Y.Z-rcN manifest
|
||||
docker manifest create ${HUB}:${CLEAN_VERSION} ${HUB_SOURCES}
|
||||
docker manifest push --purge ${HUB}:${CLEAN_VERSION}
|
||||
docker manifest create ${GHCR}:${CLEAN_VERSION} ${GHCR_SOURCES}
|
||||
docker manifest push --purge ${GHCR}:${CLEAN_VERSION}
|
||||
# preview manifest
|
||||
docker manifest create ${HUB}:preview ${HUB_SOURCES}
|
||||
docker manifest push --purge ${HUB}:preview
|
||||
docker manifest create ${GHCR}:preview ${GHCR_SOURCES}
|
||||
docker manifest push --purge ${GHCR}:preview
|
||||
|
||||
- name: "Log out of registries"
|
||||
if: always()
|
||||
run: |-
|
||||
docker logout
|
||||
docker logout ghcr.io
|
||||
|
||||
Debian:
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
@@ -18,9 +18,15 @@ permissions:
|
||||
jobs:
|
||||
Docker:
|
||||
runs-on: ubuntu-24.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
arch:
|
||||
- amd64
|
||||
- arm64
|
||||
continue-on-error: false # true in prod, false for testing
|
||||
steps:
|
||||
- name: "Set dated version for unstable builds"
|
||||
- name: "Set version"
|
||||
id: version
|
||||
run: |-
|
||||
echo "JELLYFIN_VERSION=${{ inputs.version }}" >> $GITHUB_ENV
|
||||
@@ -38,14 +44,86 @@ jobs:
|
||||
run: |-
|
||||
./checkout.py ${{ inputs.version || 'master' }}
|
||||
|
||||
- name: "Run builder for Docker containers"
|
||||
env:
|
||||
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
|
||||
DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }}
|
||||
GHCR_USERNAME: ${{ secrets.GHCR_USERNAME }}
|
||||
GHCR_TOKEN: ${{ secrets.GHCR_TOKEN }}
|
||||
- name: "Run builder for Docker ${{ matrix.arch }}"
|
||||
run: |-
|
||||
sudo --preserve-env ./build.py ${{ env.JELLYFIN_VERSION }} docker ${{ env.DEBUG_FLAG }}
|
||||
sudo ./build.py ${{ env.JELLYFIN_VERSION }} docker ${{ matrix.arch }} ${{ env.DEBUG_FLAG }}
|
||||
|
||||
- name: "Push Docker image to registries"
|
||||
run: |-
|
||||
VERSION="${{ env.JELLYFIN_VERSION }}"
|
||||
CLEAN_VERSION="${VERSION#v}"
|
||||
IMAGE="jellyfin/jellyfin:${CLEAN_VERSION}-${{ matrix.arch }}"
|
||||
GHCR_IMAGE="ghcr.io/jellyfin/jellyfin:${CLEAN_VERSION}-${{ matrix.arch }}"
|
||||
docker image tag ${IMAGE} ${GHCR_IMAGE}
|
||||
docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_TOKEN }} 2>&1
|
||||
docker push ${IMAGE}
|
||||
docker logout
|
||||
docker login -u ${{ secrets.GHCR_USERNAME }} -p ${{ secrets.GHCR_TOKEN }} ghcr.io 2>&1
|
||||
docker push ${GHCR_IMAGE}
|
||||
docker logout ghcr.io
|
||||
|
||||
DockerManifest:
|
||||
needs:
|
||||
- Docker
|
||||
runs-on: ubuntu-24.04
|
||||
continue-on-error: false # true in prod, false for testing
|
||||
steps:
|
||||
- name: "Set version"
|
||||
id: version
|
||||
run: |-
|
||||
echo "JELLYFIN_VERSION=${{ inputs.version }}" >> $GITHUB_ENV
|
||||
|
||||
- name: "Log in to Docker Hub"
|
||||
run: |-
|
||||
docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_TOKEN }} 2>&1
|
||||
|
||||
- name: "Log in to GHCR"
|
||||
run: |-
|
||||
docker login -u ${{ secrets.GHCR_USERNAME }} -p ${{ secrets.GHCR_TOKEN }} ghcr.io 2>&1
|
||||
|
||||
- name: "Create and push manifests"
|
||||
run: |-
|
||||
VERSION="${{ env.JELLYFIN_VERSION }}"
|
||||
CLEAN_VERSION="${VERSION#v}"
|
||||
DATE=$(date +'%Y%m%d-%H%M%S')
|
||||
HUB="jellyfin/jellyfin"
|
||||
GHCR="ghcr.io/jellyfin/jellyfin"
|
||||
HUB_SOURCES="${HUB}:${CLEAN_VERSION}-amd64 ${HUB}:${CLEAN_VERSION}-arm64"
|
||||
GHCR_SOURCES="${GHCR}:${CLEAN_VERSION}-amd64 ${GHCR}:${CLEAN_VERSION}-arm64"
|
||||
XY="${CLEAN_VERSION%.*}"
|
||||
X="${XY%.*}"
|
||||
|
||||
# Dated X.Y.Z manifest
|
||||
docker manifest create ${HUB}:${CLEAN_VERSION}.${DATE} ${HUB_SOURCES}
|
||||
docker manifest push --purge ${HUB}:${CLEAN_VERSION}.${DATE}
|
||||
docker manifest create ${GHCR}:${CLEAN_VERSION}.${DATE} ${GHCR_SOURCES}
|
||||
docker manifest push --purge ${GHCR}:${CLEAN_VERSION}.${DATE}
|
||||
# X.Y.Z manifest
|
||||
docker manifest create ${HUB}:${CLEAN_VERSION} ${HUB_SOURCES}
|
||||
docker manifest push --purge ${HUB}:${CLEAN_VERSION}
|
||||
docker manifest create ${GHCR}:${CLEAN_VERSION} ${GHCR_SOURCES}
|
||||
docker manifest push --purge ${GHCR}:${CLEAN_VERSION}
|
||||
# X.Y manifest
|
||||
docker manifest create ${HUB}:${XY} ${HUB_SOURCES}
|
||||
docker manifest push --purge ${HUB}:${XY}
|
||||
docker manifest create ${GHCR}:${XY} ${GHCR_SOURCES}
|
||||
docker manifest push --purge ${GHCR}:${XY}
|
||||
# X manifest
|
||||
docker manifest create ${HUB}:${X} ${HUB_SOURCES}
|
||||
docker manifest push --purge ${HUB}:${X}
|
||||
docker manifest create ${GHCR}:${X} ${GHCR_SOURCES}
|
||||
docker manifest push --purge ${GHCR}:${X}
|
||||
# latest manifest
|
||||
docker manifest create ${HUB}:latest ${HUB_SOURCES}
|
||||
docker manifest push --purge ${HUB}:latest
|
||||
docker manifest create ${GHCR}:latest ${GHCR_SOURCES}
|
||||
docker manifest push --purge ${GHCR}:latest
|
||||
|
||||
- name: "Log out of registries"
|
||||
if: always()
|
||||
run: |-
|
||||
docker logout
|
||||
docker logout ghcr.io
|
||||
|
||||
Debian:
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
@@ -16,12 +16,21 @@ permissions:
|
||||
jobs:
|
||||
Docker:
|
||||
runs-on: ubuntu-24.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
arch:
|
||||
- amd64
|
||||
- arm64
|
||||
outputs:
|
||||
JELLYFIN_VERSION: ${{ steps.version.outputs.JELLYFIN_VERSION }}
|
||||
continue-on-error: false # true in prod, false for testing
|
||||
steps:
|
||||
- name: "Set dated version for unstable builds"
|
||||
id: version
|
||||
run: |-
|
||||
echo "JELLYFIN_VERSION=$(date +'%Y%m%d%H')" >> $GITHUB_ENV
|
||||
echo "JELLYFIN_VERSION=$(date +'%Y%m%d%H')" >> $GITHUB_OUTPUT
|
||||
echo "JELLYFIN_RELEASE_TYPE=unstable" >> $GITHUB_ENV
|
||||
echo "DEBUG_FLAG=--debug" >>$GITHUB_ENV
|
||||
|
||||
@@ -37,14 +46,66 @@ jobs:
|
||||
run: |-
|
||||
./checkout.py master
|
||||
|
||||
- name: "Run builder for Docker containers"
|
||||
env:
|
||||
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
|
||||
DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }}
|
||||
GHCR_USERNAME: ${{ secrets.GHCR_USERNAME }}
|
||||
GHCR_TOKEN: ${{ secrets.GHCR_TOKEN }}
|
||||
- name: "Run builder for Docker ${{ matrix.arch }}"
|
||||
run: |-
|
||||
sudo --preserve-env ./build.py ${{ env.JELLYFIN_VERSION }} docker ${{ env.DEBUG_FLAG }}
|
||||
sudo ./build.py ${{ env.JELLYFIN_VERSION }} docker ${{ matrix.arch }} ${{ env.DEBUG_FLAG }}
|
||||
|
||||
- name: "Push Docker image to registries"
|
||||
run: |-
|
||||
CLEAN_VERSION="${{ env.JELLYFIN_VERSION }}"
|
||||
IMAGE="jellyfin/jellyfin:${CLEAN_VERSION}-${{ matrix.arch }}"
|
||||
GHCR_IMAGE="ghcr.io/jellyfin/jellyfin:${CLEAN_VERSION}-${{ matrix.arch }}"
|
||||
docker image tag ${IMAGE} ${GHCR_IMAGE}
|
||||
docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_TOKEN }} 2>&1
|
||||
docker push ${IMAGE}
|
||||
docker logout
|
||||
docker login -u ${{ secrets.GHCR_USERNAME }} -p ${{ secrets.GHCR_TOKEN }} ghcr.io 2>&1
|
||||
docker push ${GHCR_IMAGE}
|
||||
docker logout ghcr.io
|
||||
|
||||
DockerManifest:
|
||||
needs:
|
||||
- Docker
|
||||
runs-on: ubuntu-24.04
|
||||
continue-on-error: false # true in prod, false for testing
|
||||
steps:
|
||||
- name: "Set version from previous job"
|
||||
id: version
|
||||
run: |-
|
||||
echo "JELLYFIN_VERSION=${{ needs.Docker.outputs.JELLYFIN_VERSION }}" >> $GITHUB_ENV
|
||||
|
||||
- name: "Log in to Docker Hub"
|
||||
run: |-
|
||||
docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_TOKEN }} 2>&1
|
||||
|
||||
- name: "Log in to GHCR"
|
||||
run: |-
|
||||
docker login -u ${{ secrets.GHCR_USERNAME }} -p ${{ secrets.GHCR_TOKEN }} ghcr.io 2>&1
|
||||
|
||||
- name: "Create and push manifests"
|
||||
run: |-
|
||||
CLEAN_VERSION="${{ env.JELLYFIN_VERSION }}"
|
||||
HUB="jellyfin/jellyfin"
|
||||
GHCR="ghcr.io/jellyfin/jellyfin"
|
||||
HUB_SOURCES="${HUB}:${CLEAN_VERSION}-amd64 ${HUB}:${CLEAN_VERSION}-arm64"
|
||||
GHCR_SOURCES="${GHCR}:${CLEAN_VERSION}-amd64 ${GHCR}:${CLEAN_VERSION}-arm64"
|
||||
|
||||
# Dated version manifest (the version string already contains the date for unstable)
|
||||
docker manifest create ${HUB}:${CLEAN_VERSION} ${HUB_SOURCES}
|
||||
docker manifest push --purge ${HUB}:${CLEAN_VERSION}
|
||||
docker manifest create ${GHCR}:${CLEAN_VERSION} ${GHCR_SOURCES}
|
||||
docker manifest push --purge ${GHCR}:${CLEAN_VERSION}
|
||||
# unstable manifest
|
||||
docker manifest create ${HUB}:unstable ${HUB_SOURCES}
|
||||
docker manifest push --purge ${HUB}:unstable
|
||||
docker manifest create ${GHCR}:unstable ${GHCR_SOURCES}
|
||||
docker manifest push --purge ${GHCR}:unstable
|
||||
|
||||
- name: "Log out of registries"
|
||||
if: always()
|
||||
run: |-
|
||||
docker logout
|
||||
docker logout ghcr.io
|
||||
|
||||
Debian:
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
@@ -399,239 +399,56 @@ def build_docker(
|
||||
jellyfin_version, build_type, build_arch, _build_version, local=False, debug=False
|
||||
):
|
||||
"""
|
||||
Build Docker images for one or all architectures and combining manifests
|
||||
Build a Docker image for a single architecture and load it into the local daemon
|
||||
"""
|
||||
log("> Building Docker images...")
|
||||
|
||||
if build_arch:
|
||||
log(f"NOTE: Building only for arch {build_arch}")
|
||||
|
||||
# We build all architectures simultaneously to push a single tag, so no conditional checks
|
||||
architectures = configurations["docker"]["archmaps"].keys()
|
||||
|
||||
if build_arch:
|
||||
if build_arch not in architectures:
|
||||
log(f"Error: Architecture {build_arch} is not valid.")
|
||||
exit(1)
|
||||
else:
|
||||
architectures = [build_arch]
|
||||
log(f"> Building Docker image for {build_arch}...")
|
||||
log("")
|
||||
|
||||
# Set the dockerfile
|
||||
dockerfile = configurations[build_type]["dockerfile"]
|
||||
|
||||
# Determine if this is a "latest"-type image (v in jellyfin_version) or not
|
||||
if "v" in jellyfin_version and not "rc" in jellyfin_version:
|
||||
is_stable = True
|
||||
is_preview = False
|
||||
elif "rc" in jellyfin_version:
|
||||
is_stable = False
|
||||
is_preview = True
|
||||
else:
|
||||
is_stable = False
|
||||
is_preview = False
|
||||
|
||||
jellyfin_version = jellyfin_version.replace("v", "")
|
||||
|
||||
log(f"NOTE: Build type is {'stable' if is_stable else 'preview/unstable'} for version {jellyfin_version}")
|
||||
log(f"NOTE: Building version {jellyfin_version} for {build_arch}")
|
||||
log("")
|
||||
|
||||
# Set today's date in a convenient format for use as an image suffix
|
||||
date = datetime.now().strftime("%Y%m%d-%H%M%S")
|
||||
# Get our ARCH variables from the archmaps
|
||||
PACKAGE_ARCH = configurations["docker"]["archmaps"][build_arch]["PACKAGE_ARCH"]
|
||||
DOTNET_ARCH = configurations["docker"]["archmaps"][build_arch]["DOTNET_ARCH"]
|
||||
IMAGE_ARCH = configurations["docker"]["archmaps"][build_arch]["IMAGE_ARCH"]
|
||||
TARGET_ARCH = configurations["docker"]["archmaps"][build_arch]["TARGET_ARCH"]
|
||||
|
||||
images_hub = list()
|
||||
images_ghcr = list()
|
||||
for _build_arch in architectures:
|
||||
log(f">> Building Docker image for {_build_arch}...")
|
||||
log("")
|
||||
# Use a consistent per-arch image name (no date suffix; overwritten on rebuild)
|
||||
imagename = f"{configurations['docker']['imagename']}:{jellyfin_version}-{build_arch}"
|
||||
|
||||
# Get our ARCH variables from the archmaps
|
||||
PACKAGE_ARCH = configurations["docker"]["archmaps"][_build_arch]["PACKAGE_ARCH"]
|
||||
DOTNET_ARCH = configurations["docker"]["archmaps"][_build_arch]["DOTNET_ARCH"]
|
||||
IMAGE_ARCH = configurations["docker"]["archmaps"][_build_arch]["IMAGE_ARCH"]
|
||||
TARGET_ARCH = configurations["docker"]["archmaps"][_build_arch]["TARGET_ARCH"]
|
||||
# Clean up any existing qemu static image
|
||||
log(f">>> {docker_run_cmd} --privileged linuxserver/qemu-static --reset -p yes")
|
||||
os.system(f"{docker_run_cmd} --privileged linuxserver/qemu-static --reset -p yes")
|
||||
log("")
|
||||
|
||||
# Use a unique docker image name for consistency
|
||||
if is_stable or is_preview:
|
||||
imagename = f"{configurations['docker']['imagename']}:{jellyfin_version}-{_build_arch}.{date}"
|
||||
else:
|
||||
imagename = f"{configurations['docker']['imagename']}:{jellyfin_version}-{_build_arch}"
|
||||
# Prepare the list of build-args
|
||||
build_args = list()
|
||||
build_args.append(f"--build-arg PACKAGE_ARCH={PACKAGE_ARCH}")
|
||||
build_args.append(f"--build-arg DOTNET_ARCH={DOTNET_ARCH}")
|
||||
build_args.append(f"--build-arg IMAGE_ARCH={IMAGE_ARCH}")
|
||||
build_args.append(f"--build-arg TARGET_ARCH={TARGET_ARCH}")
|
||||
build_args.append(f"--build-arg JELLYFIN_VERSION={jellyfin_version}")
|
||||
build_args.append(f"--build-arg CONFIG={'Debug' if debug else 'Release'}")
|
||||
build_args.append("--load")
|
||||
|
||||
# Clean up any existing qemu static image
|
||||
log(
|
||||
f">>> {docker_run_cmd} --privileged linuxserver/qemu-static --reset -p yes"
|
||||
)
|
||||
os.system(
|
||||
f"{docker_run_cmd} --privileged linuxserver/qemu-static --reset -p yes"
|
||||
)
|
||||
log("")
|
||||
# Determine framework versions
|
||||
framework_versions = _determine_framework_versions()
|
||||
for arg in framework_versions.keys():
|
||||
if framework_versions[arg] is not None:
|
||||
build_args.append(f"--build-arg {arg}={framework_versions[arg]}")
|
||||
|
||||
# Prepare the list of build-args
|
||||
build_args = list()
|
||||
build_args.append(f"--build-arg PACKAGE_ARCH={PACKAGE_ARCH}")
|
||||
build_args.append(f"--build-arg DOTNET_ARCH={DOTNET_ARCH}")
|
||||
build_args.append(f"--build-arg IMAGE_ARCH={IMAGE_ARCH}")
|
||||
build_args.append(f"--build-arg TARGET_ARCH={TARGET_ARCH}")
|
||||
build_args.append(f"--build-arg JELLYFIN_VERSION={jellyfin_version}")
|
||||
build_args.append(f"--build-arg CONFIG={'Debug' if debug else 'Release'}")
|
||||
build_args = ' '.join(build_args)
|
||||
|
||||
# Determine framework versions
|
||||
framework_versions = _determine_framework_versions()
|
||||
for arg in framework_versions.keys():
|
||||
if framework_versions[arg] is not None:
|
||||
build_args.append(
|
||||
f"--build-arg {arg}={framework_versions[arg]}"
|
||||
)
|
||||
|
||||
if local:
|
||||
build_args.append("--load")
|
||||
|
||||
build_args = ' '.join(build_args)
|
||||
|
||||
# Build the dockerfile
|
||||
log(
|
||||
f">>> {docker_build_cmd} {build_args} --file {repo_root_dir}/{dockerfile} --tag {imagename} {repo_root_dir}"
|
||||
)
|
||||
ret = os.system(
|
||||
f"{docker_build_cmd} {build_args} --file {repo_root_dir}/{dockerfile} --tag {imagename} {repo_root_dir}"
|
||||
)
|
||||
if ret > 0:
|
||||
exit(1)
|
||||
images_hub.append(imagename)
|
||||
|
||||
if not local:
|
||||
os.system(f"docker image tag {imagename} ghcr.io/{imagename}")
|
||||
images_ghcr.append(f"ghcr.io/{imagename}")
|
||||
|
||||
log("")
|
||||
|
||||
if local:
|
||||
return
|
||||
|
||||
if not getenv('DOCKER_USERNAME') or not getenv('DOCKER_TOKEN'):
|
||||
log("Warning: No DOCKER_USERNAME or DOCKER_TOKEN in environment; skipping manifest build and push (DockerHub and GHCR).")
|
||||
return
|
||||
|
||||
def build_manifests(server, images):
|
||||
# Build the manifests
|
||||
log(f">> Building Docker manifests for {server}...")
|
||||
manifests = list()
|
||||
|
||||
if is_stable or is_preview:
|
||||
log(">>> Building X.Y.Z dated version manifest...")
|
||||
log(
|
||||
f">>>> docker manifest create {server}/{configurations['docker']['imagename']}:{jellyfin_version}.{date} {' '.join(images)}"
|
||||
)
|
||||
os.system(
|
||||
f"docker manifest create {server}/{configurations['docker']['imagename']}:{jellyfin_version}.{date} {' '.join(images)}"
|
||||
)
|
||||
manifests.append(
|
||||
f"{server}/{configurations['docker']['imagename']}:{jellyfin_version}.{date}"
|
||||
)
|
||||
|
||||
log(">>> Building X.Y.Z version manifest...")
|
||||
log(
|
||||
f">>>> docker manifest create {server}/{configurations['docker']['imagename']}:{jellyfin_version} {' '.join(images)}"
|
||||
)
|
||||
os.system(
|
||||
f"docker manifest create {server}/{configurations['docker']['imagename']}:{jellyfin_version} {' '.join(images)}"
|
||||
)
|
||||
manifests.append(f"{server}/{configurations['docker']['imagename']}:{jellyfin_version}")
|
||||
|
||||
if is_stable:
|
||||
# Build major-minor point version
|
||||
log(">>> Building X.Y version manifest...")
|
||||
manifest_version_xy = '.'.join(jellyfin_version.split('.')[0:2])
|
||||
log(
|
||||
f">>>> docker manifest create {server}/{configurations['docker']['imagename']}:{manifest_version_xy} {' '.join(images)}"
|
||||
)
|
||||
os.system(
|
||||
f"docker manifest create {server}/{configurations['docker']['imagename']}:{manifest_version_xy} {' '.join(images)}"
|
||||
)
|
||||
manifests.append(f"{server}/{configurations['docker']['imagename']}:{manifest_version_xy}")
|
||||
|
||||
# Build major-only point version
|
||||
log(">>> Building X version manifest...")
|
||||
manifest_version_x = '.'.join(jellyfin_version.split('.')[0:1])
|
||||
log(
|
||||
f">>>> docker manifest create {server}/{configurations['docker']['imagename']}:{manifest_version_x} {' '.join(images)}"
|
||||
)
|
||||
os.system(
|
||||
f"docker manifest create {server}/{configurations['docker']['imagename']}:{manifest_version_x} {' '.join(images)}"
|
||||
)
|
||||
manifests.append(f"{server}/{configurations['docker']['imagename']}:{manifest_version_x}")
|
||||
|
||||
log(">>> Building latest manifest...")
|
||||
log(
|
||||
f">>>> docker manifest create {server}/{configurations['docker']['imagename']}:latest {' '.join(images)}"
|
||||
)
|
||||
os.system(
|
||||
f"docker manifest create {server}/{configurations['docker']['imagename']}:latest {' '.join(images)}"
|
||||
)
|
||||
manifests.append(f"{server}/{configurations['docker']['imagename']}:latest")
|
||||
elif is_preview:
|
||||
log(">>> Building preview manifest...")
|
||||
log(
|
||||
f">>>> docker manifest create {server}/{configurations['docker']['imagename']}:preview {' '.join(images)}"
|
||||
)
|
||||
os.system(
|
||||
f"docker manifest create {server}/{configurations['docker']['imagename']}:preview {' '.join(images)}"
|
||||
)
|
||||
manifests.append(f"{server}/{configurations['docker']['imagename']}:preview")
|
||||
else:
|
||||
log(">>> Building unstable manifest...")
|
||||
log(
|
||||
f">>>> docker manifest create {server}/{configurations['docker']['imagename']}:unstable {' '.join(images)}"
|
||||
)
|
||||
os.system(
|
||||
f"docker manifest create {server}/{configurations['docker']['imagename']}:unstable {' '.join(images)}"
|
||||
)
|
||||
manifests.append(f"{server}/{configurations['docker']['imagename']}:unstable")
|
||||
|
||||
return manifests
|
||||
|
||||
# Log in to DockerHub
|
||||
os.system(
|
||||
f"docker login -u {getenv('DOCKER_USERNAME')} -p {getenv('DOCKER_TOKEN')} 2>&1"
|
||||
)
|
||||
|
||||
# Push the images to DockerHub
|
||||
for image in images_hub:
|
||||
log(f">>> Pushing image {image} to DockerHub")
|
||||
log(f">>>> docker push {image} 2>&1")
|
||||
os.system(f"docker push {image} 2>&1")
|
||||
|
||||
manifests_hub = build_manifests("docker.io", images_hub)
|
||||
|
||||
# Push the images and manifests to DockerHub
|
||||
for manifest in manifests_hub:
|
||||
log(f">>> Pushing manifest {manifest} to DockerHub")
|
||||
log(f">>>> docker manifest push --purge {manifest} 2>&1")
|
||||
os.system(f"docker manifest push --purge {manifest} 2>&1")
|
||||
|
||||
# Log out of DockerHub
|
||||
os.system("docker logout")
|
||||
|
||||
# Log in to GHCR
|
||||
os.system(
|
||||
f"docker login -u {getenv('GHCR_USERNAME')} -p {getenv('GHCR_TOKEN')} ghcr.io 2>&1"
|
||||
)
|
||||
|
||||
# Push the images to GHCR
|
||||
for image in images_ghcr:
|
||||
log(f">>> Pushing image {image} to GHCR")
|
||||
log(f">>>> docker push {image} 2>&1")
|
||||
os.system(f"docker push {image} 2>&1")
|
||||
|
||||
manifests_ghcr = build_manifests("ghcr.io", images_ghcr)
|
||||
|
||||
# Push the images and manifests to GHCR
|
||||
for manifest in manifests_ghcr:
|
||||
log(f">>> Pushing manifest {manifest} to GHCR")
|
||||
log(f">>>> docker manifest push --purge {manifest} 2>&1")
|
||||
os.system(f"docker manifest push --purge {manifest} 2>&1")
|
||||
|
||||
# Log out of GHCR
|
||||
os.system("docker logout")
|
||||
# Build the dockerfile
|
||||
log(f">>> {docker_build_cmd} {build_args} --file {repo_root_dir}/{dockerfile} --tag {imagename} {repo_root_dir}")
|
||||
ret = os.system(f"{docker_build_cmd} {build_args} --file {repo_root_dir}/{dockerfile} --tag {imagename} {repo_root_dir}")
|
||||
if ret > 0:
|
||||
exit(1)
|
||||
|
||||
|
||||
def build_nuget(
|
||||
@@ -710,7 +527,7 @@ def usage():
|
||||
log(" BUILD_TYPE: The type of build to execute")
|
||||
log(f" * Valid options are: {', '.join(configurations.keys())}")
|
||||
log(" BUILD_ARCH: The CPU architecture of the build")
|
||||
log(" * Valid options are: <empty> [portable/docker only], amd64, arm64")
|
||||
log(" * Valid options are: <empty> [portable only], amd64, arm64")
|
||||
log(" BUILD_VERSION: A valid OS distribution version (.deb build types only)")
|
||||
|
||||
|
||||
@@ -737,7 +554,7 @@ parser.add_argument('jellyfin_version', help='The output version')
|
||||
parser.add_argument('build_type', choices=configurations.keys(), help='The build platform')
|
||||
parser.add_argument('build_arch', default=None, nargs='?', help='The build architecture')
|
||||
parser.add_argument('build_version', default=None, nargs='?', help='The build release version [debian/ubuntu only]')
|
||||
parser.add_argument('--local', action='store_true', help='Local build, do not generate manifests or push them [docker only]')
|
||||
parser.add_argument('--local', action='store_true', help='Local build, do not push packages [nuget only]')
|
||||
parser.add_argument('--debug', action='store_true', help='Debug build, set .NET to use Debug instead of Release')
|
||||
|
||||
args = parser.parse_args()
|
||||
@@ -747,7 +564,7 @@ build_type = args.build_type
|
||||
build_arch = args.build_arch
|
||||
build_version = args.build_version
|
||||
|
||||
if build_type not in ["portable", "docker", "nuget"] and not build_arch:
|
||||
if build_type not in ["portable", "nuget"] and not build_arch:
|
||||
log(f"Error: You must specify an architecture for build platform {build_type}")
|
||||
exit(1)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user