Various fixes
* Retrieve build commands from build_manager
* fixing psa build dir
* Use different node labels for different builds
* Add script to download jenkins artifacts
* Verify status per stage
* Moving code to library
* Ability to comment on gerrit change
Change-Id: I390674b7ed6cfd20e4746a2d32e708fd6855857b
Signed-off-by: Dean Birch <dean.birch@arm.com>
diff --git a/jenkins/download_artifacts.py b/jenkins/download_artifacts.py
new file mode 100755
index 0000000..5e9111b
--- /dev/null
+++ b/jenkins/download_artifacts.py
@@ -0,0 +1,106 @@
+#!/usr/bin/env python3
+#
+# Downloads artifacts from a build of tf-m-build-and-test
+#
+
+__copyright__ = """
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+ """
+
+import requests
+import argparse
+import os
+from urllib.parse import urljoin
+from html.parser import HTMLParser
+
+
+class UrlExtracter(HTMLParser):
+ def __init__(self):
+ super().__init__()
+ self.last_tag = None
+ self.last_link = None
+ self.last_config = None
+ self.build_artifacts = {}
+ self.build_logs = {}
+
+ def handle_starttag(self, tag, attrs):
+ for key, value in attrs:
+ if key == "href":
+ self.last_link = value
+ self.last_tag = tag
+
+ def handle_endtag(self, tag):
+ if tag == "br":
+ self.last_tag = None
+
+ def handle_data(self, data):
+ if not self.last_tag:
+ self.last_config = data.replace(": ", "").replace("\n", "")
+ return
+
+ if self.last_tag == "a":
+ if data == "Artifacts":
+ self.build_artifacts[self.last_config] = self.last_link
+ elif data == "Logs":
+ self.build_logs[self.last_config] = self.last_link
+
+
+def download_artifacts(url, save_dir):
+ if not url.endswith("/"):
+ url += "/"
+ job_page_req = requests.get(url)
+ if job_page_req.status_code != requests.codes.ok:
+ print("Issue contacting given URL")
+ return
+ print("Found build")
+ build_links_req = requests.get(urljoin(url, "artifact/build_links.html"))
+ if build_links_req.status_code != requests.codes.ok:
+ print("Given build did not have an artifact called `build_links.html`")
+ return
+ parser = UrlExtracter()
+ print("Extracting links from build_links.html")
+ parser.feed(build_links_req.text)
+ print("Links found")
+ if not os.path.exists(save_dir):
+ print("Creating directory at {}".format(save_dir))
+ os.makedirs(save_dir)
+ else:
+ print("Reusing directory at {}.")
+ for config, log_url in parser.build_logs.items():
+ print("Downloading {}".format(log_url))
+ log_req = requests.get(log_url)
+ log_file_path = os.path.join(save_dir, "{}.log".format(config))
+ with open(log_file_path, "w") as log_file:
+ log_file.write(log_req.text)
+ print("Saved log to {}".format(log_file_path))
+ for config, artifacts_url in parser.build_artifacts.items():
+ zip_url = urljoin(artifacts_url, "*zip*/archive.zip")
+ print("Downloading {}".format(zip_url))
+ artifact_zip_req = requests.get(zip_url, stream=True)
+ zip_file = os.path.join(save_dir, "{}.zip".format(config))
+ with open(zip_file, "wb") as artifact_zip:
+ for chunk in artifact_zip_req.iter_content(chunk_size=8192):
+ artifact_zip.write(chunk)
+ print("Saved artifacts zip to {}".format(zip_file))
+ print("Finished")
+
+
+def main():
+ argparser = argparse.ArgumentParser()
+ argparser.add_argument(
+ "job_url", help="Url to a completed build of tf-m-build-and-test"
+ )
+ argparser.add_argument(
+ "-o", "--output_dir", default="artifacts", help="Location to save artifacts to."
+ )
+ args = argparser.parse_args()
+ download_artifacts(args.job_url, args.output_dir)
+
+
+if __name__ == "__main__":
+ main()