2019-02-02 08:13:06 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
import os, sys, yaml, json, subprocess, datetime
|
|
|
|
|
2019-02-03 05:04:08 +00:00
|
|
|
import manifest
|
|
|
|
|
|
|
|
cwd = os.getcwd()
|
|
|
|
|
2019-03-07 04:47:55 +00:00
|
|
|
def run_os_command(command, environment=None, shell=False):
|
|
|
|
if shell:
|
|
|
|
cmd = command
|
|
|
|
else:
|
|
|
|
cmd = command.split()
|
|
|
|
|
2019-02-09 00:16:41 +00:00
|
|
|
try:
|
|
|
|
command_output = subprocess.run(
|
2019-03-07 04:47:55 +00:00
|
|
|
cmd,
|
2019-02-09 00:16:41 +00:00
|
|
|
env=environment,
|
|
|
|
stdout=subprocess.PIPE,
|
|
|
|
stderr=subprocess.PIPE,
|
2019-03-07 04:47:55 +00:00
|
|
|
shell=shell
|
2019-02-09 00:16:41 +00:00
|
|
|
)
|
|
|
|
except Exception as e:
|
|
|
|
print(e)
|
|
|
|
print(command_output)
|
|
|
|
|
|
|
|
return command_output.stdout.decode('utf8'), command_output.stderr.decode('utf8'), command_output.returncode
|
2019-02-02 08:13:06 +00:00
|
|
|
|
|
|
|
def build_plugin(project):
|
|
|
|
# Schema:
|
|
|
|
# build_type: dotnet|docker|script
|
|
|
|
# dotnet_runtime: the runtime for dotnet builds
|
|
|
|
# dotnet_configuration: the configuration for dotnet builds
|
|
|
|
# dotnet_framework: the framework for dotnet builds
|
|
|
|
# docker_file: the Dockerfile for docker builds
|
|
|
|
# script_path: the path for script builds
|
|
|
|
|
|
|
|
# Extract our name and type
|
|
|
|
project_name = project['name']
|
|
|
|
project_type = project['type']
|
|
|
|
# Set out the directories
|
2019-02-03 05:04:08 +00:00
|
|
|
type_dir = "{}/projects/{}".format(cwd, project_type)
|
|
|
|
project_dir = "{}/projects/{}/{}".format(cwd, project_type, project_name)
|
2019-02-02 08:13:06 +00:00
|
|
|
# Check if a build configuration exists and load it
|
2019-02-03 05:04:08 +00:00
|
|
|
manifest_file = '{}/build.yaml'.format(project_dir)
|
2019-02-02 08:13:06 +00:00
|
|
|
if not os.path.exists(manifest_file):
|
|
|
|
print("ERROR: Project {} does not contain a valid 'build.yaml' file.".format(project['name']))
|
|
|
|
return False
|
2019-02-03 05:04:08 +00:00
|
|
|
build_cfg = manifest.load_manifest(manifest_file)
|
2019-02-02 08:13:06 +00:00
|
|
|
|
2020-03-08 15:51:23 +00:00
|
|
|
project_version = "{}.0.0.0".format(build_cfg['version'])
|
2019-02-02 08:13:06 +00:00
|
|
|
|
|
|
|
# move into the project directory
|
|
|
|
revdir = os.getcwd()
|
|
|
|
os.chdir(project_dir)
|
|
|
|
|
|
|
|
if build_cfg['build_type'] == 'dotnet':
|
2019-08-03 20:04:43 +00:00
|
|
|
restore_command = "dotnet restore --no-cache"
|
|
|
|
stdout, stderr, retcode = run_os_command(restore_command)
|
2019-11-03 20:47:32 +00:00
|
|
|
if retcode:
|
|
|
|
print(stdout)
|
|
|
|
print(stderr)
|
|
|
|
exit(1)
|
2019-08-03 20:04:43 +00:00
|
|
|
|
2019-12-15 07:47:49 +00:00
|
|
|
build_command = "dotnet publish --configuration {} --framework {} --output ./bin/".format(
|
2019-02-02 08:13:06 +00:00
|
|
|
build_cfg['dotnet_configuration'],
|
|
|
|
build_cfg['dotnet_framework']
|
|
|
|
)
|
2019-04-26 03:24:00 +00:00
|
|
|
stdout, stderr, retcode = run_os_command(build_command)
|
2019-11-03 20:47:32 +00:00
|
|
|
if retcode:
|
|
|
|
print(stdout)
|
|
|
|
print(stderr)
|
|
|
|
exit(1)
|
2019-12-15 07:47:49 +00:00
|
|
|
print(stdout)
|
2019-04-05 03:03:50 +00:00
|
|
|
elif build_cfg['build_type'] == 'build.py':
|
|
|
|
build_command = "python3 build.py"
|
2019-04-26 03:08:56 +00:00
|
|
|
stdout, stderr, retcode = run_os_command(build_command)
|
2019-11-03 20:47:32 +00:00
|
|
|
if retcode:
|
|
|
|
print(stdout)
|
|
|
|
print(stderr)
|
|
|
|
exit(1)
|
2019-02-02 08:13:06 +00:00
|
|
|
else:
|
|
|
|
print("ERROR: Unsupported build type.")
|
|
|
|
return False
|
|
|
|
|
2019-02-10 23:22:20 +00:00
|
|
|
raw_bin_dir = "{}/bin".format(project_dir)
|
|
|
|
os.chdir(raw_bin_dir)
|
|
|
|
|
|
|
|
# Get a sensible name
|
|
|
|
new_name = "{}_{}.zip".format(project_name, project_version)
|
|
|
|
# Move out the artifacts
|
|
|
|
artifacts_list = list()
|
|
|
|
for artifact in build_cfg['artifacts']:
|
|
|
|
artifacts_list.append("{}".format(artifact))
|
|
|
|
stdout, stderr, retcode = run_os_command("zip {} {}".format(new_name, ' '.join(artifacts_list)))
|
|
|
|
if retcode:
|
2020-02-15 18:42:13 +00:00
|
|
|
print('Could not archive artifacts: {}'.format(stdout))
|
2019-02-10 23:22:20 +00:00
|
|
|
return False
|
|
|
|
|
2019-02-02 08:13:06 +00:00
|
|
|
# Move back to the previous directory
|
|
|
|
os.chdir(revdir)
|
|
|
|
|
|
|
|
# Collect artifacts
|
|
|
|
src_dir = "{}/bin".format(project_dir)
|
2019-04-25 23:25:56 +00:00
|
|
|
target_dir = "./bin/plugin/{}".format(project_name)
|
2019-02-02 08:13:06 +00:00
|
|
|
# Make the type dir if it doesn't exist
|
|
|
|
if not os.path.isdir(target_dir):
|
|
|
|
os.makedirs(target_dir)
|
|
|
|
|
2019-02-10 23:22:20 +00:00
|
|
|
stdout, stderr, retcode = run_os_command("mv {}/{} {}/".format(src_dir, new_name, target_dir))
|
2019-02-02 08:13:06 +00:00
|
|
|
if retcode:
|
2019-02-10 23:22:20 +00:00
|
|
|
print('Could not move archive: {}'.format(stderr))
|
2019-02-02 08:13:06 +00:00
|
|
|
return False
|
|
|
|
|
2019-02-10 22:57:52 +00:00
|
|
|
# Remove build junk
|
|
|
|
run_os_command("rm -rf {}".format(src_dir))
|
|
|
|
|
2019-02-02 08:13:06 +00:00
|
|
|
bin_md5sum = run_os_command("md5sum {}/{}".format(target_dir, new_name))[0].split()[0]
|
|
|
|
|
2020-03-14 23:33:31 +00:00
|
|
|
generate_plugin_manifest(project, build_cfg, bin_md5sum, project_version)
|
2019-02-02 08:13:06 +00:00
|
|
|
|
|
|
|
return True
|
|
|
|
|
2020-03-14 23:33:31 +00:00
|
|
|
def generate_plugin_manifest(project, build_cfg, bin_md5sum, project_version):
|
2019-02-02 08:13:06 +00:00
|
|
|
# Extract our name, type, and plugin_id
|
|
|
|
project_name = project['name']
|
2019-02-09 00:16:41 +00:00
|
|
|
project_plugin_guid = build_cfg['guid']
|
|
|
|
project_plugin_overview = build_cfg['overview']
|
|
|
|
project_plugin_description = build_cfg['description']
|
|
|
|
project_plugin_category = build_cfg['category']
|
2019-03-12 04:40:07 +00:00
|
|
|
project_plugin_owner = build_cfg['owner']
|
2019-02-02 08:13:06 +00:00
|
|
|
|
2020-05-24 07:54:37 +00:00
|
|
|
target_abi = build_cfg['targetAbi']
|
2019-04-05 03:03:50 +00:00
|
|
|
|
2019-02-02 08:13:06 +00:00
|
|
|
build_date = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
|
|
|
2019-04-25 23:25:56 +00:00
|
|
|
target_dir = "./bin/plugin/{}".format(project_name)
|
2019-04-05 03:03:50 +00:00
|
|
|
manifest_fragment_file_name = "{}/{}.manifest.json".format(target_dir, project_name)
|
|
|
|
|
|
|
|
plugin_manifest_versions = list()
|
|
|
|
plugin_manifest_existing_version_fragments = list()
|
|
|
|
if os.path.isfile(manifest_fragment_file_name):
|
|
|
|
with open(manifest_fragment_file_name, 'r') as manifest_fragment_file:
|
|
|
|
old_config = json.load(manifest_fragment_file)
|
|
|
|
for version in old_config['versions']:
|
|
|
|
if version['versionStr'] != project_version:
|
|
|
|
plugin_manifest_existing_version_fragments.append(version)
|
|
|
|
|
|
|
|
plugin_manifest_new_version_fragment = [{
|
2020-05-24 07:54:37 +00:00
|
|
|
"version": project_version,
|
|
|
|
"changelog": "changelog",
|
|
|
|
"targetAbi": target_abi,
|
2019-04-05 03:03:50 +00:00
|
|
|
"sourceUrl": "https://repo.jellyfin.org/releases/plugin/{0}/{0}_{1}.zip".format(project_name, project_version),
|
|
|
|
"checksum": bin_md5sum,
|
2020-05-24 07:54:37 +00:00
|
|
|
"timestamp": build_date
|
2019-04-05 03:03:50 +00:00
|
|
|
}]
|
|
|
|
plugin_manifest_versions = plugin_manifest_new_version_fragment + plugin_manifest_existing_version_fragments
|
|
|
|
|
2019-02-02 08:13:06 +00:00
|
|
|
plugin_manifest_fragment = {
|
2020-05-24 07:54:37 +00:00
|
|
|
"guid": project_plugin_guid,
|
2019-02-02 08:13:06 +00:00
|
|
|
"name": project_plugin_nicename,
|
2020-05-24 07:54:37 +00:00
|
|
|
"description": project_plugin_description,
|
2019-02-02 08:13:06 +00:00
|
|
|
"overview": project_plugin_overview,
|
2019-03-12 04:40:07 +00:00
|
|
|
"owner": project_plugin_owner,
|
2019-02-02 08:13:06 +00:00
|
|
|
"category": project_plugin_category,
|
2019-04-05 03:03:50 +00:00
|
|
|
"versions": plugin_manifest_versions
|
2019-02-02 08:13:06 +00:00
|
|
|
}
|
|
|
|
with open(manifest_fragment_file_name, 'w') as manifest_fragment_file:
|
|
|
|
json.dump(plugin_manifest_fragment, manifest_fragment_file, sort_keys=True, indent=4)
|
|
|
|
print("Wrote plugin manifest fragment to {}".format(manifest_fragment_file_name))
|