Reformat (Black) and lint (flake8) Python scripts
This commit is contained in:
275
build.py
275
build.py
@@ -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
|
||||||
|
)
|
||||||
|
|||||||
11
checkout.py
11
checkout.py
@@ -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():
|
||||||
|
|||||||
Reference in New Issue
Block a user