diff options
author | Jan Holthuis <jan.holthuis@ruhr-uni-bochum.de> | 2021-03-28 21:48:43 +0200 |
---|---|---|
committer | Jan Holthuis <jan.holthuis@ruhr-uni-bochum.de> | 2021-03-28 21:48:43 +0200 |
commit | c71e64d211243e121b89fe19495576fbf58892cb (patch) | |
tree | 98c0f72bc9b4aa362c825bf506405e440c801dfe | |
parent | 23b621cec968f2feede3bce6df9fa5786e77002a (diff) |
GitHub Actions: Add some comments regarding manifest generation
-rw-r--r-- | .github/workflows/build.yml | 8 | ||||
-rw-r--r-- | tools/generate_download_metadata.py | 28 |
2 files changed, 33 insertions, 3 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 38bd7ee6e1..a7e5cb2338 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -333,8 +333,10 @@ jobs: Add-Content -Path "$Env:GITHUB_ENV" -Value "PATH=$Env:PATH" - name: "Generate Artifact Metadata" - id: generate_artifact_metadata - # skip deploying Ubuntu builds to downloads.mixxx.org because these are deployed to the PPA + # Generate metadata for file artifact and write it to the job output + # using the artifacts_slug value. This also sets the DEPLOY_DIR + # environment variable that is used in the deploy.sh script in the next + # step. if: github.event_name == 'push' run: python3 tools/generate_download_metadata.py artifact ${{ matrix.artifacts_path }} "${{ matrix.artifacts_slug }}" env: @@ -378,6 +380,8 @@ jobs: fetch-depth: 0 - name: "Collect Artifacts Metadata & Write Manifest" + # Retrieve the metadata from the matrix job's outputs, merge them into a + # single JSON document and then deploy to the server. if: github.event_name == 'push' && env.SSH_PASSWORD != null run: python3 tools/generate_download_metadata.py manifest env: diff --git a/tools/generate_download_metadata.py b/tools/generate_download_metadata.py index beea581c62..f3dbc954bf 100644 --- a/tools/generate_download_metadata.py +++ b/tools/generate_download_metadata.py @@ -13,7 +13,10 @@ import urllib.request def url_fetch(url, headers=None, **kwargs): + """Make a web request to the given URL and return the response object.""" request_headers = { + # Override the User-Agent because our download server seems to block + # requests with the default UA value and responds "403 Forbidden". "User-Agent": ( "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:86.0) Gecko/20100101 " "Firefox/86.0" @@ -26,6 +29,7 @@ def url_fetch(url, headers=None, **kwargs): def url_exists(url): + """Make a HEAD request to the URL and check if the response is "200 OK".""" try: resp = url_fetch(url, method="HEAD") except IOError: @@ -34,6 +38,7 @@ def url_exists(url): def url_download_json(url): + """Returns the JSON object from the given URL or return None.""" try: resp = url_fetch(url) manifest_data = resp.read().decode() @@ -44,6 +49,7 @@ def url_download_json(url): def sha256(file_path): + """Returns the sha256 hexdigest for a file.""" with open(file_path, mode="rb") as fp: read_chunk = functools.partial(fp.read, 1024) m = hashlib.sha256() @@ -53,6 +59,7 @@ def sha256(file_path): def find_git_branch(path="."): + """Return the checked out git branch for the given path.""" return subprocess.check_output( ("git", "rev-parse", "--abbrev-ref", "HEAD"), cwd=path, @@ -61,6 +68,11 @@ def find_git_branch(path="."): def generate_file_metadata(file_path, destdir): + """ + Generate the file metadata for file_Path. + + The destdir argument is used for for generating the download URL. + """ file_stat = os.stat(file_path) file_sha256 = sha256(file_path) file_name = os.path.basename(file_path) @@ -91,12 +103,14 @@ def generate_file_metadata(file_path, destdir): def collect_manifest_data(job_data): + """Parse the job metadata dict and return the manifest data.""" job_result = job_data["result"] print(f"Build job result: {job_result}") assert job_result == "success" manifest_data = {} for output_name, output_data in job_data["outputs"].items(): + # Filter out unrelated job outputs that don't start with "artifact-". prefix, _, slug = output_name.partition("-") if prefix != "artifact" or not slug: print(f"Ignoring output '{output_name}'...") @@ -105,9 +119,10 @@ def collect_manifest_data(job_data): url = artifact_data["file_url"] + # Make sure that the file actually exists on the download server resp = url_fetch(url, method="HEAD") if not resp.status == 200: - raise LookupError(f"Unable to find URL '{url}' on remove server") + raise LookupError(f"Unable to find URL '{url}' on remote server") manifest_data[slug] = artifact_data @@ -138,32 +153,41 @@ def main(argv=None): ) if args.cmd == "artifact": + # Check that we have exactly one file artifact artifact_paths = glob.glob(args.file) assert len(artifact_paths) == 1 file_path = artifact_paths[0] + # Generate metadata and print it metadata = generate_file_metadata(file_path, destdir) print(json.dumps(metadata, indent=2, sort_keys=True)) if os.getenv("CI") == "true": + # Set GitHub Actions job output print( "::set-output name=artifact-{}::{}".format( args.slug, json.dumps(metadata) ) ) + + # Set the DEPLOY_DIR variable for the next build step url = urllib.parse.urlparse(metadata["file_url"]) deploy_dir = posixpath.dirname(url.path) with open(os.environ["GITHUB_ENV"], mode="a") as fp: fp.write(f"DEPLOY_DIR={deploy_dir}\n") elif args.cmd == "manifest": + # Parse the JOB_DATA JSON data, generate the manifest data and print it job_data = json.loads(os.environ["JOB_DATA"]) manifest_data = collect_manifest_data(job_data) print(json.dumps(manifest_data, indent=2, sort_keys=True)) + # Write the manifest.json for subsequent deployment to the server with open("manifest.json", mode="w") as fp: json.dump(manifest_data, fp, indent=2, sort_keys=True) if os.getenv("CI") == "true": + # Check if generated manifest.json file differs from the one that + # is currently deployed. manifest_url = os.environ["MANIFEST_URL"].format( git_branch=git_branch ) @@ -175,6 +199,8 @@ def main(argv=None): if manifest_data == remote_manifest_data: return + # The manifest data is different, so we set the DEPLOY_DIR and + # MANIFEST_DIRTY env vars. deploy_dir = os.environ["DESTDIR"].format(git_branch=git_branch) with open(os.environ["GITHUB_ENV"], mode="a") as fp: fp.write(f"DEPLOY_DIR={deploy_dir}\n") |