-
-
Save jmcgeheeiv/8a7431aa2483a5a4f420 to your computer and use it in GitHub Desktop.
| #!/usr/bin/env python3 | |
| # Download the latest successful build artifacts from Jenkins using Python 3 | |
| # John McGehee 1/25/2016 | |
| # | |
| # Based on the Python 2 version by supertom: https://gist.github.com/supertom/2759847 | |
| import argparse | |
| import codecs | |
| import io | |
| import json | |
| import os | |
| import sys | |
| try: | |
| import pycurl | |
| isPyCurlAvailable = True | |
| except ImportError: | |
| import urllib.request | |
| isPyCurlAvailable = False | |
| parser = argparse.ArgumentParser(description="Download the latest successful build artifacts from Jenkins.") | |
| parser.add_argument('jobs', metavar='jobName', nargs='+', | |
| help="List of job names from which to fetch the latest artifact, " | |
| "including folder name(s). For example: 'folderName1/folderName2/jobName'.") | |
| args = parser.parse_args() | |
| assert isinstance(args.jobs, list) and args.jobs, "A list of at least one job must be specified" | |
| ########## | |
| # configuration | |
| build_host = "jenkins.johnnado.com" | |
| lastBuildAPIURL = "http://" + build_host + "/job/%s/lastSuccessfulBuild/api/json" | |
| lastBuildArtifactLURL = "http://" + build_host + "/job/%s/lastSuccessfulBuild/artifact/%s" | |
| localSaveDir = "." | |
| # Default for .tgz artifacts; change if yours are different, for example .apk files. | |
| artifactExtension=".internal.tgz" | |
| ########## | |
| # UDFs | |
| def downloadFile(url, filename): | |
| print("==> Downloading File: ", filename, " URL: ", url) | |
| if isPyCurlAvailable: | |
| fp = open(filename, "wb") | |
| curl = pycurl.Curl() | |
| curl.setopt(pycurl.URL, url) | |
| curl.setopt(pycurl.WRITEDATA, fp) | |
| curl.perform() | |
| curl.close() | |
| fp.close() | |
| else: | |
| urllib.request.urlretrieve(url, filename) | |
| ########### | |
| # start | |
| print("Fetching files from Jenkins") | |
| if not os.path.exists(localSaveDir): | |
| print("==> Creating Dir %s" % (localSaveDir)) | |
| os.makedirs(localSaveDir) | |
| for job in args.jobs: | |
| job = job.strip('/') | |
| job = job.replace('/', '/job/') | |
| jobURL = lastBuildAPIURL % (job) | |
| if isPyCurlAvailable: | |
| buf = io.BytesIO() | |
| c = pycurl.Curl() | |
| c.setopt(c.URL, jobURL) | |
| c.setopt(c.WRITEFUNCTION, buf.write) | |
| c.perform() | |
| jsonbytes = buf.getvalue() | |
| buf.close() | |
| else: | |
| with urllib.request.urlopen(jobURL) as response: | |
| jsonbytes = response.read() # a `bytes` object | |
| jsonstr = jsonbytes.decode('utf-8') | |
| jd = json.loads(jsonstr) | |
| artifacts = jd['artifacts'] | |
| for art in artifacts: | |
| if art['fileName'].find(artifactExtension) > -1: | |
| artURL = lastBuildArtifactLURL % (job,art['relativePath']) | |
| downloadFile(str(artURL),localSaveDir + "/" + str(art['fileName'])) | |
For anyone blind like me wondering why nothing is working, don't forget to set the extension variable
Thank you! Working great
@parkerlreed is this "extension variable" artifactExtension? What did you set it to?
@jmcgeheeiv Your code does not handle necessary authentication to jenkins via generated token and I found the documentation on jenkins side insufficient for hints what underlying protocol is used.
With curl, this looks like subprocess.run(["curl", (artifacturl + arti_fname), "--output", arti_fname, "--user", authinfo], check=True).
I tried unsuccessful the python session API via html.
Any ideas from your side?
@parkerlreed is this "extension variable"
artifactExtension? What did you set it to?
It just needs to be whatever you are pulling. Mine was an apk so I had to change that for it to download.
I added a comment documenting artifactExtension. Thanks @parkerlreed!
I added a comment documenting
artifactExtension. Thanks @parkerlreed!
Cheers!
No external dependency is needed to handle downloads.
For example,
curl -s http://localhost:8000/job/test-job-1/lastSuccessfulBuild/api/json --user <your-username>:<authentication-token> |jqis enough, but of course python has everything necessary to handle HTML Get and parse the json.