diff --git a/.github/workflows/actions/ado_tag/action.yml b/.github/workflows/actions/ado_tag/action.yml index c18a259..343a97c 100644 --- a/.github/workflows/actions/ado_tag/action.yml +++ b/.github/workflows/actions/ado_tag/action.yml @@ -20,6 +20,8 @@ runs: if: ${{ github.event_name == 'workflow_run' && github.event.workflow_run.event != 'workflow_dispatch' }} shell: bash run: | + az extension add --name azure-devops + az devops configure --defaults organization=https://dev.azure.com/lukaszadamsielski0187 python /home/runner/work/workflows_tests/workflows_tests/scripts/script.py --commit-sha ${{ github.event.workflow_run.head_sha }} --deploy_env ${{ inputs.deploy_env }} # - id: failing_step # continue-on-error: true diff --git a/scripts/az_cli.py b/scripts/az_cli.py new file mode 100644 index 0000000..fc17ec1 --- /dev/null +++ b/scripts/az_cli.py @@ -0,0 +1,15 @@ +import subprocess +from subprocess import check_output, CalledProcessError + +class AzCli: + + def tag_work_items(work_items_ids: list[str], tag: str): + update_result = {} + for work_item_id in work_items_ids: + output = None + try: + output = check_output(f'az boards work-item update --id {work_item_id} --fields "System.Tags={tag}', shell=True, stderr=subprocess.STDOUT) + except CalledProcessError as e: + update_result.update({work_item_id: e.stderr}) + update_result.update({work_item_id: output}) + print(update_result) \ No newline at end of file diff --git a/scripts/gh_cli.py b/scripts/gh_cli.py index b11b2ba..786e493 100644 --- a/scripts/gh_cli.py +++ b/scripts/gh_cli.py @@ -1,24 +1,24 @@ import re import subprocess import json +from enum import Enum + +class PrState(str, Enum): + OPEN = 'open' + CLOSED = 'closed' + MERGED = 'merged' + ALL = 'all' class GitHubCli: - def extract_pr_body(self, commit_sha: str) -> str: + def extract_pr_body(self, commit_sha: str, pr_state: PrState) -> str: prDetails = None try: - prDetails = subprocess.check_output(f'gh pr list --json body --state merged --search {commit_sha}', shell=True, text=True) + prDetails = subprocess.check_output(f'gh pr list --json body --state {pr_state.value} --search {commit_sha}', shell=True, text=True) except subprocess.CalledProcessError as e: raise Exception(f'Failed to retrieve PR body! {e.stderr}') prDetailsJson = json.loads(prDetails) - print(prDetailsJson) return prDetailsJson[0]['body'] if len(prDetailsJson) != 0 else '' - def extract_data_from_pr_body(self, commit_sha: str, pattern: re.Pattern) -> list[str]: - print(self.extract_pr_body(commit_sha)) - return re.findall(pattern, self.extract_pr_body(commit_sha)) - - - - - \ No newline at end of file + def extract_data_by_pattern_from_pr_body(self, commit_sha: str, pr_state: PrState, pattern: re.Pattern) -> list[str]: + return re.findall(pattern, self.extract_pr_body(commit_sha, pr_state)) \ No newline at end of file diff --git a/scripts/script.py b/scripts/script.py index fabe04f..ab27707 100644 --- a/scripts/script.py +++ b/scripts/script.py @@ -1,29 +1,13 @@ import argparse import subprocess -import json -import re -from gh_cli import GitHubCli - -def constant(f): - def fset(self, value): - raise TypeError - def fget(self): - return f() - return property(fget, fset) +from gh_cli import GitHubCli, PrState +from az_cli import AzCli class _Const(object): - @constant - def GET_PR_DETAILS_CLI_COMMAND() -> str: - return 'gh pr list --json body --state merged --search {commit_sha}' - @constant - def ADO_TAG_PATTERN() -> re.Pattern: - return r"AB#\d{1}" - @constant def ADO_TAGGING_COMMAND() -> str: return 'az boards work-item update --id {work_item_id} --org https://dev.azure.com/lukaszadamsielski0187 --fields "System.Tags={deploy_env}" --output json' CONST = _Const() -GH_CLI = GitHubCli() def parseArguments(): parser = argparse.ArgumentParser(description="Utility to tag ADO workitem with deployment environemnt", exit_on_error=False) @@ -31,18 +15,6 @@ def parseArguments(): parser.add_argument('--deploy_env', type=str, required=True, dest='deploy_env') return parser.parse_args() -def extractWorkItemIdFromPR(commitSha): - extractPrBodyCommand = CONST.GET_PR_DETAILS_CLI_COMMAND.format(commit_sha = commitSha) - - prBodySubprocessResponse = subprocess.run(extractPrBodyCommand, capture_output=True, shell=True, text=True) - if prBodySubprocessResponse.returncode != 0: - raise Exception('Failed to retrieve PR body for commit identified by {} SHA! Reason: {}'.format(commitSha, prBodySubprocessResponse.stderr)) - adoTagsFromPrBody = re.findall(CONST.ADO_TAG_PATTERN, json.loads(prBodySubprocessResponse.stdout)[0]['body']) - if len(adoTagsFromPrBody) != 1: - raise Exception('Could not retrieve ADO tag from PR body or there is more than one!') - - return adoTagsFromPrBody[0].split('#')[1] - def tagAdoWorkItem(workItemId: str, deploymentEnv: str): adoTaggingCommand = CONST.ADO_TAGGING_COMMAND.format(work_item_id = workItemId, deploy_env = deploymentEnv) @@ -53,12 +25,14 @@ def tagAdoWorkItem(workItemId: str, deploymentEnv: str): def main(): args = parseArguments() + gh_cli = GitHubCli() + az_cli = AzCli() commitSha = args.commit_sha deploymentEnv = args.deploy_env # tagAdoWorkItem(extractWorkItemIdFromPR(commitSha), deploymentEnv) - x = GH_CLI.extract_data_from_pr_body(commitSha, r'AB#(\d+)') - print(x) - + workItemsIds = gh_cli.extract_data_by_pattern_from_pr_body(commitSha, PrState.MERGED, r'AB#(\d+)') + az_cli.tag_work_items(workItemsIds, deploymentEnv) + if __name__ == '__main__': try: main()