diff --git a/actions/cancel_old_builds.yaml b/actions/cancel_old_builds.yaml new file mode 100644 index 0000000..5b0ca6f --- /dev/null +++ b/actions/cancel_old_builds.yaml @@ -0,0 +1,15 @@ +--- +name: cancel_old_builds_for_pr +description: Action which looks for old st2_pkg_e2e_test builds for a particular builds and cancel any old / existing build. +enabled: true +runner_type: python-script +entry_point: cancel_old_builds_for_pr.py +parameters: + build_num: + type: string + description: "Circle CI build number." + required: true + pr_num: + type: string + description: "Github pull request number" + required: true diff --git a/actions/cancel_old_builds_for_pr.py b/actions/cancel_old_builds_for_pr.py new file mode 100644 index 0000000..85b1612 --- /dev/null +++ b/actions/cancel_old_builds_for_pr.py @@ -0,0 +1,94 @@ +import os + +from st2common.runners.base_action import Action + +from st2client.client import Client + +ACTION_REF = 'st2ci.st2_pkg_e2e_test' + + +class CancelOldBuildsForPrAction(Action): + def run(self, build_num, pr_num): + if not build_num or not pr_num: + self.logger.info('Skipping old build cancelation because pr num or build num is not ' + 'set') + return + + build_num = int(build_num) + pr_num = int(pr_num) + + # 1. Find any matching executions + client = self._get_client() + + execution_apis = client.liveactions.query(action=ACTION_REF, status='running', limit=100, + include_attributes='id,status,parameters') + + to_cancel_execution_apis = self._filter_executions(execution_apis, + current_build_num=build_num, + current_pr_num=pr_num) + + to_cancel_execution_apis = execution_apis + self.logger.info('Found "%s" old execution(s) for PR "%s" to be canceled' % + (len(to_cancel_execution_apis), pr_num)) + # Make sure we exclude current one and not cancel the current / latest one + + # 2. Cancel old ones + for execution_api in to_cancel_execution_apis: + msg = ('Canceling old execution with id "%s" for PR "%s" (build_num %s < ' + 'current_build_num %s)' % (execution_api.id, pr_num, + execution_api.parameters['pr_num'], pr_num)) + self.logger.info(msg) + client.liveactions.delete_by_id(execution_api.id) + + # TODO: We should probably also ensure here that cleanup task is also called.. + + def _filter_executions(self, execution_apis, current_build_num, current_pr_num): + # Filter the executions and only return old ones + result = [] + + for execution_api in execution_apis: + parameters = execution_api.parameters + + build_num = int(parameters.get('build_num', 0)) + pr_num = int(parameters.get('pr_num', 0)) + + # Additional safety check to make sure we don't cancel current build + if build_num == current_build_num: + continue + + # Skip executions for other PRs + # Builds without pr_num set are not triggered as part of a PR build but via nightly + # builds or similar so we also skip those + if not pr_num or pr_num != current_pr_num: + continue + + # Execution is considered as old if build_num is < current build num + if build_num and build_num < current_build_num: + result.apend(execution_api) + + return result + + def _get_client(self): + base_url, api_url, auth_url = self._get_st2_urls() + + client_kwargs = { + 'base_url': base_url, + 'api_url': api_url, + 'auth_url': auth_url, + } + + token = self._get_auth_token() + client_kwargs['token'] = token + + return Client(**client_kwargs) + + def _get_st2_urls(self): + base_url = None + api_url = os.environ.get('ST2_ACTION_API_URL', None) + auth_url = os.environ.get('ST2_ACTION_AUTH_URL', None) + + return base_url, api_url, auth_url + + def _get_auth_token(self): + token = os.environ.get('ST2_ACTION_AUTH_TOKEN', None) + return token diff --git a/actions/st2_pkg_e2e_test.meta.yaml b/actions/st2_pkg_e2e_test.meta.yaml index 27e3386..49582b3 100644 --- a/actions/st2_pkg_e2e_test.meta.yaml +++ b/actions/st2_pkg_e2e_test.meta.yaml @@ -66,6 +66,9 @@ parameters: dev_build: type: string description: Repo name + CircleCI build number ('st2/3126') to install artifacts from. Overrides version. + pr_num: + type: string + description: Github pull request number. initial_commit: type: string description: Git hash of an initial commit from st2 repo. If provided, the workflow will update status of this commit. diff --git a/actions/workflows/st2_pkg_e2e_test.yaml b/actions/workflows/st2_pkg_e2e_test.yaml index f201eb5..d69f738 100644 --- a/actions/workflows/st2_pkg_e2e_test.yaml +++ b/actions/workflows/st2_pkg_e2e_test.yaml @@ -16,6 +16,7 @@ input: - release - version - dev_build + - pr_num - initial_commit - enterprise - enterprise_key @@ -40,7 +41,7 @@ vars: - bootstrap_script_arg_dev_or_ver: <% switch( ctx().dev_build => "dev=" + ctx().dev_build, - not ctx().dev_build => "version=" + coalesce(ctx().version, '')) %> + not ctx().dev_build => "version=" + coalesce(ctx().version, '')) %> - st2_username: st2admin - st2_password: Ch@ngeMe - github_status_org: StackStorm @@ -67,7 +68,11 @@ tasks: next: - when: <% ctx().initial_commit != null %> do: set_github_status_pending - - when: <% ctx().initial_commit = null %> + # NOTE: We skip cancelation of old builds for executions which are not triggered as part of + # PR builds (e.g. nightly package builds) + - when: <% ctx().initial_commit = null and ctx().pr_num %> + do: cancel_old_builds_for_pr + - when: <% ctx().initial_commit = null and not ctx().pr_num %> do: create_vm set_github_status_pending: action: github.add_status @@ -80,9 +85,21 @@ tasks: description: E2E tests are running... target_url: <% ctx().github_status_url %> next: - - when: <% succeeded() %> + # NOTE: We skip cancelation of old builds for executions which are not triggered as part of + # PR builds (e.g. nightly package builds) + - when: <% succeeded() and ctx().pr_num %> + do: cancel_old_builds_for_pr + - when: <% succeeded() and not ctx().pr_num %> do: create_vm + cancel_old_builds_for_pr: + action: st2ci.cancel_old_builds_for_pr + input: + build_num: <% ctx().dev_build %> + pr_num: <% ctx().pr_num %> + next: + - do: + - create_vm create_vm: action: st2cd.create_vm_role input: diff --git a/rules/st2_pkg_e2e_test_centos7_on_st2_pr.yaml b/rules/st2_pkg_e2e_test_centos7_on_st2_pr.yaml index 9147c00..4a13ca4 100644 --- a/rules/st2_pkg_e2e_test_centos7_on_st2_pr.yaml +++ b/rules/st2_pkg_e2e_test_centos7_on_st2_pr.yaml @@ -42,6 +42,7 @@ action: pkg_env: staging release: unstable dev_build: "st2/{{trigger.body.payload.build_num}}" + pr_num: {{trigger.body.payload.pull_requests[0].url.split('/')[-1]}} initial_commit: "{{trigger.body.payload.vcs_revision}}" triggering_commit_url: | COMMITTER: {{trigger.body.payload.author_name}}