def initialize(self): self.circleci = Api(self.args['circleci_token']) self.last_state = None self.light_id = self.args['entity_id'] self.effect_by_state() self.run_every(self.on_ci_state_update, datetime.datetime.now(), 10)
def __init__(self, token): try: self.ci = Api(token) self.username = self.ci.get_user_info()['login'] app.logger.info("Initialised connection to Circleci with user: %s", self.username) return None except Exception as e: app.logger.error( "Unable to initialise connection to CircleCi api: %s", repr(e)) return None
def run(self): if self.circleci is None: self.circleci = Api(self.circleci_token) if self.workflows: if self.workflow_branch and not self.workflow_name: self.output = dict( full_text='workflow_name must be specified!' ) return project = {p['reponame']: p for p in self.circleci.get_projects()}.get(self.repo_name) if not self.workflow_branch: self.workflow_branch = project.get('default_branch') workflow_info = project['branches'].get(self.workflow_branch)['latest_workflows'].get(self.workflow_name) self.last_build_started = self._format_time(workflow_info.get('created_at')) self.repo_status = workflow_info.get('status') self.last_build_duration = '' # TODO: gather this information once circleCI exposes it else: self.repo_summary = self.circleci.get_project_build_summary( self.repo_owner, self.repo_name, limit=1) if len(self.repo_summary) != 1: return self.repo_summary = self.repo_summary[0] self.repo_status = self.repo_summary.get('status') self.last_build_started = self._format_time(self.repo_summary.get('queued_at')) try: self.last_build_duration = TimeWrapper( self.repo_summary.get('build_time_millis') / 1000, default_format=self.duration_format) except TypeError: self.last_build_duration = 0 if self.repo_status_map: self.repo_status = self.repo_status_map.get(self.repo_status, self.repo_status) self.output = dict( full_text=formatp(self.format, **vars(self)), short_text=self.short_format.format(**vars(self)), ) if self.status_color_map: self.output['color'] = self.status_color_map.get(self.repo_status, self.color) else: self.output['color'] = self.color
def deploy(): """Deploy SupportService to LightSail. Uses a feature flag to disable automatically deploying specific environments. It can be found in the production environment of the support-service project. """ l = LaunchDarklyApi(os.environ.get('LD_API_KEY'), 'ldsolutions.tk') a = AwsApi(logger, keyPairName='SupportService') c = ConfigGenerator() ci = Api(os.environ.get('CIRCLE_TOKEN')) envs = l.getEnvironments('support-service') for env in envs: hostname = env['hostname'] ctx = {"key": "circleci", "custom": {"hostname": hostname}} params = { "build_parameters": { "CIRCLE_JOB": "deploy_instance", "LD_HOST": hostname } } if client.variation("auto-deploy-env", ctx, False): # run deploy job for environment resp = ci.trigger_build('launchdarkly', 'SupportService', branch='master', params=params) click.echo( "Sending Deploy Job to CircleCI for {0}".format(hostname)) click.echo("CircleCI Build URL: {0}".format(resp['build_url'])) else: click.echo( "Not Auto Deploying, auto-deploy-env flag is off for {0}". format(hostname))
class ApiHandler: """Wrapper around circleci API calls, specific for artifact access.""" def __init__(self, token, user='******', project='connectedhomeip'): self.api = Api(token) self.user = user self.project = project self.vcs_type = 'github' def fetchCompletedBuilds(self, branch='master'): """Gets a snapshot of the latest successful builds in the specified branch.""" for build in self.api.get_project_build_summary( self.user, self.project, branch=branch, status_filter='successful'): logging.debug('Fetched summary: %r', build) yield CompletedBuild(job_name=build['workflows']['job_name'], build_num=build['build_num']) def fetchLatestBuildNumber(self, job_name, branch='master'): """Fetch the latest build number for the specified job name.""" logging.info('Searching for the latest job "%s"', job_name) for build in self.fetchCompletedBuilds(branch): logging.info('Found a completed build %r', build) if build.job_name == job_name: logging.info('Found the latest job with id %d', build.build_num) return build.build_num logging.error('No usable latest build was found.') raise Exception('No build found for job "%s"' % job_name) def getArtifacts(self, build_num): """Fetch artifacts for the specified build number.""" for artifact in self.api.get_artifacts(self.user, self.project, build_num, self.vcs_type): logging.debug('Fetched artifact info: %r', artifact) yield ArtifactInfo(path=artifact['path'], url=artifact['url'])
class Lampka(hass.Hass): def initialize(self): self.circleci = Api(self.args['circleci_token']) self.last_state = None self.light_id = self.args['entity_id'] self.effect_by_state() self.run_every(self.on_ci_state_update, datetime.datetime.now(), 10) def on_ci_state_update(self, kwargs=None): self.log("Tick, so we refresh!") self.effect_by_state() def effect_by_state(self): last_build = self.circleci.get_recent_builds()[0] if last_build['status'] != self.last_state: effect = "" self.last_state = last_build['status'] self.log("State of build changed to: {}".format(self.last_state)) if self.last_state == 'running' or self.last_state == 'queued': self.log("Effect is running...") effect = "Running" elif self.last_state == 'success' or self.last_state == 'fixed': self.log("Effect is success...") effect = "Success" else: self.log("Effect is failed...") effect = "Failed" current_state = self.get_state(self.light_id) if current_state == 'on': self.call_service('light/turn_on', entity_id=self.light_id, effect=effect)
def setUp(self): self.c = Api(os.getenv('CIRCLE_TOKEN'))
class TestCircleCIApi(unittest.TestCase): def setUp(self): self.c = Api(os.getenv('CIRCLE_TOKEN')) def test_trigger_with_build_params(self): params = {"build_parameters[CIRCLE_JOB]": "integration"} resp = self.c.trigger_build('thomasrockhu', 'circleci.py', params=params) self.assertEqual(resp['build_parameters']['CIRCLE_JOB'], 'integration') def test_add_ssh_key(self): # note this is a throwaway key key = """ -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAr74mGZIij/V59DTGRPaijyDolWA33FlyopBVSys09MOOF7HT EWLMwyyRIR3t6mjl7kcS3rTPWORLF4U+8iMv1EyitV+fV+pQIJmK8gZvyyNePCR0 wvAizhNTcYgtZF86D/EBNHwOdN0o4P+4qlbBlPjFiW7S5X6iDbrV9H4ADQDI2R+c EBets+aVRrtCdR+cGrOS9BRVf4NK6ADQaKOcgTYRTJuxI48O18iUj9dZSCAlO6xQ obpALlQKj0srGcx9++vTzED3Wr9JpOfsC8LqNdJdaF6KJfBsc1xczSw980hcXwWx /zrQaii5W7nFU2lRrwdXyscqutL1I5lLKDYhLQIDAQABAoIBACA9mxG/3HVajGf/ sov+Ty5A1EprH3ReOIiYP/2NTKbGpW+1YMpkvLnlmC5iJj6FxgDjqxOOSie9ogUL ndOgHusssADkLQBc7Rw97t6dza6Pq38PFRiaI1h49Srz15f9XFKGXTk6tRA9bn1w jHk7d0IULXEcErald6dbKlszLmE0AHvWHWNrABwbNBzG2PrFFbrWbYiUDhIx8Ebj 9IKDu8JqYr5o6Kv8agOAWkq4S3iGQ9S+suTiV+3/kyK7XL5TI5gVPdZR4NIAGFKO +1TBNtCiYl+LQ46km5cmirESTsObNM3JrF8VWBlVZoVrxZiIhYUAKrFzcJ905Vrh PN0rwmECgYEA6LWeorGs9kyVgNI4KnvVI1AXACnpy4L48ypqIns5A71j+4OiVI64 dWAlHB64ZoMVVBqTCv/uiloqzlK+FCe8cxi3Xh/hBDmKmGZygpFoRdGwmNA+1CoA DZftaswUQ64Qt8jc9HmQnufvkxniNAewRxuZDP462WgBwZhRe8hvUqUCgYEAwVT0 HojCaLm2TMY2XE9EzCHNF1XlfqzB0i0dJ4pQ2SZ8st1F8vkEjHsPEOURRkLzWFC4 A/QWFsmhv4UKpDplV5QV3S+FgbpzLdV64vUYBuo06OZGcJgCdtZyt6vGSB4f+mq2 VQt+j6ZYlI5nWwkz1Yvg8AmBemuXNFui8o/c9ekCgYB2vwa9+nBKFnZLj/n9I8d1 B49VFA4rPSAP5VrXUY2cbO4yD8+r2lAiBPeqy7pJBSbDDfRurn5otu4U7n/0BPrS uJAJRbcq0rn4Xn6cRdqxlfjJYapN1UjFpvsNfinxB0ecoLCvR8EWdT/5DkIxTqMT BfApgylAeyQ6R6F8yqCTyQKBgQCN5XFrO8scnDmt7ckWRWPkQ2bJGtVe/SMgxNXi IIWoa7QYf4mIhLaO+P8c0lO0cw0yI8R7ulnADet2qwodcXLSLbFCb0+Y4KUK3eXc 0DD7WkjNK75Fg3xDhrAaGKxmYB3uaQY8MzyH6HqZRk+bpIxzzr+gzglHNdJ7rkpR p79wiQKBgQCwFyjcLAfA5uJDZ9jVEZ2BKgd9IGo16HrRnd+mpggUBGf2mbE2JGgk rAUZ8tU0o5Ec6T0ZQkcous7OwBZGE+JLuFa3S6JfISLw42brjQ9dE5mosm7m2d4H 3C9cAnmV6aJkTwT46OiNvUYZ8je5WP+4Kqb2ke9xw3ddk5X1n5AB4w== -----END RSA PRIVATE KEY----- """ resp = self.c.add_ssh_key('thomasrockhu', 'circleci-sandbox', key, hostname='localhost') # there is no response when success, so we test to make sure # that there is no other message as well. self.assertTrue(len(resp) == 0) def test_get_user_info(self): # exercise a real "GET" resp = self.c.get_user_info() self.assertEqual(resp['login'], 'thomasrockhu') def test_clear_cache(self): # execrise a real "DELETE" resp = self.c.clear_cache('thomasrockhu', 'circleci-sandbox') self.assertEqual(resp['status'], 'build dependency caches deleted') def test_retry_build_no_cache(self): # use Experimental API self.e = Experimental(os.getenv('CIRCLE_TOKEN')) resp = self.e.retry_no_cache('thomasrockhu', 'circleci-sandbox', 1) self.assertTrue(resp['no_dependency_cache']) def test_add_heroku_key(self): key = os.getenv('HEROKU_KEY') resp = self.c.add_heroku_key(key) # there is no response when success, so we test to make sure # that there is no other message as well. self.assertTrue(len(resp) == 0) def test_download_artifact(self): resp = self.c.get_artifacts('thomasrockhu', 'circleci.py', 87) artifact = self.c.download_artifact(resp[0]['url']) self.assertIn('circleci_api_py.html', artifact) artifact_with_destdir = self.c.download_artifact( resp[0]['url'], '/tmp') self.assertIn('tmp', artifact_with_destdir) artifact_with_destdir_and_filename = self.c.download_artifact( resp[0]['url'], '/tmp', 'myartifact.txt') self.assertIn('myartifact.txt', artifact_with_destdir_and_filename)
class TestCircleCIApi(unittest.TestCase): def setUp(self): self.c = Api(os.getenv('CIRCLE_TOKEN')) def loadMock(self, filename): """helper function to open mock responses""" filename = 'tests/mocks/{0}'.format(filename) with open(filename, 'r') as f: self.c._request = MagicMock(return_value=f.read()) def test_bad_verb(self): with self.assertRaises(BadVerbError) as e: self.c._request('BAD', 'dummy') self.assertEqual('BAD', e.exception.argument) self.assertIn('DELETE', e.exception.message) def test_get_user_info(self): self.loadMock('mock_user_info_response') resp = json.loads(self.c.get_user_info()) self.assertEqual(resp["selected_email"], '*****@*****.**') def test_get_projects(self): self.loadMock('mock_get_projects_response') resp = json.loads(self.c.get_projects()) self.assertEqual(resp[0]['vcs_url'], 'MOCK+https://ghe-dev.circleci.com/ccie-tester/testing') def test_follow_project(self): self.loadMock('mock_follow_project_response') resp = json.loads(self.c.follow_project('ccie-tester', 'testing')) self.assertEqual(resp["mock+following"], True) def test_get_project_build_summary(self): self.loadMock('mock_project_build_summary_response') resp = json.loads(self.c.get_project_build_summary('ccie-tester', 'testing')) self.assertEqual(len(resp), 6) self.assertEqual(resp[0]['username'], 'MOCK+ccie-tester') # with invalid status filter with self.assertRaises(InvalidFilterError) as e: json.loads(self.c.get_project_build_summary('ccie-tester', 'testing', status_filter='dummy')) self.assertEqual('dummy', e.exception.argument) self.assertIn('running', e.exception.message) # with branch resp = json.loads(self.c.get_project_build_summary('ccie-tester', 'testing', branch='master')) self.assertEqual(len(resp), 6) self.assertEqual(resp[0]['username'], 'MOCK+ccie-tester') def test_get_recent_builds(self): self.loadMock('mock_get_recent_builds_response') resp = json.loads(self.c.get_recent_builds()) self.assertEqual(len(resp), 7) self.assertEqual(resp[0]['reponame'], 'MOCK+testing') def test_get_build_info(self): self.loadMock('mock_get_build_info_response') resp = json.loads(self.c.get_build_info('ccie-tester', 'testing', '1')) self.assertEqual(resp['reponame'], 'MOCK+testing') def test_get_artifacts(self): self.loadMock('mock_get_artifacts_response') resp = json.loads(self.c.get_artifacts('ccie-tester', 'testing', '1')) self.assertEqual(resp[0]['path'], 'MOCK+raw-test-output/go-test-report.xml') def test_retry_build(self): self.loadMock('mock_retry_build_response') resp = json.loads(self.c.retry_build('ccie-tester', 'testing', '1')) self.assertEqual(resp['reponame'], 'MOCK+testing') # with SSH resp = json.loads(self.c.retry_build('ccie-tester', 'testing', '1', ssh=True)) self.assertEqual(resp['reponame'], 'MOCK+testing') def test_cancel_build(self): self.loadMock('mock_cancel_build_response') resp = json.loads(self.c.cancel_build('ccie-tester', 'testing', '11')) self.assertEqual(resp['reponame'], 'MOCK+testing') self.assertEqual(resp['build_num'], 11) self.assertTrue(resp['canceled']) def test_add_ssh_user(self): self.loadMock('mock_add_ssh_user_response') resp = json.loads(self.c.add_ssh_user('ccie-tester', 'testing', '11')) self.assertEqual(resp['reponame'], 'MOCK+testing') self.assertEqual(resp['ssh_users'][0]['login'], 'ccie-tester') def test_trigger_build(self): self.loadMock('mock_trigger_build_response') resp = json.loads(self.c.trigger_build('ccie-tester', 'testing')) self.assertEqual(resp['reponame'], 'MOCK+testing') def test_list_checkout_keys(self): self.loadMock('mock_list_checkout_keys_response') resp = json.loads(self.c.list_checkout_keys('levlaz', 'circleci-sandbox')) self.assertEqual(resp[0]['type'], 'deploy-key') self.assertIn('public_key', resp[0]) def test_create_checkout_key(self): with self.assertRaises(BadKeyError) as e: self.c.create_checkout_key('levlaz', 'test', 'bad') self.assertEqual('bad', e.exception.argument) self.assertIn('deploy-key', e.exception.message) self.loadMock('mock_create_checkout_key_response') resp = json.loads(self.c.create_checkout_key('levlaz', 'test', 'deploy-key')) self.assertEqual(resp['type'], 'deploy-key') self.assertIn('public_key', resp) def test_get_checkout_key(self): self.loadMock('mock_get_checkout_key_response') resp = json.loads(self.c.get_checkout_key('levlaz', 'circleci-sandbox', '94:19:ab:a9:f4:2b:21:1c:a5:87:dd:ee:3d:c2:90:4e')) self.assertEqual(resp['type'], 'deploy-key') self.assertIn('public_key', resp) def test_delete_checkout_key(self): self.loadMock('mock_delete_checkout_key_response') resp = json.loads(self.c.delete_checkout_key('levlaz', 'circleci-sandbox', '94:19:ab:a9:f4:2b:21:1c:a5:87:dd:ee:3d:c2:90:4e')) self.assertEqual(resp['message'], 'ok') def test_clear_cache(self): self.loadMock('mock_clear_cache_response') resp = json.loads(self.c.clear_cache('levlaz', 'circleci-sandbox')) self.assertEqual('build dependency caches deleted', resp['status']) def test_get_test_metadata(self): self.loadMock('mock_get_test_metadata_response') resp = json.loads(self.c.get_test_metadata('levlaz', 'circleci-demo-javascript-express', 127)) self.assertEqual(len(resp), 2) self.assertIn('tests', resp) def test_list_envvars(self): self.loadMock('mock_list_envvars_response') resp = json.loads(self.c.list_envvars('levlaz', 'circleci-sandbox')) self.assertEqual(len(resp), 4) self.assertEqual(resp[0]['name'], 'BAR') def test_add_envvar(self): self.loadMock('mock_add_envvar_response') resp = json.loads(self.c.add_envvar('levlaz', 'circleci-sandbox', 'foo', 'bar')) self.assertEqual(resp['name'], 'foo') self.assertNotEqual(resp['value'], 'bar') def test_get_envvar(self): self.loadMock('mock_get_envvar_response') resp = json.loads(self.c.get_envvar('levlaz', 'circleci-sandbox', 'foo')) self.assertEqual(resp['name'], 'foo') self.assertNotEqual(resp['value'], 'bar') def test_delete_envvar(self): self.loadMock('mock_delete_envvar_response') resp = json.loads(self.c.delete_envvar('levlaz', 'circleci-sandbox', 'foo')) self.assertEqual(resp['message'], 'ok') def test_get_latest_artifact(self): self.loadMock('mock_get_latest_artifacts_response') resp = json.loads(self.c.get_latest_artifact('levlaz', 'circleci-sandbox')) self.assertEqual(resp[0]['path'],'circleci-docs/index.html') resp = json.loads(self.c.get_latest_artifact('levlaz', 'circleci-sandbox', 'master')) self.assertEqual(resp[0]['path'],'circleci-docs/index.html') with self.assertRaises(InvalidFilterError): self.c.get_latest_artifact('levlaz', 'circleci-sandbox', 'master', 'invalid')
class CircleCI(IntervalModule): """ Get current status of circleci builds Requires `circleci` `dateutil.parser` Formatters: * `{repo_slug}` - repository owner/repository name * `{repo_status}` - repository status * `{repo_name}` - repository name * `{repo_owner}` - repository owner * `{last_build_started}` - date of the last finished started * `{last_build_duration}` - duration of the last build, not populated with workflows(yet) Examples .. code-block:: python status_color_map = { 'passed': '#00FF00', 'failed': '#FF0000', 'errored': '#FFAA00', 'cancelled': '#EEEEEE', 'started': '#0000AA', } .. code-block:: python repo_status_map={ 'success': '<span color="#00af00">success</span>', 'running': '<span color="#0000af">running</span>', 'failed': '<span color="#af0000">failed</span>', } """ settings = ( 'format', ('circleci_token', 'circleci access token'), ('repo_slug', 'repository identifier eg. "enkore/i3pystatus"'), ('time_format', 'passed directly to .strftime() for `last_build_started`'), ('repo_status_map', 'map representing how to display status'), ('duration_format', '`last_build_duration` format string'), ('status_color_map', 'color for all text based on status'), ('color', 'color for all text not otherwise colored'), ('workflow_name', '[WORKFLOWS_ONLY] if specified, monitor this workflows status. if not specified this module ' 'will default to reporting the status of your last build'), ('workflow_branch', '[WORKFLOWS_ONLY] if specified, monitor the workflows in this branch')) required = ('circleci_token', 'repo_slug') format = '{repo_owner}/{repo_name}-{repo_status} [({last_build_started}({last_build_duration}))]' short_format = '{repo_name}-{repo_status}' time_format = '%m/%d' duration_format = '%m:%S' status_color_map = None repo_slug = None circleci_token = None repo_status_map = None color = '#DDDDDD' workflow_name = None workflow_branch = None circleci = None on_leftclick = 'open_build_webpage' def init(self): self.repo_status = None self.last_build_duration = None self.last_build_started = None self.repo_owner, self.repo_name = self.repo_slug.split('/') self.workflows = self.workflow_name is not None or self.workflow_branch is not None def _format_time(self, time): _datetime = dateutil.parser.parse(time) return _datetime.strftime(self.time_format) @require(internet) def run(self): if self.circleci is None: self.circleci = Api(self.circleci_token) if self.workflows: if self.workflow_branch and not self.workflow_name: self.output = dict( full_text='workflow_name must be specified!' ) return project = {p['reponame']: p for p in self.circleci.get_projects()}.get(self.repo_name) if not self.workflow_branch: self.workflow_branch = project.get('default_branch') workflow_info = project['branches'].get(self.workflow_branch)['latest_workflows'].get(self.workflow_name) self.last_build_started = self._format_time(workflow_info.get('created_at')) self.repo_status = workflow_info.get('status') self.last_build_duration = '' # TODO: gather this information once circleCI exposes it else: self.repo_summary = self.circleci.get_project_build_summary( self.repo_owner, self.repo_name, limit=1) if len(self.repo_summary) != 1: return self.repo_summary = self.repo_summary[0] self.repo_status = self.repo_summary.get('status') self.last_build_started = self._format_time(self.repo_summary.get('queued_at')) try: self.last_build_duration = TimeWrapper( self.repo_summary.get('build_time_millis') / 1000, default_format=self.duration_format) except TypeError: self.last_build_duration = 0 if self.repo_status_map: self.repo_status = self.repo_status_map.get(self.repo_status, self.repo_status) self.output = dict( full_text=formatp(self.format, **vars(self)), short_text=self.short_format.format(**vars(self)), ) if self.status_color_map: self.output['color'] = self.status_color_map.get(self.repo_status, self.color) else: self.output['color'] = self.color def open_build_webpage(self): if self.repo_summary.get('workflows'): url_format = 'workflow-run/{}'.format(self.repo_summary['workflows']['workflow_id']) else: url_format = 'gh/{repo_owner}/{repo_name}/{job_number}' os.popen('xdg-open https:/circleci.com/{} > /dev/null' .format(url_format))
""" ld_lambda Process LaunchDarkly webhooks to trigger a CI build when a new environment is created. """ import os import json import logging from circleci.api import Api logger = logging.getLogger() logger.setLevel(logging.INFO) circleci = Api(os.environ.get("CIRCLE_TOKEN")) def trigger_deloy(): params = { 'build_parameters[CIRCLE_JOB]': 'deploy' } circleci.trigger_build( username='******', project='SupportService', params=params ) def handler(event, context): """ AWS Lambda Handler """
class CircleCIHelper: def __init__(self, token): try: self.ci = Api(token) self.username = self.ci.get_user_info()['login'] app.logger.info("Initialised connection to Circleci with user: %s", self.username) return None except Exception as e: app.logger.error( "Unable to initialise connection to CircleCi api: %s", repr(e)) return None def get_own_projects(self, include_branches=False): try: projects = [] for project in self.ci.get_projects(): if (include_branches): branches = [] for branch in project['branches']: branches.append(branch) projects.append({ "name": project['username'] + "/" + project['reponame'], "branches": branches }) else: projects.append({ "name": project['username'] + "/" + project['reponame'] }) return projects except Exception as e: app.logger.error("Unable to get user own projects: %s", repr(e)) return [] def get_latest_project_builds(self, username, project): try: recent_builds = [] for build in self.ci.get_project_build_summary(username, project): recent_builds.append({ "build_num": build['build_num'], "branch": build['branch'], "status": build['status'], "build_time_ms": build['build_time_millis'], "start_time": build['start_time'] }) return recent_builds except Exception as e: app.logger.error( "Unable to get user '%s' latest project '%s' builds: %s", username, project, repr(e)) return []
def __init__(self, token, user='******', project='connectedhomeip'): self.api = Api(token) self.user = user self.project = project self.vcs_type = 'github'
import logging import paho.mqtt.client as mqtt from circleci.api import Api from ruamel.yaml import YAML logging.basicConfig(level=logging.INFO, format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s") CONFIG_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'config.yaml') LOGGER = logging.getLogger('lamp') LOGGER.info("Loading config: " + CONFIG_PATH) CONFIG = YAML(typ='safe').load(open(CONFIG_PATH)) circleci = Api(CONFIG['circle_token']) client = mqtt.Client() if 'username' in CONFIG: client.username_pw_set(CONFIG['username'], CONFIG['password']) client.connect(CONFIG['host'], CONFIG['port'], 60) client.loop_start() try: while True: LOGGER.info("Fetching build status...") build = circleci.get_recent_builds()[0] status = build['status'] LOGGER.info("Status is: {}".format(status)) client.publish(CONFIG['topic'], status, 2, True) time.sleep(5)
def on_event(self, event, extension): """ Handle event """ extension.circle = Api(event.preferences['api_token'])
def on_event(self, event, extension): """ Event handler """ if event.id == 'api_token': extension.circle = Api(event.new_value)
from collections import defaultdict import json import os from circleci.api import Api DESTDIR = os.environ.get('DESTDIR', None) CIRCLE_TOKEN = os.environ.get('CIRCLE_TOKEN', None) assert len(CIRCLE_TOKEN) >= 1, "Missing CIRCLE_TOKEN environment variable." circleci = Api(CIRCLE_TOKEN) def find_most_recent_store_builds(store_job_name_prefix='store-'): all_recent_builds = circleci.get_project_build_summary( username='******', project='tf-big', limit=50, status_filter=None, branch='master', vcs_type='github', ) commit_filter = None most_recent_store_builds = list() for build in all_recent_builds: job_name = build['workflows']['job_name'] commit = build['all_commit_details'][0]['commit']