cancel previous builds for the same revisions
using metadata tags set in #298 finds and cancels existing builds before starting a new one. One caveat is that no result is reported back to Phabricator for the cancelled build. That should not be an issue in the normal usecase. For #278
This commit is contained in:
parent
6b731dc4d5
commit
1c04f70eb9
3 changed files with 26 additions and 34 deletions
|
@ -78,6 +78,9 @@ class BuildkiteApi:
|
|||
# https://buildkite.com/docs/apis/rest-api/builds#get-a-build
|
||||
return benedict(self.get(f'https://api.buildkite.com/v2/organizations/{self.organization}/pipelines/{pipeline}/builds/{build_number}').json())
|
||||
|
||||
def list_running_revision_builds(self, pipeline: str, rev: str):
|
||||
return self.get(f'https://api.buildkite.com/v2/organizations/{self.organization}/pipelines/{pipeline}/builds?state[]=scheduled&state[]=running&meta_data[ph_buildable_revision]={rev}').json()
|
||||
|
||||
@backoff.on_exception(backoff.expo, Exception, max_tries=3, logger='', factor=3)
|
||||
def get(self, url: str):
|
||||
authorization = f'Bearer {self.token}'
|
||||
|
@ -86,6 +89,15 @@ class BuildkiteApi:
|
|||
raise Exception(f'Buildkite responded with non-OK status: {response.status_code}')
|
||||
return response
|
||||
|
||||
# cancel a build. 'build' is a json object returned by API.
|
||||
def cancel_build(self, build):
|
||||
build = benedict(build)
|
||||
url = f'https://api.buildkite.com/v2/organizations/{self.organization}/pipelines/{build.get("pipeline.slug")}/builds/{build.get("number")}/cancel'
|
||||
authorization = f'Bearer {self.token}'
|
||||
response = requests.put(url, headers={'Authorization': authorization})
|
||||
if response.status_code != 200:
|
||||
raise Exception(f'Buildkite responded with non-OK status: {response.status_code}')
|
||||
|
||||
|
||||
def format_url(url: str, name: Optional[str] = None):
|
||||
if name is None:
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
# Copyright 2020 Google LLC
|
||||
#
|
||||
# Licensed under the the Apache License v2.0 with LLVM Exceptions (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://llvm.org/LICENSE.txt
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import os
|
||||
import requests
|
||||
|
||||
def main(review_number, api_key):
|
||||
buildkite = requests.Session()
|
||||
buildkite.headers.update({'Authorization': 'Bearer {}'.format(api_key)})
|
||||
api = lambda query: 'https://api.buildkite.com/v2' + query
|
||||
|
||||
builds = buildkite.get(api('/organizations/llvm-project/builds?state[]=scheduled&state[]=running')).json()
|
||||
for build in builds:
|
||||
if build['message'] == review_number:
|
||||
pipeline = build['pipeline']['slug']
|
||||
buildkite.put(api('/organizations/llvm-project/pipelines/{}/builds/{}/cancel'.format(pipeline, build['number'])))
|
||||
|
||||
if __name__ == '__main__':
|
||||
review_number = 'D{}'.format(os.getenv('ph_buildable_revision'))
|
||||
api_key = # TODO where do we get that? The agents on the service queue need to have the proper access (read_builds and write_builds)
|
||||
main(review_number, api_key)
|
|
@ -15,7 +15,9 @@
|
|||
|
||||
import os
|
||||
import yaml
|
||||
from buildkite_utils import annotate, feedback_url, set_metadata
|
||||
import logging
|
||||
from buildkite_utils import set_metadata, BuildkiteApi
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
diff_id = os.getenv("ph_buildable_diff")
|
||||
|
@ -23,6 +25,17 @@ if __name__ == '__main__':
|
|||
base_commit = os.getenv('ph_base_commit', 'auto')
|
||||
run_build = os.getenv('ph_skip_build') is None
|
||||
trigger = os.getenv('ph_trigger_pipeline')
|
||||
logging.basicConfig(level=log_level, format='%(levelname)-7s %(message)s')
|
||||
|
||||
# Cancel any existing builds.
|
||||
# Do this before setting own 'ph_buildable_revision'.
|
||||
try:
|
||||
bk = BuildkiteApi(os.getenv("BUILDKITE_API_TOKEN"), os.getenv("BUILDKITE_ORGANIZATION_SLUG"))
|
||||
for b in bk.list_running_revision_builds(os.getenv("BUILDKITE_PIPELINE_SLUG"), os.getenv('ph_buildable_revision')):
|
||||
logging.info(f'cancelling build {b.get("web_url")}')
|
||||
bk.cancel_build(b)
|
||||
except Exception as e:
|
||||
logging.error(e)
|
||||
|
||||
set_metadata('ph_buildable_diff', os.getenv("ph_buildable_diff"))
|
||||
set_metadata('ph_buildable_revision', os.getenv('ph_buildable_revision'))
|
||||
|
|
Loading…
Reference in a new issue