scriptworker 63.4.5__tar.gz → 63.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. {scriptworker-63.4.5 → scriptworker-63.5.0}/HISTORY.rst +15 -0
  2. {scriptworker-63.4.5 → scriptworker-63.5.0}/PKG-INFO +1 -1
  3. {scriptworker-63.4.5 → scriptworker-63.5.0}/pyproject.toml +1 -1
  4. {scriptworker-63.4.5 → scriptworker-63.5.0}/src/scriptworker/constants.py +38 -1
  5. {scriptworker-63.4.5 → scriptworker-63.5.0}/src/scriptworker/cot/verify.py +55 -1
  6. {scriptworker-63.4.5 → scriptworker-63.5.0}/src/scriptworker/github.py +12 -6
  7. {scriptworker-63.4.5 → scriptworker-63.5.0}/.gitignore +0 -0
  8. {scriptworker-63.4.5 → scriptworker-63.5.0}/CONTRIBUTING.rst +0 -0
  9. {scriptworker-63.4.5 → scriptworker-63.5.0}/LICENSE +0 -0
  10. {scriptworker-63.4.5 → scriptworker-63.5.0}/README.rst +0 -0
  11. {scriptworker-63.4.5 → scriptworker-63.5.0}/renovate.json +0 -0
  12. {scriptworker-63.4.5 → scriptworker-63.5.0}/scripts/gen_ed25519_key.py +0 -0
  13. {scriptworker-63.4.5 → scriptworker-63.5.0}/scriptworker.yaml.tmpl +0 -0
  14. {scriptworker-63.4.5 → scriptworker-63.5.0}/src/scriptworker/__init__.py +0 -0
  15. {scriptworker-63.4.5 → scriptworker-63.5.0}/src/scriptworker/artifacts.py +0 -0
  16. {scriptworker-63.4.5 → scriptworker-63.5.0}/src/scriptworker/client.py +0 -0
  17. {scriptworker-63.4.5 → scriptworker-63.5.0}/src/scriptworker/config.py +0 -0
  18. {scriptworker-63.4.5 → scriptworker-63.5.0}/src/scriptworker/context.py +0 -0
  19. {scriptworker-63.4.5 → scriptworker-63.5.0}/src/scriptworker/cot/__init__.py +0 -0
  20. {scriptworker-63.4.5 → scriptworker-63.5.0}/src/scriptworker/cot/generate.py +0 -0
  21. {scriptworker-63.4.5 → scriptworker-63.5.0}/src/scriptworker/data/cot_v1_schema.json +0 -0
  22. {scriptworker-63.4.5 → scriptworker-63.5.0}/src/scriptworker/data/scriptworker_task_schema.json +0 -0
  23. {scriptworker-63.4.5 → scriptworker-63.5.0}/src/scriptworker/ed25519.py +0 -0
  24. {scriptworker-63.4.5 → scriptworker-63.5.0}/src/scriptworker/exceptions.py +0 -0
  25. {scriptworker-63.4.5 → scriptworker-63.5.0}/src/scriptworker/log.py +0 -0
  26. {scriptworker-63.4.5 → scriptworker-63.5.0}/src/scriptworker/task.py +0 -0
  27. {scriptworker-63.4.5 → scriptworker-63.5.0}/src/scriptworker/task_process.py +0 -0
  28. {scriptworker-63.4.5 → scriptworker-63.5.0}/src/scriptworker/utils.py +0 -0
  29. {scriptworker-63.4.5 → scriptworker-63.5.0}/src/scriptworker/worker.py +0 -0
  30. {scriptworker-63.4.5 → scriptworker-63.5.0}/tox.ini +0 -0
@@ -4,6 +4,21 @@ Change Log
4
4
  All notable changes to this project will be documented in this file.
5
5
  This project adheres to `Semantic Versioning <http://semver.org/>`__.
6
6
 
7
+ 63.5.0 - 2026-09-23
8
+ -------------------
9
+
10
+ Fixed
11
+ ~~~~~
12
+
13
+ - Add `mozilla-firefox` as a Github owner for Firefox
14
+ - Url parsing bug when Github <owner> has <repo> as a substring
15
+
16
+ Added
17
+ ~~~~~
18
+
19
+ - Allow tasks sourced from "Git mirrors" to run in graphs alongside tasks
20
+ sourced from their Mercurial equivalents
21
+
7
22
  63.4.5 - 2026-09-11
8
23
  -------------------
9
24
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: scriptworker
3
- Version: 63.4.5
3
+ Version: 63.5.0
4
4
  Summary: Taskcluster scriptworker
5
5
  Author-email: Mozilla Release Engineering <releng@mozilla.com>
6
6
  License-File: LICENSE
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "scriptworker"
3
- version = "63.4.5"
3
+ version = "63.5.0"
4
4
  description = "Taskcluster scriptworker"
5
5
  authors = [
6
6
  { name = "Mozilla Release Engineering", email = "releng@mozilla.com" },
@@ -435,6 +435,43 @@ DEFAULT_CONFIG: immutabledict[str, Any] = immutabledict(
435
435
  )
436
436
  }
437
437
  ),
438
+ # XXX While migrating Firefox from hg.mozilla.org to GitHub, graphs are
439
+ # still generated by decision tasks from hg, but some tasks in them
440
+ # clone from the GitHub mirror instead. This maps an hg repo to its
441
+ # GitHub mirror. A task whose source is the mirror of its parent task's
442
+ # repo is treated as coming from the parent's repo; its definition has
443
+ # already been verified against the parent task's graph. Parent
444
+ # (decision/action) tasks themselves are never mapped.
445
+ # Remove this once the migration is complete.
446
+ "hg_git_mirrors": immutabledict(
447
+ {
448
+ "by-cot-product": immutabledict(
449
+ {
450
+ "adhoc": immutabledict({}),
451
+ "app-services": immutabledict({}),
452
+ "enterprise": immutabledict({}),
453
+ "firefox": immutabledict(
454
+ {
455
+ "/mozilla-central": "/mozilla-firefox/firefox",
456
+ "/integration/autoland": "/mozilla-firefox/firefox",
457
+ "/releases/mozilla-beta": "/mozilla-firefox/firefox",
458
+ "/releases/mozilla-release": "/mozilla-firefox/firefox",
459
+ "/releases/mozilla-esr115": "/mozilla-firefox/firefox",
460
+ "/releases/mozilla-esr140": "/mozilla-firefox/firefox",
461
+ "/releases/mozilla-esr153": "/mozilla-firefox/firefox",
462
+ }
463
+ ),
464
+ "glean": immutabledict({}),
465
+ "mobile": immutabledict({}),
466
+ "mozillavpn": immutabledict({}),
467
+ "scriptworker": immutabledict({}),
468
+ "thunderbird": immutabledict({}),
469
+ "translations": immutabledict({}),
470
+ "xpi": immutabledict({}),
471
+ }
472
+ )
473
+ }
474
+ ),
438
475
  "valid_tasks_for": immutabledict(
439
476
  {
440
477
  "by-cot-product": immutabledict(
@@ -514,7 +551,7 @@ DEFAULT_CONFIG: immutabledict[str, Any] = immutabledict(
514
551
  "mozilla",
515
552
  "thunderbird",
516
553
  ),
517
- "firefox": "",
554
+ "firefox": "mozilla-firefox",
518
555
  "glean": "mozilla",
519
556
  "mobile": "mozilla-mobile",
520
557
  "mozillavpn": "mozilla-mobile",
@@ -40,7 +40,12 @@ from scriptworker.constants import DEFAULT_CONFIG
40
40
  from scriptworker.context import Context
41
41
  from scriptworker.ed25519 import ed25519_public_key_from_string, verify_ed25519_signature
42
42
  from scriptworker.exceptions import BaseDownloadError, CoTError, ScriptWorkerEd25519Error
43
- from scriptworker.github import GitHubRepository, extract_github_repo_full_name, extract_github_repo_owner_and_name, extract_github_repo_ssh_url
43
+ from scriptworker.github import (
44
+ GitHubRepository,
45
+ extract_github_repo_full_name,
46
+ extract_github_repo_owner_and_name,
47
+ extract_github_repo_ssh_url,
48
+ )
44
49
  from scriptworker.log import contextual_log_handler, get_chain_of_trust_log_filename
45
50
  from scriptworker.task import (
46
51
  get_action_callback_name,
@@ -1983,6 +1988,44 @@ def get_source_url(obj):
1983
1988
  return source
1984
1989
 
1985
1990
 
1991
+ # hg_git_mirrors {{{1
1992
+ def _get_parent_repo(chain, repos):
1993
+ """Get the repo of ``chain``'s parent (decision/action) tasks.
1994
+
1995
+ These are the tasks whose definitions are rebuilt from the tree, and that
1996
+ the other tasks in the graph derive their trust from.
1997
+
1998
+ Args:
1999
+ chain (ChainOfTrust): the chain we're operating on
2000
+ repos (dict): the repo path of each object in the chain
2001
+
2002
+ Returns:
2003
+ str: the parent tasks' repo path. If they don't agree, or can't be
2004
+ found, ``chain``'s repo; any mismatch is reported by the sibling check.
2005
+
2006
+ """
2007
+ parent_repos = {repo for obj, repo in repos.items() if obj.decision_task_id == chain.decision_task_id and obj.task_type in PARENT_TASK_TYPES}
2008
+ if len(parent_repos) == 1:
2009
+ return parent_repos.pop()
2010
+ return repos[chain]
2011
+
2012
+
2013
+ def _is_git_mirror(chain, repo, parent_repo):
2014
+ """Determine whether ``repo`` is the git mirror of ``parent_repo``.
2015
+
2016
+ Args:
2017
+ chain (ChainOfTrust): the chain we're operating on
2018
+ repo (str): a non-parent task's repo path
2019
+ parent_repo (str): the parent tasks' repo path
2020
+
2021
+ Returns:
2022
+ bool: whether ``repo`` is the git mirror of ``parent_repo``.
2023
+
2024
+ """
2025
+ mirrors = chain.context.config["hg_git_mirrors"] or {}
2026
+ return repo is not None and mirrors.get(parent_repo) == repo
2027
+
2028
+
1986
2029
  # trace_back_to_tree {{{1
1987
2030
  async def trace_back_to_tree(chain):
1988
2031
  """Trace the chain back to the tree.
@@ -2011,6 +2054,17 @@ async def trace_back_to_tree(chain):
2011
2054
  source_url = get_source_url(obj)
2012
2055
  repo_path = match_url_regex(chain.context.config["trusted_vcs_rules"], source_url, match_url_path_callback)
2013
2056
  repos[obj] = repo_path
2057
+ # XXX During the hg -> git migration, graphs generated from hg may contain
2058
+ # tasks sourced from the git mirror. Treat those as coming from the parent
2059
+ # tasks' repo. Parent tasks are never mapped: their source is what their
2060
+ # definition gets rebuilt from, so it must be trusted in its own right.
2061
+ parent_repo = _get_parent_repo(chain, repos)
2062
+ for obj, repo in repos.items():
2063
+ if obj.decision_task_id != chain.decision_task_id or obj.task_type in PARENT_TASK_TYPES:
2064
+ continue
2065
+ if _is_git_mirror(chain, repo, parent_repo):
2066
+ log.info(f"{obj.name} {obj.task_id}: {repo} is the git mirror of {parent_repo}")
2067
+ repos[obj] = parent_repo
2014
2068
  # check for restricted scopes.
2015
2069
  my_repo = repos[chain]
2016
2070
  for scope in chain.task["scopes"]:
@@ -3,6 +3,7 @@
3
3
  import asyncio
4
4
  import logging
5
5
  import re
6
+ from urllib.parse import unquote, urlparse
6
7
 
7
8
  from github3 import GitHub
8
9
  from github3.exceptions import GitHubException
@@ -202,6 +203,8 @@ def extract_github_repo_owner_and_name(url):
202
203
  _check_github_url_is_supported(url)
203
204
 
204
205
  parts = get_parts_of_url_path(url)
206
+ if len(parts) < 2:
207
+ raise ValueError(f"Could not extract repo owner and name from GitHub URL: {url}")
205
208
  repo_owner = parts[0]
206
209
  repo_name = parts[1]
207
210
 
@@ -257,17 +260,20 @@ def extract_github_repo_and_revision_from_source_url(url):
257
260
  """
258
261
  _check_github_url_is_supported(url)
259
262
 
260
- parts = get_parts_of_url_path(url)
261
- repo_name = parts[1]
263
+ parsed = urlparse(url)
264
+ parts = unquote(parsed.path).lstrip("/").split("/")
265
+ if len(parts) < 2:
266
+ raise ValueError(f"Could not extract repo owner and name from GitHub URL: {url}")
267
+ repo_owner = parts[0]
268
+ repo_name = _strip_trailing_dot_git(parts[1])
262
269
  try:
263
270
  revision = parts[3]
264
271
  except IndexError:
265
- raise ValueError("Revision cannot be extracted from url: {}".format(url))
272
+ raise ValueError(f"Revision cannot be extracted from url: {url}")
266
273
 
267
- end_index = url.index(repo_name) + len(repo_name)
268
- repo_url = url[:end_index]
274
+ repo_url = f"{parsed.scheme}://{parsed.netloc}/{repo_owner}/{repo_name}"
269
275
 
270
- return _strip_trailing_dot_git(repo_url), revision
276
+ return repo_url, revision
271
277
 
272
278
 
273
279
  def _strip_trailing_dot_git(url):
File without changes
File without changes
File without changes
File without changes