diff --git a/.github/actions/smart-ci/action.yml b/.github/actions/smart-ci/action.yml index 23717c9dde50ce..ebe420d4ef301a 100644 --- a/.github/actions/smart-ci/action.yml +++ b/.github/actions/smart-ci/action.yml @@ -13,6 +13,9 @@ inputs: commit_sha: description: "GitHub commit hash. Used if no PR number is set" required: false + ref_name: + description: "GitHub ref name" + required: false component_pattern: description: "Pattern to extract component name from PR label. If not set, any label is considered a component name" required: false @@ -88,6 +91,7 @@ runs: python ${{ github.action_path }}/smart_ci.py \ $([[ -n "${{ inputs.pr }}" ]] && echo '--pr ${{ inputs.pr }}' || echo '-s ${{ inputs.commit_sha }}') \ -r ${{ inputs.repository }} \ + -f "${{ inputs.ref_name }}" \ -p "${{ inputs.component_pattern }}" \ -c "${{ inputs.components_config }}" \ -m "${{ inputs.components_config_schema }}" \ diff --git a/.github/actions/smart-ci/smart_ci.py b/.github/actions/smart-ci/smart_ci.py index fc88294247c221..ae6786d9882bad 100644 --- a/.github/actions/smart-ci/smart_ci.py +++ b/.github/actions/smart-ci/smart_ci.py @@ -109,11 +109,26 @@ def get_changed_component_names(pr, all_possible_components: set, component_patt return components +def get_changeset(gh_api, pr, target_branch, commit_sha): + """Returns changeset either from PR or commit""" + if pr: + return gh_api.pulls.list_files(pr) + if target_branch: + target_branch_head_commit = gh_api.repos.get_branch(target_branch).commit.sha + # In merge-queue branch all commits between head of target branch and head of current branch (commit_sha) + # contain changes added to queue earlier to be validated together. Getting all of them + changes from + # commit_sha below + changed_files = gh_api.repos.compare_commits(f'{target_branch_head_commit}...{commit_sha}').get('files', []) + return changed_files + raise ValueError(f'Either "pr" or "target_branch" parameter must be non-empty') + + def parse_args(): parser = argparse.ArgumentParser(description='Returns product components changed in a given PR or commit') parser.add_argument('--pr', type=int, required=False, help='PR number. If not set, --commit is used') parser.add_argument('-s', '--commit-sha', required=False, help='Commit SHA. If not set, --pr is used') parser.add_argument('-r', '--repo', help='GitHub repository') + parser.add_argument('-f', '--ref_name', required=False, help='GitHub ref name') parser.add_argument('-p', '--pattern', default=None, help='Pattern to extract component name from PR label. ' 'If not set, any label is considered a component name') parser.add_argument('-c', '--components-config', default='.github/components.yml', @@ -172,18 +187,27 @@ def main(): component_name = component_name_from_label(label, args.pattern) all_possible_components.add(component_name if component_name else label) - no_match_files_changed = False + run_full_scope = False # For now, we don't want to apply smart ci rules for post-commits is_postcommit = not pr - if is_postcommit: + + merge_queue_prefix = 'gh-readonly-queue/' + is_merge_queue = args.ref_name.startswith(merge_queue_prefix) + merge_queue_target_branch = re.findall(f'^{merge_queue_prefix}(.*)/', args.ref_name)[0] if is_merge_queue else None + + if is_merge_queue: + logger.info(f"The run is a merge-queue run, executing full validation scope for all components, if " + f"not all queued changes match patterns in 'skip-when-only-listed-files-changed'") + run_full_scope = True + elif is_postcommit: logger.info(f"The run is a post-commit run, executing full validation scope for all components") + run_full_scope = True else: no_match_files_changed = 'no-match-files' in [label.name for label in pr.labels] if no_match_files_changed: logger.info(f"There are changed files that don't match any pattern in labeler config, " f"executing full validation scope for all components") - - run_full_scope = is_postcommit or no_match_files_changed + run_full_scope = True # In post-commits - validate all components regardless of changeset # In pre-commits - validate only changed components with their dependencies @@ -197,7 +221,7 @@ def main(): affected_components = cfg.get_affected_components(changed_component_names) skip_workflow = False - if args.pr and not run_full_scope: + if is_merge_queue or (args.pr and not run_full_scope): if args.skip_when_only_listed_labels_set: excepted_labels = set(args.skip_when_only_listed_labels_set.split(',')) excepted_labels_only = changed_component_names - excepted_labels == set() @@ -205,7 +229,7 @@ def main(): if not skip_workflow and args.skip_when_only_listed_files_changed: # To avoid spending extra API requests running step below only if necessary - changed_files = gh_api.pulls.list_files(args.pr) + changed_files = get_changeset(gh_api, args.pr, merge_queue_target_branch, args.commit_sha) patterns = set(args.skip_when_only_listed_files_changed.split(',')) matched_files_only = all(any(fnmatch(f.filename, pattern) for pattern in patterns) for f in changed_files) diff --git a/.github/workflows/android_arm64.yml b/.github/workflows/android_arm64.yml index a8deb0e3d476e1..d313929a1b016e 100644 --- a/.github/workflows/android_arm64.yml +++ b/.github/workflows/android_arm64.yml @@ -31,6 +31,7 @@ jobs: repository: ${{ github.repository }} pr: ${{ github.event.number }} commit_sha: ${{ github.sha }} + ref_name: ${{ github.ref_name }} component_pattern: "category: (.*)" repo_token: ${{ secrets.GITHUB_TOKEN }} skip_when_only_listed_labels_set: 'docs' diff --git a/.github/workflows/fedora.yml b/.github/workflows/fedora.yml index 84434981be989d..7863d04f47dac4 100644 --- a/.github/workflows/fedora.yml +++ b/.github/workflows/fedora.yml @@ -31,6 +31,7 @@ jobs: repository: ${{ github.repository }} pr: ${{ github.event.number }} commit_sha: ${{ github.sha }} + ref_name: ${{ github.ref_name }} component_pattern: "category: (.*)" repo_token: ${{ secrets.GITHUB_TOKEN }} skip_when_only_listed_labels_set: 'docs' diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 319abaa44d564a..4e37bfe6b6c0da 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -38,6 +38,7 @@ jobs: repository: ${{ github.repository }} pr: ${{ github.event.number }} commit_sha: ${{ github.sha }} + ref_name: ${{ github.ref_name }} component_pattern: "category: (.*)" repo_token: ${{ secrets.GITHUB_TOKEN }} skip_when_only_listed_labels_set: 'docs' diff --git a/.github/workflows/linux_arm64.yml b/.github/workflows/linux_arm64.yml index fd8403e0de6c53..9894bccaa48615 100644 --- a/.github/workflows/linux_arm64.yml +++ b/.github/workflows/linux_arm64.yml @@ -35,6 +35,7 @@ jobs: repository: ${{ github.repository }} pr: ${{ github.event.number }} commit_sha: ${{ github.sha }} + ref_name: ${{ github.ref_name }} component_pattern: "category: (.*)" repo_token: ${{ secrets.GITHUB_TOKEN }} skip_when_only_listed_labels_set: 'docs' diff --git a/.github/workflows/linux_conditional_compilation.yml b/.github/workflows/linux_conditional_compilation.yml index 79ac560f84b88a..d8f6edbc867803 100644 --- a/.github/workflows/linux_conditional_compilation.yml +++ b/.github/workflows/linux_conditional_compilation.yml @@ -35,6 +35,7 @@ jobs: repository: ${{ github.repository }} pr: ${{ github.event.number }} commit_sha: ${{ github.sha }} + ref_name: ${{ github.ref_name }} component_pattern: "category: (.*)" repo_token: ${{ secrets.GITHUB_TOKEN }} skip_when_only_listed_labels_set: 'docs' diff --git a/.github/workflows/linux_riscv.yml b/.github/workflows/linux_riscv.yml index 088fddccf1b210..ff8fa44c0c7ab0 100644 --- a/.github/workflows/linux_riscv.yml +++ b/.github/workflows/linux_riscv.yml @@ -34,6 +34,7 @@ jobs: repository: ${{ github.repository }} pr: ${{ github.event.number }} commit_sha: ${{ github.sha }} + ref_name: ${{ github.ref_name }} component_pattern: "category: (.*)" repo_token: ${{ secrets.GITHUB_TOKEN }} skip_when_only_listed_labels_set: 'docs' diff --git a/.github/workflows/mac.yml b/.github/workflows/mac.yml index 0165980d1b2f57..c645781522039e 100644 --- a/.github/workflows/mac.yml +++ b/.github/workflows/mac.yml @@ -52,6 +52,7 @@ jobs: repository: ${{ github.repository }} pr: ${{ github.event.number }} commit_sha: ${{ github.sha }} + ref_name: ${{ github.ref_name }} component_pattern: "category: (.*)" repo_token: ${{ secrets.GITHUB_TOKEN }} skip_when_only_listed_labels_set: 'docs' diff --git a/.github/workflows/mac_arm64.yml b/.github/workflows/mac_arm64.yml index 64873a9b104138..4e7ed1c2a24d49 100644 --- a/.github/workflows/mac_arm64.yml +++ b/.github/workflows/mac_arm64.yml @@ -51,6 +51,7 @@ jobs: repository: ${{ github.repository }} pr: ${{ github.event.number }} commit_sha: ${{ github.sha }} + ref_name: ${{ github.ref_name }} component_pattern: "category: (.*)" repo_token: ${{ secrets.GITHUB_TOKEN }} skip_when_only_listed_labels_set: 'docs' diff --git a/.github/workflows/webassembly.yml b/.github/workflows/webassembly.yml index c5d94f267e4298..135e6a76c49fbb 100644 --- a/.github/workflows/webassembly.yml +++ b/.github/workflows/webassembly.yml @@ -31,6 +31,7 @@ jobs: repository: ${{ github.repository }} pr: ${{ github.event.number }} commit_sha: ${{ github.sha }} + ref_name: ${{ github.ref_name }} component_pattern: "category: (.*)" repo_token: ${{ secrets.GITHUB_TOKEN }} skip_when_only_listed_labels_set: 'docs' diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index e25ff48ca31128..ff7ae0310aaaec 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -34,6 +34,7 @@ jobs: repository: ${{ github.repository }} pr: ${{ github.event.number }} commit_sha: ${{ github.sha }} + ref_name: ${{ github.ref_name }} component_pattern: "category: (.*)" repo_token: ${{ secrets.GITHUB_TOKEN }} skip_when_only_listed_labels_set: 'docs' diff --git a/.github/workflows/windows_conditional_compilation.yml b/.github/workflows/windows_conditional_compilation.yml index 7780e50eedc894..af156906db340a 100644 --- a/.github/workflows/windows_conditional_compilation.yml +++ b/.github/workflows/windows_conditional_compilation.yml @@ -37,6 +37,7 @@ jobs: repository: ${{ github.repository }} pr: ${{ github.event.number }} commit_sha: ${{ github.sha }} + ref_name: ${{ github.ref_name }} component_pattern: "category: (.*)" repo_token: ${{ secrets.GITHUB_TOKEN }} skip_when_only_listed_labels_set: 'docs'