diff options
author | Daniel Smith <[email protected]> | 2025-05-09 10:12:39 +0200 |
---|---|---|
committer | Daniel Smith <[email protected]> | 2025-06-30 09:56:47 +0000 |
commit | c4452b03d784239e5d953c16891efe6c28a4fa43 (patch) | |
tree | 8ddb15faffdb9683fcd275a829899ff2a6fd680c /main.py | |
parent | d31c4e4313f266e39ddf9b26113d6bdea3fe7bb0 (diff) |
Rarely, it may be desirable to force skipping a certian module
even if it might be considered broken. This feature must be
used with extreme caution, as it may lead to an inconsistent
state of the submodule set.
Use of this feature should be limited to cases where the module
is in a known-good state, but blocked from updating in CI
by a known failure mode which does not affect the release
process, and would not place the module in a qt5.git snapshot
in a bad state.
Fixes: QTQAINFRA-7164
Change-Id: Ic4a6e1f4db2e558f6ebe94dfc6ccd3d280ce5e33
Reviewed-by: Daniel Smith <[email protected]>
Diffstat (limited to 'main.py')
-rw-r--r-- | main.py | 70 |
1 files changed, 68 insertions, 2 deletions
@@ -4,8 +4,10 @@ import argparse import os import sys -import yaml import json +import base64 +import yaml +from gerrit.utils import exceptions as GerritExceptions from tools import Namespace, config as Config, state, toolbox, dependency_resolver, repo as Repo @@ -81,6 +83,10 @@ def parse_args(print_help: bool = False) -> Namespace: help="List of non-blocking repos to update. These will be included in the\n" "round but will not cause a failure if they fail to integrate unless\n" "another blocking module depends on it.") + parser.add_argument('--skip-module', dest='skip_module', type=str, + help="Specify a module to skip, using its current SHA from qt5.git's\n" + "submodule reference. The module will be marked as DONE_NO_UPDATE.\n" + "This action happens before dependency resolution for the current run.") if print_help: parser.print_help() args = parser.parse_args() @@ -154,6 +160,66 @@ def main(): # Update the working state with any newly added repos passed to the script. config.state_data = state.update_state_data(config.state_data, repos) + # Handle --skip-module argument + if config.args.skip_module: + skipped_module_name = config.args.skip_module + if skipped_module_name in config.state_data: + skipped_repo = config.state_data[skipped_module_name] + print(f"INFO: Attempting to skip module {skipped_module_name} as per --skip-module argument.") + + qt5_submodule_sha = None + try: + gerrit = config.datasources.gerrit_client + # Determine the name of the submodule file in qt5.git (e.g., 'qtwayland' for 'qt/qtwayland') + # Repo.name is id.removeprefix(prefix) + submodule_file_name = skipped_repo.id.removeprefix(skipped_repo.prefix) + if not submodule_file_name: # Should not happen if prefix is correct + submodule_file_name = skipped_repo.id.split('/')[-1] + + qt5_supermodule_name = f"{config.args.repo_prefix}qt5" + target_branch_for_qt5_lookup = skipped_repo.branch or config.args.branch + + file_content_raw = gerrit.projects.get(qt5_supermodule_name).branches.get( + f"refs/heads/{target_branch_for_qt5_lookup}" + ).get_file_content(submodule_file_name) + qt5_submodule_sha = bytes.decode(base64.b64decode(file_content_raw), "utf-8").strip() + except GerritExceptions.NotFoundError: + print(f"WARN: Could not find submodule {submodule_file_name} in {qt5_supermodule_name} " + f"for branch {target_branch_for_qt5_lookup} to get its SHA. Cannot skip.") + except Exception as e: + print(f"WARN: Error fetching SHA for {submodule_file_name} from {qt5_supermodule_name}: {e}. Cannot skip.") + + if qt5_submodule_sha: + print(f"INFO: Setting {skipped_module_name} to use SHA {qt5_submodule_sha} from {qt5_supermodule_name} submodule reference.") + skipped_repo.progress = Repo.PROGRESS.DONE_NO_UPDATE + skipped_repo.proposal.merged_ref = qt5_submodule_sha + skipped_repo.original_ref = qt5_submodule_sha # Align original_ref as well + + # Fetch and set deps_yaml and proposal.proposed_yaml from this specific SHA + try: + yaml_content_raw = gerrit.projects.get(skipped_repo.id).get_commit(qt5_submodule_sha).get_file_content('dependencies.yaml') + yaml_text = bytes.decode(base64.b64decode(yaml_content_raw), "utf-8") + parsed_yaml = yaml.safe_load(yaml_text) + skipped_repo.deps_yaml = parsed_yaml + skipped_repo.proposal.proposed_yaml = parsed_yaml + print(f"INFO: Updated deps_yaml for {skipped_module_name} from SHA {qt5_submodule_sha}.") + except GerritExceptions.NotFoundError: + print(f"WARN: No dependencies.yaml found for {skipped_module_name} at SHA {qt5_submodule_sha}. Using empty.") + skipped_repo.deps_yaml = {"dependencies": {}} + skipped_repo.proposal.proposed_yaml = {"dependencies": {}} + except yaml.YAMLError as e: + print(f"WARN: Could not parse dependencies.yaml for {skipped_module_name} at SHA {qt5_submodule_sha}: {e}. Using empty.") + skipped_repo.deps_yaml = {"dependencies": {}} + skipped_repo.proposal.proposed_yaml = {"dependencies": {}} + except Exception as e: # Catch other potential errors like base64 decoding + print(f"WARN: Error processing dependencies.yaml for {skipped_module_name} at SHA {qt5_submodule_sha}: {e}. Using empty.") + skipped_repo.deps_yaml = {"dependencies": {}} + skipped_repo.proposal.proposed_yaml = {"dependencies": {}} + else: + print(f"WARN: Could not determine SHA for {skipped_module_name} from {qt5_supermodule_name}. Module will not be skipped.") + else: + print(f"WARN: Module '{config.args.skip_module}' specified via --skip-module not found in current state or repo list. Ignoring.") + # Update the progress of all repos in the state since the last run of the tool. changes_since_last_run = False for repo in config.state_data.values(): @@ -376,4 +442,4 @@ def main(): if __name__ == '__main__': - main()
\ No newline at end of file + main() |