aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Smith <daniel.smith@qt.io>2024-09-19 11:03:53 +0200
committerDaniel Smith <daniel.smith@qt.io>2024-10-14 06:23:14 +0000
commit03969b2c3907cac183b03869b74795d2cd3c7397 (patch)
treea7e7d7d0bcdd89dec796d1051c052336793be370
parentb77375de3773cb62210d9be82a00177c2433085f (diff)
Enable syncing of a specific repo branch in a normal update roundHEADdev
This commit enables an additional mode of use when specifying repos to update. Repos in both blocking and non-blocking repo arguments may now follow the format "repo::branch". This forces the given repo to update on the specific branch, rather than the default given by the --branch argument. This is useful for syncing a nonstandard repo that relies upon a differently named branch in Qt. For example, specifying --branch 6.8 --repos tqtc-boot2qt/qtsaferenderer::2.2 will update the qtsaferenderer repo on the 2.2 branch, using the sumodule shas of the 6.8 branch for all dependencies. Task-number: QTQAINFRA-6537 Change-Id: Ic2865af6fb482d450b71526f0ed77635283acde6 Reviewed-by: Daniel Smith <daniel.smith@qt.io>
-rw-r--r--README.md24
-rw-r--r--tools/toolbox.py34
2 files changed, 45 insertions, 13 deletions
diff --git a/README.md b/README.md
index 70c8a73..c5e55e8 100644
--- a/README.md
+++ b/README.md
@@ -100,7 +100,21 @@ tree often need to be updated separately, and in a specific order.
5. Continue to run the utility repeatedly to progress the round until
the target module is updated with new SHAs for its dependencies.
-5. Perform an update for one or more modules, then update qt/qt5.git and
+5. Perform an update to one or more repos on a different branch than the base
+ branch specified for the round.
+ 1. `python3 main.py --prefix qt/ --branch 6.8 --repos tqtc-boot2qt/qtsaferenderer::2.2`
+ 2. This assembles a full dependency map for the given repo(s), reads the shas from qt5.git for
+ --branch, and updates any dependencies not part of qt5.git.
+ 3. In this example, a repo on a specific branch can be made to sync with dependencies on
+ a different branch. Specify this by following the repo with ::[branch].
+ This is typically only used when a repo follows a separate release
+ cycle from the rest of Qt.
+ 4. When the first updates are merged, run the utility again with the same
+ arguments to continue the "round".
+ 5. Continue to run the utility repeatedly to progress the round until
+ the target module is updated with new SHAs for its dependencies.
+
+6. Perform an update for one or more modules, then update qt/qt5.git and
yocto/meta-qt6 with the new module SHA(s).
1. `python3 main.py --head --branch dev --qt5Update --yoctoUpdate --repos
qt-extensions/qthttpserver`
@@ -109,7 +123,7 @@ tree often need to be updated separately, and in a specific order.
yocto/meta-qt6.git with the merged SHAs of the target modules. Only
modules which already exist in the super-repos will be updated.
-6. Rewind an ongoing round to a specific dependency to pull in additional
+7. Rewind an ongoing round to a specific dependency to pull in additional
changes and continue the update round.
1. `python3 main.py --head --branch dev --rewind qt/qtdeclarative --repos
qt-extensions/qthttpserver`
@@ -120,7 +134,7 @@ tree often need to be updated separately, and in a specific order.
depend on _qt/qtdeclarative_ and pull the new head of _qt/qtdeclarative_,
then continue from there.
-7. Remove a dependency from a module
+8. Remove a dependency from a module
1. `python3 main.py --head --branch dev --dropDependency
qt/qtsvg:qt-extensions/qthttpserver --repos qt-extensions/qthttpserver`
2. If a repo no longer needs a dependency, it can be removed in this way.
@@ -130,7 +144,7 @@ tree often need to be updated separately, and in a specific order.
4. _**Note:**_ This action is destructive! See the `--help` output for
important information and detailed usage instructions
-8. Update all current modules in qt/qt5.git
+9. Update all current modules in qt/qt5.git
1. `python3 main.py --default-repos --branch dev --qt5Update --yoctoUpdate`
2. This collects a list of all modules in qt5 marked as 'essential',
'addon', 'deprecated', 'ignore', or 'preview' in the _.gitmodules_
@@ -139,7 +153,7 @@ tree often need to be updated separately, and in a specific order.
3. When finished, qt/qt5.git and yocto/meta-qt6 are updated with the
SHAs of all modules updated in the round
-9. Include in a round additional repos/modules which should be considered
+10. Include in a round additional repos/modules which should be considered
"non-blocking" by the utility.
1. `python3 main.py --default-repos --branch dev --qt5Update --yoctoUpdate
--nonBlockingRepos qt-extensions/qthttpserver`
diff --git a/tools/toolbox.py b/tools/toolbox.py
index 6b6282c..86da594 100644
--- a/tools/toolbox.py
+++ b/tools/toolbox.py
@@ -83,6 +83,8 @@ def gerrit_link_maker(config: Config, change: Union[GerritChange.GerritChange, R
def set_round_topic(config: Config):
"""Set the round topic"""
+ if not config.state_data.get(config.args.repo_prefix+'qtbase'):
+ return
if config.state_data.get(config.args.repo_prefix+'qtbase').proposal.merged_ref:
print("Dependency Round Topic:",
f"dependency_round_{config.state_data.get(config.args.repo_prefix+'qtbase').proposal.merged_ref[:10]}")
@@ -96,8 +98,14 @@ def get_repos(config: Config, repos_override: list[str] = None, non_blocking_ove
:argument repos_override: If set, returns a dict of Repo which only includes these repos."""
base_repos = repos_override or config.args.repos or config.REPOS
- non_blocking_repos = non_blocking_override
+ pinned_branch_repos = [r for r in base_repos if "::" in r]
+ print(f"Pinned branch repos: {pinned_branch_repos}")
+ base_repos = [r.split("::")[0] for r in base_repos]
+ print(f"Base repos: {base_repos}")
+ non_blocking_repos = [r.split("::")[0] for r in non_blocking_override] if non_blocking_override else None
if not non_blocking_repos and non_blocking_repos is not None:
+ pinned_branch_repos += [r for r in non_blocking_override if "::" in r]
+ print(f"Pinned branch repos: {pinned_branch_repos}")
non_blocking_repos = config.args.non_blocking_repos or config.NON_BLOCKING_REPOS
other_repos = []
if not repos_override or non_blocking_override:
@@ -128,8 +136,11 @@ def get_repos(config: Config, repos_override: list[str] = None, non_blocking_ove
retdict[repo.id].is_non_blocking = repo.is_non_blocking
else:
# Initialize the new repo
- repo.deps_yaml, repo.branch = get_dependencies_yaml(config, repo)
- repo.original_ref, repo.original_message = get_head(config, repo)
+ pinned_repo_branch = None
+ if repo.id in [r.split("::")[0] for r in pinned_branch_repos]:
+ pinned_repo_branch = [r.split("::")[1] for r in pinned_branch_repos if repo.id in r].pop()
+ repo.deps_yaml, repo.branch = get_dependencies_yaml(config, repo, branch = pinned_repo_branch)
+ repo.original_ref, repo.original_message = get_head(config, repo, branch = pinned_repo_branch)
retdict[repo.id] = repo
if not config.args.update_default_repos and not config.args.use_head:
for repo in retdict.keys():
@@ -204,6 +215,7 @@ def parse_gitmodules(config: Config,
}
}
"""
+ print(f"collecting gitmodules for {repo}::{branch}::{ref}")
repo_id = repo.id if type(repo) == Repo else repo
branch = branch if branch.startswith("refs/heads/") else 'refs/heads/' + branch
gerrit = config.datasources.gerrit_client
@@ -250,12 +262,18 @@ def get_qt5_submodules(config: Config, types: list[str]) -> dict[str, Repo]:
return retdict
-def get_head(config: Config, repo: Union[Repo, str], pull_head: bool = False) -> str:
+def get_head(config: Config, repo: Union[Repo, str], pull_head: bool = False, branch: Union[str, None] = None) -> str:
"""Fetch the branch head of a repo from codereview, or return the
saved ref from state if the repo progress is >= PROGRESS.DONE.
Override state refs and pull remote branch HEAD with pull_head=True"""
gerrit = config.datasources.gerrit_client
- real_branch = repo.branch if type(repo) is Repo else config.args.branch
+ real_branch = ""
+ if type(repo) is Repo:
+ real_branch = repo.branch if repo.branch else config.args.branch
+ elif branch is not None:
+ real_branch = branch
+ else:
+ real_branch = config.args.branch
if type(repo) == str:
repo = search_for_repo(config, repo)
if (not pull_head and repo.id in config.state_data.keys()
@@ -491,12 +509,12 @@ def parse_log_build_failures(logtext: str) -> str:
return ""
-def get_dependencies_yaml(config, repo: Repo, fetch_head: bool = False) -> tuple[yaml, str]:
+def get_dependencies_yaml(config, repo: Repo, fetch_head: bool = False, branch: str = None) -> tuple[yaml, str]:
"""Fetches the dependencies.yaml file of a repo from gerrit,
or returns the saved dependencies.yaml from state if the repo
progress is >= PROGRESS.DONE"""
gerrit = config.datasources.gerrit_client
- found_branch = config.args.branch
+ found_branch = branch if branch is not None else config.args.branch
r = None
if repo.id in config.qt5_default.keys() and not config.args.use_head and not fetch_head:
if repo.id in config.state_data.keys():
@@ -518,7 +536,7 @@ def get_dependencies_yaml(config, repo: Repo, fetch_head: bool = False) -> tuple
repo.id].branch
else:
return config.state_data[repo.id].deps_yaml, config.state_data[repo.id].branch
- branches = [config.args.branch, "dev", "master"]
+ branches = [found_branch, config.args.branch, "dev", "master"]
for branch in branches:
try:
_repo = gerrit.projects.get(repo.id)