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
|
|
|
|
2019-04-09 04:15:36 +00:00
|
|
|
project_version = "{}.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-04-26 03:08:56 +00:00
|
|
|
stdout, stderr, retcode = 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']
|
|
|
|
)
|
|
|
|
run_os_command(build_command)
|
2019-04-26 03:08:56 +00:00
|
|
|
print(stdout)
|
|
|
|
print(stderr)
|
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)
|
|
|
|
print(stdout)
|
|
|
|
print(stderr)
|
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:
|
|
|
|
print('Could not archive artifacts: {}'.format(stderr))
|
|
|
|
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]
|
|
|
|
|
|
|
|
generate_plugin_manifest(project, build_cfg, bin_md5sum)
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
def generate_plugin_manifest(project, build_cfg, bin_md5sum):
|
|
|
|
# Extract our name, type, and plugin_id
|
|
|
|
project_name = project['name']
|
|
|
|
project_type = project['type']
|
|
|
|
project_plugin_id = project['plugin_id']
|
2019-02-09 00:16:41 +00:00
|
|
|
project_plugin_guid = build_cfg['guid']
|
|
|
|
project_plugin_nicename = build_cfg['nicename']
|
|
|
|
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-04-09 04:15:36 +00:00
|
|
|
project_version = "{}.0".format(build_cfg['version'])
|
2019-02-02 08:13:06 +00:00
|
|
|
|
2019-04-05 03:03:50 +00:00
|
|
|
jellyfin_version = build_cfg['jellyfin_version']
|
|
|
|
|
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 = [{
|
2019-04-09 04:15:36 +00:00
|
|
|
"name": project_plugin_nicename,
|
2019-04-05 03:03:50 +00:00
|
|
|
"versionStr": project_version,
|
|
|
|
"classification": "Release",
|
|
|
|
"description": "Release",
|
|
|
|
"requiredVersionStr": jellyfin_version,
|
|
|
|
"sourceUrl": "https://repo.jellyfin.org/releases/plugin/{0}/{0}_{1}.zip".format(project_name, project_version),
|
|
|
|
"targetFilename": "{0}_{1}.zip".format(project_name, project_version),
|
|
|
|
"checksum": bin_md5sum,
|
|
|
|
"timestamp": build_date,
|
|
|
|
"runtimes": "netframework,netcore"
|
|
|
|
}]
|
|
|
|
plugin_manifest_versions = plugin_manifest_new_version_fragment + plugin_manifest_existing_version_fragments
|
|
|
|
|
2019-02-02 08:13:06 +00:00
|
|
|
plugin_manifest_fragment = {
|
|
|
|
"id": project_plugin_id,
|
2019-04-05 03:03:50 +00:00
|
|
|
"packageId": project_plugin_id,
|
2019-02-02 08:13:06 +00:00
|
|
|
"name": project_plugin_nicename,
|
2019-02-09 00:16:41 +00:00
|
|
|
"shortDescription": project_plugin_description,
|
2019-02-02 08:13:06 +00:00
|
|
|
"overview": project_plugin_overview,
|
|
|
|
"isPremium": False,
|
|
|
|
"richDescUrl": "",
|
|
|
|
"thumbImage": "",
|
|
|
|
"previewImage": "",
|
|
|
|
"type": "UserInstalled",
|
2019-03-12 04:40:07 +00:00
|
|
|
"owner": project_plugin_owner,
|
2019-02-02 08:13:06 +00:00
|
|
|
"category": project_plugin_category,
|
|
|
|
"titleColor": "#FFFFFF",
|
|
|
|
"featureId": project_plugin_nicename,
|
|
|
|
"regInfo": "",
|
|
|
|
"price": 0.00,
|
|
|
|
"targetSystem": "Server",
|
|
|
|
"guid": project_plugin_guid,
|
|
|
|
"adult": 0,
|
|
|
|
"totalRatings": 1,
|
|
|
|
"avgRating": 5,
|
|
|
|
"isRegistered": False,
|
|
|
|
"expDate": None,
|
|
|
|
"installs": 0,
|
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))
|