Skip to content

Instantly share code, notes, and snippets.

@SanCHEESE
Last active June 4, 2021 13:21
Show Gist options
  • Save SanCHEESE/320f84bda6c8caa1d030128ab384bf88 to your computer and use it in GitHub Desktop.
Save SanCHEESE/320f84bda6c8caa1d030128ab384bf88 to your computer and use it in GitHub Desktop.
A simple python script that runs teamcity build remotely or locally, monitors its state and gets artifacts
import requests, sys, time, shutil
from requests.auth import HTTPBasicAuth
import xml.etree.ElementTree as xml
base_url = None
user = None
passwd = None
common_path = 'httpAuth/app/rest'
def main(argv):
# get tc url
base_url = argv[0]
# get conf id
conf_id = argv[1]
# get user
user = argv[2]
# get user password
passwd = argv[3]
xml_response = None
# trigger build
url = '{}/{}/buildQueue'.format(base_url, common_path)
try:
print("Starting a build with conf_id={}, POST url={}".format(conf_id, url))
response = requests.post(url, auth=HTTPBasicAuth(user, passwd),
data="<build><buildType id=\"{}\"/></build>".format(conf_id),
headers={"Content-Type": "application/xml"})
xml_response = xml.fromstring(response.content)
del response
except requests.exceptions.RequestException:
print('HTTP Request {} failed'.format(url))
exit(1)
# get build id
build_id = xml_response.attrib['id']
print("build_id={}".format(build_id))
url += '/id:{}'.format(build_id)
state = None
status = None
# monitor build state
while state != 'finished':
wait_time = 10
try:
print("Getting build status, build_id={}, POST url={}".format(build_id, url))
response = requests.get(url, auth=HTTPBasicAuth(user, passwd), headers={"Content-Type": "application/xml"})
xml_response = xml.fromstring(response.content)
del response
state = xml_response.attrib['state']
if state == 'queued':
wait_time = 30
print('Another teamcity build already running or current build was queued. Will sleep for {}s'.format(
wait_time))
else:
status = xml_response.attrib['status']
print('Teamcity build status = {}, state = {}'.format(status, state))
except requests.exceptions.RequestException:
print('HTTP Request {} failed'.format(url))
exit(1)
if state == 'finished':
break
time.sleep(wait_time)
if status == 'UNKNOWN':
print('Teamcity build was cancelled')
exit(1)
elif status == 'SUCCESS':
print('Teamcity build succeeded')
# get artifacts and save to script's directory
url = '{}/{}/builds/id:{}/artifacts'.format(base_url, common_path, build_id)
try:
print("Getting build artifacts, build_id={}, POST url={}".format(build_id, url))
response = requests.get(url, auth=HTTPBasicAuth(user, passwd), headers={"Content-Type": "application/xml"})
xml_response = xml.fromstring(response.content)
del response
except requests.exceptions.RequestException:
print('HTTP Request {} failed'.format(url))
exit(1)
for artifact in xml_response:
artifact_path = artifact.attrib['name']
url += '/content/{}'.format(artifact_path)
try:
response = requests.get(url, auth=HTTPBasicAuth(user, passwd), stream=True)
with open(artifact_path, 'wb') as out_file:
shutil.copyfileobj(response.raw, out_file)
print('Artifact {} successfully downloaded'.format(artifact_path))
del response
except requests.exceptions.RequestException:
print('HTTP Request {} failed'.format(url))
exit(1)
elif status == 'FAILURE':
print('Remote teamcity build failed')
# TODO: download logs and print them to console
exit(1)
if __name__ == "__main__":
main(sys.argv[1:])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment