Reformat (Black) and lint (flake8) Python scripts

This commit is contained in:
Joshua M. Boniface
2024-02-16 03:00:16 -05:00
parent 33389396a7
commit 6abc19f3d9
2 changed files with 210 additions and 76 deletions

275
build.py
View File

@@ -7,14 +7,11 @@
from datetime import datetime from datetime import datetime
from email.utils import format_datetime, localtime from email.utils import format_datetime, localtime
from os import system
import os.path import os.path
from subprocess import run, PIPE from subprocess import run, PIPE
import sys import sys
from yaml import load, SafeLoader from yaml import load, SafeLoader
from git import Repo
# Determine top level directory of this repository ("jellyfin-packaging") # Determine top level directory of this repository ("jellyfin-packaging")
revparse = run(["git", "rev-parse", "--show-toplevel"], stdout=PIPE) revparse = run(["git", "rev-parse", "--show-toplevel"], stdout=PIPE)
repo_root_dir = revparse.stdout.decode().strip() repo_root_dir = revparse.stdout.decode().strip()
@@ -23,17 +20,46 @@ repo_root_dir = revparse.stdout.decode().strip()
docker_build_cmd = "docker build --progress=plain --no-cache" docker_build_cmd = "docker build --progress=plain --no-cache"
docker_run_cmd = "docker run --rm" docker_run_cmd = "docker run --rm"
# Configuration loader
try:
with open("build.yaml", encoding="utf-8") as fh:
configurations = load(fh, Loader=SafeLoader)
except Exception as e:
print(f"Error: Failed to find 'build.yaml' configuration: {e}")
exit(1)
def build_package_deb(jellyfin_version, build_type, build_arch, build_version): def build_package_deb(jellyfin_version, build_type, build_arch, build_version):
"""
Build a .deb package (Debian or Ubuntu) within a Docker container that matches the requested distribution version
"""
print(f"> Building an {build_arch} {build_type} .deb package...")
print()
try: try:
os_type = build_type if build_type in configurations.keys() else None os_type = build_type if build_type in configurations.keys() else None
if os_type is None: if os_type is None:
raise ValueError(f"{build_type} is not a valid OS type in {configurations.keys()}") raise ValueError(
os_version = configurations[build_type]['releases'][build_version] if build_version in configurations[build_type]['releases'].keys() else None f"{build_type} is not a valid OS type in {configurations.keys()}"
)
os_version = (
configurations[build_type]["releases"][build_version]
if build_version in configurations[build_type]["releases"].keys()
else None
)
if os_version is None: if os_version is None:
raise ValueError(f"{build_version} is not a valid {build_type} version in {configurations[build_type]['releases'].keys()}") raise ValueError(
PACKAGE_ARCH = configurations[build_type]['archmaps'][build_arch]['PACKAGE_ARCH'] if build_arch in configurations[build_type]['archmaps'].keys() else None f"{build_version} is not a valid {build_type} version in {configurations[build_type]['releases'].keys()}"
)
PACKAGE_ARCH = (
configurations[build_type]["archmaps"][build_arch]["PACKAGE_ARCH"]
if build_arch in configurations[build_type]["archmaps"].keys()
else None
)
if PACKAGE_ARCH is None: if PACKAGE_ARCH is None:
raise ValueError(f"{build_arch} is not a valid {build_type} {build_version} architecture in {configurations[build_type]['archmaps'].keys()}") raise ValueError(
f"{build_arch} is not a valid {build_type} {build_version} architecture in {configurations[build_type]['archmaps'].keys()}"
)
except Exception as e: except Exception as e:
print(f"Invalid/unsupported arguments: {e}") print(f"Invalid/unsupported arguments: {e}")
exit(1) exit(1)
@@ -42,7 +68,7 @@ def build_package_deb(jellyfin_version, build_type, build_arch, build_version):
dockerfile = configurations[build_type]["dockerfile"] dockerfile = configurations[build_type]["dockerfile"]
# Set the cross-gcc version # Set the cross-gcc version
crossgccvers = configurations[build_type]['cross-gcc'][build_version] crossgccvers = configurations[build_type]["cross-gcc"][build_version]
# Prepare the debian changelog file # Prepare the debian changelog file
changelog_src = f"{repo_root_dir}/debian/changelog.in" changelog_src = f"{repo_root_dir}/debian/changelog.in"
@@ -55,13 +81,13 @@ def build_package_deb(jellyfin_version, build_type, build_arch, build_version):
comment = f"Jellyfin release {jellyfin_version}, see https://github.com/jellyfin/jellyfin/releases/{jellyfin_version} for details." comment = f"Jellyfin release {jellyfin_version}, see https://github.com/jellyfin/jellyfin/releases/{jellyfin_version} for details."
else: else:
comment = f"Jellyin unstable release {jellyfin_version}." comment = f"Jellyin unstable release {jellyfin_version}."
jellyfin_version = jellyfin_version.replace('v', '') jellyfin_version = jellyfin_version.replace("v", "")
changelog = changelog.format( changelog = changelog.format(
package_version=jellyfin_version, package_version=jellyfin_version,
package_build=f"{build_type[:3]}{os_version.replace('.', '')}", package_build=f"{build_type[:3]}{os_version.replace('.', '')}",
release_comment=comment, release_comment=comment,
release_date=format_datetime(localtime()) release_date=format_datetime(localtime()),
) )
with open(changelog_dst, "w") as fh: with open(changelog_dst, "w") as fh:
@@ -71,25 +97,47 @@ def build_package_deb(jellyfin_version, build_type, build_arch, build_version):
imagename = f"{configurations[build_type]['imagename']}-{jellyfin_version}_{build_arch}-{build_type}-{build_version}" imagename = f"{configurations[build_type]['imagename']}-{jellyfin_version}_{build_arch}-{build_type}-{build_version}"
# Build the dockerfile and packages # Build the dockerfile and packages
os.system(f"{docker_build_cmd} --build-arg PACKAGE_TYPE={os_type} --build-arg PACKAGE_VERSION={os_version} --build-arg PACKAGE_ARCH={PACKAGE_ARCH} --build-arg GCC_VERSION={crossgccvers} --file {repo_root_dir}/{dockerfile} --tag {imagename} {repo_root_dir}") os.system(
os.system(f"{docker_run_cmd} --volume {repo_root_dir}:/jellyfin --volume {repo_root_dir}/out/{build_type}:/dist --env JELLYFIN_VERSION={jellyfin_version} --name {imagename} {imagename}") f"{docker_build_cmd} --build-arg PACKAGE_TYPE={os_type} --build-arg PACKAGE_VERSION={os_version} --build-arg PACKAGE_ARCH={PACKAGE_ARCH} --build-arg GCC_VERSION={crossgccvers} --file {repo_root_dir}/{dockerfile} --tag {imagename} {repo_root_dir}"
)
os.system(
f"{docker_run_cmd} --volume {repo_root_dir}:/jellyfin --volume {repo_root_dir}/out/{build_type}:/dist --env JELLYFIN_VERSION={jellyfin_version} --name {imagename} {imagename}"
)
def build_package_rpm(jellyfin_version, build_type, build_arch, build_version): def build_package_rpm(jellyfin_version, build_type, build_arch, build_version):
"""
Build a .rpm package (Fedora or CentOS) within a Docker container that matches the requested distribution version
"""
print(f"> Building an {build_arch} {build_type} .rpm package...")
print()
pass pass
def build_linux(jellyfin_version, build_type, build_arch, _build_version): def build_linux(jellyfin_version, build_type, build_arch, _build_version):
"""
Build a portable Linux archive
"""
print(f"> Building a portable {build_arch} Linux archive...")
print()
try: try:
PACKAGE_ARCH = configurations[build_type]['archmaps'][build_arch]['PACKAGE_ARCH'] if build_arch in configurations[build_type]['archmaps'].keys() else None PACKAGE_ARCH = (
configurations[build_type]["archmaps"][build_arch]["PACKAGE_ARCH"]
if build_arch in configurations[build_type]["archmaps"].keys()
else None
)
if PACKAGE_ARCH is None: if PACKAGE_ARCH is None:
raise ValueError(f"{build_arch} is not a valid {build_type} {build_version} architecture in {configurations[build_type]['archmaps'].keys()}") raise ValueError(
DOTNET_ARCH = configurations[build_type]['archmaps'][build_arch]['DOTNET_ARCH'] f"{build_arch} is not a valid {build_type} {build_version} architecture in {configurations[build_type]['archmaps'].keys()}"
)
DOTNET_ARCH = configurations[build_type]["archmaps"][build_arch]["DOTNET_ARCH"]
except Exception as e: except Exception as e:
print(f"Invalid/unsupported arguments: {e}") print(f"Invalid/unsupported arguments: {e}")
exit(1) exit(1)
jellyfin_version = jellyfin_version.replace('v', '') jellyfin_version = jellyfin_version.replace("v", "")
# Set the dockerfile # Set the dockerfile
dockerfile = configurations[build_type]["dockerfile"] dockerfile = configurations[build_type]["dockerfile"]
@@ -101,21 +149,37 @@ def build_linux(jellyfin_version, build_type, build_arch, _build_version):
archivetypes = f"{configurations[build_type]['archivetypes']}" archivetypes = f"{configurations[build_type]['archivetypes']}"
# Build the dockerfile and packages # Build the dockerfile and packages
os.system(f"{docker_build_cmd} --file {repo_root_dir}/{dockerfile} --tag {imagename} {repo_root_dir}") os.system(
os.system(f"{docker_run_cmd} --volume {repo_root_dir}:/jellyfin --volume {repo_root_dir}/out/{build_type}:/dist --env JELLYFIN_VERSION={jellyfin_version} --env BUILD_TYPE={build_type} --env PACKAGE_ARCH={PACKAGE_ARCH} --env DOTNET_TYPE=linux --env DOTNET_ARCH={DOTNET_ARCH} --env ARCHIVE_TYPES={archivetypes} --name {imagename} {imagename}") f"{docker_build_cmd} --file {repo_root_dir}/{dockerfile} --tag {imagename} {repo_root_dir}"
)
os.system(
f"{docker_run_cmd} --volume {repo_root_dir}:/jellyfin --volume {repo_root_dir}/out/{build_type}:/dist --env JELLYFIN_VERSION={jellyfin_version} --env BUILD_TYPE={build_type} --env PACKAGE_ARCH={PACKAGE_ARCH} --env DOTNET_TYPE=linux --env DOTNET_ARCH={DOTNET_ARCH} --env ARCHIVE_TYPES={archivetypes} --name {imagename} {imagename}"
)
def build_windows(jellyfin_version, build_type, _build_arch, _build_version): def build_windows(jellyfin_version, build_type, _build_arch, _build_version):
"""
Build a portable Windows archive
"""
print(f"> Building a portable {build_arch} Windows archive...")
print()
try: try:
PACKAGE_ARCH = configurations[build_type]['archmaps'][build_arch]['PACKAGE_ARCH'] if build_arch in configurations[build_type]['archmaps'].keys() else None PACKAGE_ARCH = (
configurations[build_type]["archmaps"][build_arch]["PACKAGE_ARCH"]
if build_arch in configurations[build_type]["archmaps"].keys()
else None
)
if PACKAGE_ARCH is None: if PACKAGE_ARCH is None:
raise ValueError(f"{build_arch} is not a valid {build_type} {build_version} architecture in {configurations[build_type]['archmaps'].keys()}") raise ValueError(
DOTNET_ARCH = configurations[build_type]['archmaps'][build_arch]['DOTNET_ARCH'] f"{build_arch} is not a valid {build_type} {build_version} architecture in {configurations[build_type]['archmaps'].keys()}"
)
DOTNET_ARCH = configurations[build_type]["archmaps"][build_arch]["DOTNET_ARCH"]
except Exception as e: except Exception as e:
print(f"Invalid/unsupported arguments: {e}") print(f"Invalid/unsupported arguments: {e}")
exit(1) exit(1)
jellyfin_version = jellyfin_version.replace('v', '') jellyfin_version = jellyfin_version.replace("v", "")
# Set the dockerfile # Set the dockerfile
dockerfile = configurations[build_type]["dockerfile"] dockerfile = configurations[build_type]["dockerfile"]
@@ -127,21 +191,37 @@ def build_windows(jellyfin_version, build_type, _build_arch, _build_version):
archivetypes = f"{configurations[build_type]['archivetypes']}" archivetypes = f"{configurations[build_type]['archivetypes']}"
# Build the dockerfile and packages # Build the dockerfile and packages
os.system(f"{docker_build_cmd} --file {repo_root_dir}/{dockerfile} --tag {imagename} {repo_root_dir}") os.system(
os.system(f"{docker_run_cmd} --volume {repo_root_dir}:/jellyfin --volume {repo_root_dir}/out/{build_type}:/dist --env JELLYFIN_VERSION={jellyfin_version} --env BUILD_TYPE={build_type} --env PACKAGE_ARCH={PACKAGE_ARCH} --env DOTNET_TYPE=win --env DOTNET_ARCH={DOTNET_ARCH} --env ARCHIVE_TYPES={archivetypes} --name {imagename} {imagename}") f"{docker_build_cmd} --file {repo_root_dir}/{dockerfile} --tag {imagename} {repo_root_dir}"
)
os.system(
f"{docker_run_cmd} --volume {repo_root_dir}:/jellyfin --volume {repo_root_dir}/out/{build_type}:/dist --env JELLYFIN_VERSION={jellyfin_version} --env BUILD_TYPE={build_type} --env PACKAGE_ARCH={PACKAGE_ARCH} --env DOTNET_TYPE=win --env DOTNET_ARCH={DOTNET_ARCH} --env ARCHIVE_TYPES={archivetypes} --name {imagename} {imagename}"
)
def build_macos(jellyfin_version, build_type, build_arch, _build_version): def build_macos(jellyfin_version, build_type, build_arch, _build_version):
"""
Build a portable MacOS archive
"""
print(f"> Building a portable {build_arch} MacOS archive...")
print()
try: try:
PACKAGE_ARCH = configurations[build_type]['archmaps'][build_arch]['PACKAGE_ARCH'] if build_arch in configurations[build_type]['archmaps'].keys() else None PACKAGE_ARCH = (
configurations[build_type]["archmaps"][build_arch]["PACKAGE_ARCH"]
if build_arch in configurations[build_type]["archmaps"].keys()
else None
)
if PACKAGE_ARCH is None: if PACKAGE_ARCH is None:
raise ValueError(f"{build_arch} is not a valid {build_type} {build_version} architecture in {configurations[build_type]['archmaps'].keys()}") raise ValueError(
DOTNET_ARCH = configurations[build_type]['archmaps'][build_arch]['DOTNET_ARCH'] f"{build_arch} is not a valid {build_type} {build_version} architecture in {configurations[build_type]['archmaps'].keys()}"
)
DOTNET_ARCH = configurations[build_type]["archmaps"][build_arch]["DOTNET_ARCH"]
except Exception as e: except Exception as e:
print(f"Invalid/unsupported arguments: {e}") print(f"Invalid/unsupported arguments: {e}")
exit(1) exit(1)
jellyfin_version = jellyfin_version.replace('v', '') jellyfin_version = jellyfin_version.replace("v", "")
# Set the dockerfile # Set the dockerfile
dockerfile = configurations[build_type]["dockerfile"] dockerfile = configurations[build_type]["dockerfile"]
@@ -153,33 +233,52 @@ def build_macos(jellyfin_version, build_type, build_arch, _build_version):
archivetypes = f"{configurations[build_type]['archivetypes']}" archivetypes = f"{configurations[build_type]['archivetypes']}"
# Build the dockerfile and packages # Build the dockerfile and packages
os.system(f"{docker_build_cmd} --file {repo_root_dir}/{dockerfile} --tag {imagename} {repo_root_dir}") os.system(
os.system(f"{docker_run_cmd} --volume {repo_root_dir}:/jellyfin --volume {repo_root_dir}/out/{build_type}:/dist --env JELLYFIN_VERSION={jellyfin_version} --env BUILD_TYPE={build_type} --env PACKAGE_ARCH={PACKAGE_ARCH} --env DOTNET_TYPE=osx --env DOTNET_ARCH={DOTNET_ARCH} --env ARCHIVE_TYPES={archivetypes} --name {imagename} {imagename}") f"{docker_build_cmd} --file {repo_root_dir}/{dockerfile} --tag {imagename} {repo_root_dir}"
)
os.system(
f"{docker_run_cmd} --volume {repo_root_dir}:/jellyfin --volume {repo_root_dir}/out/{build_type}:/dist --env JELLYFIN_VERSION={jellyfin_version} --env BUILD_TYPE={build_type} --env PACKAGE_ARCH={PACKAGE_ARCH} --env DOTNET_TYPE=osx --env DOTNET_ARCH={DOTNET_ARCH} --env ARCHIVE_TYPES={archivetypes} --name {imagename} {imagename}"
)
def build_portable(jellyfin_version, build_type, _build_arch, _build_version): def build_portable(jellyfin_version, build_type, _build_arch, _build_version):
jellyfin_version = jellyfin_version.replace('v', '') """
Build a portable .NET archive
"""
print("> Building a portable .NET archive...")
print()
jellyfin_version = jellyfin_version.replace("v", "")
# Set the dockerfile # Set the dockerfile
dockerfile = configurations[build_type]["dockerfile"] dockerfile = configurations[build_type]["dockerfile"]
# Use a unique docker image name for consistency # Use a unique docker image name for consistency
imagename = f"{configurations[build_type]['imagename']}-{jellyfin_version}_{build_type}" imagename = (
f"{configurations[build_type]['imagename']}-{jellyfin_version}_{build_type}"
)
# Set the archive type (tar-gz or zip) # Set the archive type (tar-gz or zip)
archivetypes = f"{configurations[build_type]['archivetypes']}" archivetypes = f"{configurations[build_type]['archivetypes']}"
# Build the dockerfile and packages # Build the dockerfile and packages
os.system(f"{docker_build_cmd} --file {repo_root_dir}/{dockerfile} --tag {imagename} {repo_root_dir}") os.system(
os.system(f"{docker_run_cmd} --volume {repo_root_dir}:/jellyfin --volume {repo_root_dir}/out/{build_type}:/dist --env JELLYFIN_VERSION={jellyfin_version} --env BUILD_TYPE={build_type} --env ARCHIVE_TYPES={archivetypes} --name {imagename} {imagename}") f"{docker_build_cmd} --file {repo_root_dir}/{dockerfile} --tag {imagename} {repo_root_dir}"
)
os.system(
f"{docker_run_cmd} --volume {repo_root_dir}:/jellyfin --volume {repo_root_dir}/out/{build_type}:/dist --env JELLYFIN_VERSION={jellyfin_version} --env BUILD_TYPE={build_type} --env ARCHIVE_TYPES={archivetypes} --name {imagename} {imagename}"
)
def build_docker(jellyfin_version, build_type, _build_arch, _build_version): def build_docker(jellyfin_version, build_type, _build_arch, _build_version):
"""
Build Docker images for all architectures and combining manifests
"""
print("> Building Docker images...") print("> Building Docker images...")
print() print()
# We build all architectures simultaneously to push a single tag, so no conditional checks # We build all architectures simultaneously to push a single tag, so no conditional checks
architectures = configurations['docker']['archmaps'].keys() architectures = configurations["docker"]["archmaps"].keys()
# Set the dockerfile # Set the dockerfile
dockerfile = configurations[build_type]["dockerfile"] dockerfile = configurations[build_type]["dockerfile"]
@@ -192,7 +291,7 @@ def build_docker(jellyfin_version, build_type, _build_arch, _build_version):
is_latest = False is_latest = False
version_suffix = False version_suffix = False
jellyfin_version = jellyfin_version.replace('v', '') jellyfin_version = jellyfin_version.replace("v", "")
# Set today's date in a convenient format for use as an image suffix # Set today's date in a convenient format for use as an image suffix
date = datetime.now().strftime("%Y%m%d-%H%M%S") date = datetime.now().strftime("%Y%m%d-%H%M%S")
@@ -203,10 +302,10 @@ def build_docker(jellyfin_version, build_type, _build_arch, _build_version):
print() print()
# Get our ARCH variables from the archmaps # Get our ARCH variables from the archmaps
PACKAGE_ARCH = configurations['docker']['archmaps'][_build_arch]['PACKAGE_ARCH'] PACKAGE_ARCH = configurations["docker"]["archmaps"][_build_arch]["PACKAGE_ARCH"]
DOTNET_ARCH = configurations['docker']['archmaps'][_build_arch]['DOTNET_ARCH'] DOTNET_ARCH = configurations["docker"]["archmaps"][_build_arch]["DOTNET_ARCH"]
QEMU_ARCH = configurations['docker']['archmaps'][_build_arch]['QEMU_ARCH'] QEMU_ARCH = configurations["docker"]["archmaps"][_build_arch]["QEMU_ARCH"]
IMAGE_ARCH = configurations['docker']['archmaps'][_build_arch]['IMAGE_ARCH'] IMAGE_ARCH = configurations["docker"]["archmaps"][_build_arch]["IMAGE_ARCH"]
# Use a unique docker image name for consistency # Use a unique docker image name for consistency
if version_suffix: if version_suffix:
@@ -215,31 +314,43 @@ def build_docker(jellyfin_version, build_type, _build_arch, _build_version):
imagename = f"{configurations['docker']['imagename']}:{jellyfin_version}-{_build_arch}" imagename = f"{configurations['docker']['imagename']}:{jellyfin_version}-{_build_arch}"
# Clean up any existing qemu static image # Clean up any existing qemu static image
os.system(f"{docker_run_cmd} --privileged multiarch/qemu-user-static:register --reset") os.system(
f"{docker_run_cmd} --privileged multiarch/qemu-user-static:register --reset"
)
print() print()
# Build the dockerfile # Build the dockerfile
os.system(f"{docker_build_cmd} --build-arg PACKAGE_ARCH={PACKAGE_ARCH} --build-arg DOTNET_ARCH={DOTNET_ARCH} --build-arg QEMU_ARCH={QEMU_ARCH} --build-arg IMAGE_ARCH={IMAGE_ARCH} --build-arg JELLYFIN_VERSION={jellyfin_version} --file {repo_root_dir}/{dockerfile} --tag {imagename} {repo_root_dir}") os.system(
f"{docker_build_cmd} --build-arg PACKAGE_ARCH={PACKAGE_ARCH} --build-arg DOTNET_ARCH={DOTNET_ARCH} --build-arg QEMU_ARCH={QEMU_ARCH} --build-arg IMAGE_ARCH={IMAGE_ARCH} --build-arg JELLYFIN_VERSION={jellyfin_version} --file {repo_root_dir}/{dockerfile} --tag {imagename} {repo_root_dir}"
)
images.append(imagename) images.append(imagename)
print() print()
# Build the manifests # Build the manifests
print(f">> Building Docker manifests...") print(">> Building Docker manifests...")
manifests = list() manifests = list()
if version_suffix: if version_suffix:
print(f">>> Building dated version manifest...") print(">>> Building dated version manifest...")
os.system(f"docker manifest create --amend {configurations['docker']['imagename']}:{jellyfin_version}.{date} {' '.join(images)}") os.system(
manifests.append(f"{configurations['docker']['imagename']}:{jellyfin_version}.{date}") f"docker manifest create --amend {configurations['docker']['imagename']}:{jellyfin_version}.{date} {' '.join(images)}"
)
manifests.append(
f"{configurations['docker']['imagename']}:{jellyfin_version}.{date}"
)
print(f">>> Building version manifest...") print(">>> Building version manifest...")
os.system(f"docker manifest create --amend {configurations['docker']['imagename']}:{jellyfin_version} {' '.join(images)}") os.system(
f"docker manifest create --amend {configurations['docker']['imagename']}:{jellyfin_version} {' '.join(images)}"
)
manifests.append(f"{configurations['docker']['imagename']}:{jellyfin_version}") manifests.append(f"{configurations['docker']['imagename']}:{jellyfin_version}")
if is_latest: if is_latest:
print(f">>> Building latest manifest...") print(">>> Building latest manifest...")
os.system(f"docker manifest create --amend {configurations['docker']['imagename']}:latest {' '.join(images)}") os.system(
f"docker manifest create --amend {configurations['docker']['imagename']}:latest {' '.join(images)}"
)
manifests.append(f"{configurations['docker']['imagename']}:latest") manifests.append(f"{configurations['docker']['imagename']}:latest")
# Push the images and manifests to DockerHub (we are already logged in from GH Actions) # Push the images and manifests to DockerHub (we are already logged in from GH Actions)
@@ -255,7 +366,28 @@ def build_docker(jellyfin_version, build_type, _build_arch, _build_version):
os.system(f"docker manifest push --purge ghcr.io/{manifest}") os.system(f"docker manifest push --purge ghcr.io/{manifest}")
# Define a map of possible configurations def usage():
"""
Print usage information on error
"""
print(f"{sys.argv[0]} JELLYFIN_VERSION BUILD_TYPE [BUILD_ARCH] [BUILD_VERSION]")
print(" JELLYFIN_VERSION: The Jellyfin version being built")
print(" * Stable releases should be tag names with a 'v' e.g. v10.9.0")
print(
" * Unstable releases should be 'master' or a date-to-the-hour version e.g. 2024021600"
)
print(" BUILD_TYPE: The type of build to execute")
print(f" * Valid options are: {', '.join(configurations.keys())}")
print(" BUILD_ARCH: The CPU architecture of the build")
print(
" * Valid options are: <empty> [portable/docker only], amd64, arm64, armhf"
)
print(
" BUILD_VERSION: A valid OS distribution version (.deb/.rpm build types only)"
)
# Define a map of possible build functions from the YAML configuration
function_definitions = { function_definitions = {
"build_package_deb": build_package_deb, "build_package_deb": build_package_deb,
"build_package_rpm": build_package_rpm, "build_package_rpm": build_package_rpm,
@@ -267,50 +399,51 @@ function_definitions = {
"build_docker": build_docker, "build_docker": build_docker,
} }
def usage():
print(f"{sys.argv[0]} JELLYFIN_VERSION BUILD_TYPE [BUILD_ARCH] [BUILD_VERSION]")
print(f" JELLYFIN_VERSION: The Jellyfin version being built; stable releases should be tag names with a 'v' e.g. v10.9.0")
print(f" BUILD_TYPE: A valid build OS type (debian, ubuntu, fedora, centos, docker, portable, linux, windows, macos)")
print(f" BUILD_ARCH: A valid build OS CPU architecture (empty [portable/docker], amd64, arm64, or armhf)")
print(f" BUILD_VERSION: A valid build OS version (packaged OS types only)")
try:
with open("build.yaml") as fh:
configurations = load(fh, Loader=SafeLoader)
except Exception as e:
print(f"Error: Failed to find 'build.yaml' configuration: {e}")
exit(1)
try: try:
jellyfin_version = sys.argv[1] jellyfin_version = sys.argv[1]
build_type = sys.argv[2] build_type = sys.argv[2]
except IndexError: except IndexError:
print("Error: Missing required arguments ('JELLYFIN_VERSION' and/or 'BUILD_TYPE')")
print()
usage() usage()
exit(1) exit(1)
if build_type not in configurations.keys(): if build_type not in configurations.keys():
print(f"Error: The specified build type {build_type} is not valid: choices are: {', '.join(configurations.keys())}") print(f"Error: The specified build type '{build_type}' is not valid")
print()
usage()
exit(1) exit(1)
try: try:
if configurations[build_type]['build_function'] not in function_definitions.keys(): if configurations[build_type]["build_function"] not in function_definitions.keys():
raise ValueError raise ValueError
except Exception: except Exception:
print(f"Error: The specified build type {build_type} does not define a valid build function in this script.") print(
f"Error: The specified valid build type '{build_type}' does not define a valid build function"
)
print(
"This is a misconfiguration of the YAML or the build script; please report a bug!"
)
exit(1) exit(1)
# Optional argument (only required for some build functions)
try: try:
build_arch = sys.argv[3] build_arch = sys.argv[3]
except IndexError: except IndexError:
build_arch = None build_arch = None
# Optional argument (only required for some build functions)
try: try:
build_version = sys.argv[4] build_version = sys.argv[4]
except IndexError: except IndexError:
build_version = None build_version = None
# Autocorrect "master" to a dated version string
if jellyfin_version == "master": if jellyfin_version == "master":
jellyfin_version = datetime.now().strftime("%Y%m%d%H") jellyfin_version = datetime.now().strftime("%Y%m%d%H")
print(f"Autocorrecting 'master' version to {jellyfin_version}") print(f"NOTE: Autocorrecting 'master' version to {jellyfin_version}")
function_definitions[configurations[build_type]['build_function']](jellyfin_version, build_type, build_arch, build_version) # Launch the builder function
function_definitions[configurations[build_type]["build_function"]](
jellyfin_version, build_type, build_arch, build_version
)

View File

@@ -5,7 +5,6 @@
# Part of the Jellyfin CI system # Part of the Jellyfin CI system
############################################################################### ###############################################################################
import os.path
from subprocess import run, PIPE from subprocess import run, PIPE
import sys import sys
@@ -36,10 +35,12 @@ for submodule in this_repo.submodules:
# Validate that the provided tag is valid; if not, fall back to "master" # Validate that the provided tag is valid; if not, fall back to "master"
if target_release != "master": if target_release != "master":
if ( if (
target_release not in submodules["jellyfin-server"].tags or target_release not in submodules["jellyfin-server"].tags
target_release not in submodules["jellyfin-web"].tags or target_release not in submodules["jellyfin-web"].tags
): ):
print(f"WARNING: Provided tag {target_release} is not a valid tag for both jellyfin-server and jellyfin-web; using master instead") print(
f"WARNING: Provided tag {target_release} is not a valid tag for both jellyfin-server and jellyfin-web; using master instead"
)
target_release = "master" target_release = "master"
for submodule in submodules.keys(): for submodule in submodules.keys():