-
-
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> |jq
is enough, but of course python has everything necessary to handle HTML Get and parse the json.