taskcluster-taskgraph 24.3.0__tar.gz → 24.4.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 (270) hide show
  1. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/.github/workflows/codeql-analysis.yml +3 -3
  2. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/.github/workflows/codspeed.yml +1 -1
  3. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/.pre-commit-config.yaml +2 -2
  4. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/CHANGELOG.md +22 -0
  5. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/PKG-INFO +1 -1
  6. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/reference/parameters.rst +11 -3
  7. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/tutorials/connecting-taskcluster.rst +24 -11
  8. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/tutorials/example-taskcluster.yml +16 -11
  9. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/pyproject.toml +1 -1
  10. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/decision.py +0 -4
  11. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/graph.py +11 -2
  12. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/optimize/base.py +2 -2
  13. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/run-task/fetch-content +48 -8
  14. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/run-task/run-task +68 -2
  15. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/target_tasks.py +1 -1
  16. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/util/parameterization.py +10 -12
  17. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/util/schema.py +19 -16
  18. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/util/time.py +2 -0
  19. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/docker/index-task/package.json +1 -1
  20. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/docker/index-task/yarn.lock +4 -4
  21. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/template/{{cookiecutter.project_name}}/taskcluster.github.yml +1 -1
  22. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_graph_perf.py +68 -0
  23. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_scripts_fetch_content.py +120 -0
  24. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_scripts_run_task.py +49 -0
  25. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_util_schema.py +46 -0
  26. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/uv.lock +1 -1
  27. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/.codespell-ignore-words.txt +0 -0
  28. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/.github/CODEOWNERS +0 -0
  29. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/.github/workflows/pypi-publish.yml +0 -0
  30. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/.gitignore +0 -0
  31. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/.readthedocs.yaml +0 -0
  32. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/.taskcluster.yml +0 -0
  33. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/.yamllint +0 -0
  34. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/CODE_OF_CONDUCT.md +0 -0
  35. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/CONTRIBUTING.rst +0 -0
  36. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/LICENSE +0 -0
  37. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/Makefile +0 -0
  38. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/README.rst +0 -0
  39. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/concepts/index.rst +0 -0
  40. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/concepts/kind.rst +0 -0
  41. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/concepts/loading.rst +0 -0
  42. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/concepts/optimization.rst +0 -0
  43. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/concepts/overview.rst +0 -0
  44. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/concepts/scopes.rst +0 -0
  45. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/concepts/task-graphs.rst +0 -0
  46. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/concepts/transforms.rst +0 -0
  47. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/conf.py +0 -0
  48. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/contributing.rst +0 -0
  49. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/glossary.rst +0 -0
  50. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/howto/bootstrap-taskgraph.rst +0 -0
  51. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/howto/create-actions.rst +0 -0
  52. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/howto/create-tasks.rst +0 -0
  53. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/howto/debugging.rst +0 -0
  54. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/howto/define-schemas.rst +0 -0
  55. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/howto/docker.rst +0 -0
  56. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/howto/index.rst +0 -0
  57. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/howto/load-task-locally.rst +0 -0
  58. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/howto/resolve-keyed-by.rst +0 -0
  59. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/howto/run-locally.rst +0 -0
  60. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/howto/send-notifications.rst +0 -0
  61. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/howto/use-fetches.rst +0 -0
  62. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/index.rst +0 -0
  63. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/reference/cli.rst +0 -0
  64. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/reference/index.rst +0 -0
  65. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/reference/migrations.rst +0 -0
  66. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/reference/optimization-strategies.rst +0 -0
  67. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/reference/source/modules.rst +0 -0
  68. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/reference/source/taskgraph.actions.rst +0 -0
  69. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/reference/source/taskgraph.loader.rst +0 -0
  70. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/reference/source/taskgraph.optimize.rst +0 -0
  71. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/reference/source/taskgraph.rst +0 -0
  72. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/reference/source/taskgraph.transforms.rst +0 -0
  73. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/reference/source/taskgraph.transforms.run.rst +0 -0
  74. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/reference/source/taskgraph.util.rst +0 -0
  75. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/reference/transforms/chunking.rst +0 -0
  76. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/reference/transforms/from_deps.rst +0 -0
  77. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/reference/transforms/index.rst +0 -0
  78. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/reference/transforms/matrix.rst +0 -0
  79. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/reference/transforms/task_context.rst +0 -0
  80. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/tutorials/creating-a-task-graph.rst +0 -0
  81. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/tutorials/getting-started.rst +0 -0
  82. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/docs/tutorials/index.rst +0 -0
  83. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/make.bat +0 -0
  84. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/packages/pytest-taskgraph/README.md +0 -0
  85. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/packages/pytest-taskgraph/pyproject.toml +0 -0
  86. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/packages/pytest-taskgraph/src/pytest_taskgraph/__init__.py +0 -0
  87. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/packages/pytest-taskgraph/src/pytest_taskgraph/fixtures/gen.py +0 -0
  88. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/packages/pytest-taskgraph/src/pytest_taskgraph/fixtures/vcs.py +0 -0
  89. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/packages/sphinx-taskgraph/README.md +0 -0
  90. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/packages/sphinx-taskgraph/pyproject.toml +0 -0
  91. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/packages/sphinx-taskgraph/src/sphinx_taskgraph/__init__.py +0 -0
  92. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/packages/sphinx-taskgraph/src/sphinx_taskgraph/autoschema.py +0 -0
  93. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/renovate.json +0 -0
  94. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/__init__.py +0 -0
  95. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/actions/__init__.py +0 -0
  96. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/actions/add_new_jobs.py +0 -0
  97. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/actions/cancel.py +0 -0
  98. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/actions/cancel_all.py +0 -0
  99. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/actions/rebuild_cached_tasks.py +0 -0
  100. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/actions/registry.py +0 -0
  101. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/actions/retrigger.py +0 -0
  102. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/actions/util.py +0 -0
  103. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/config.py +0 -0
  104. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/create.py +0 -0
  105. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/docker.py +0 -0
  106. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/filter_tasks.py +0 -0
  107. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/generator.py +0 -0
  108. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/loader/__init__.py +0 -0
  109. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/loader/default.py +0 -0
  110. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/loader/transform.py +0 -0
  111. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/main.py +0 -0
  112. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/morph.py +0 -0
  113. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/optimize/__init__.py +0 -0
  114. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/optimize/strategies.py +0 -0
  115. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/parameters.py +0 -0
  116. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/run-task/hgrc +0 -0
  117. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/run-task/robustcheckout.py +0 -0
  118. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/task.py +0 -0
  119. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/taskgraph.py +0 -0
  120. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/transforms/__init__.py +0 -0
  121. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/transforms/base.py +0 -0
  122. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/transforms/cached_tasks.py +0 -0
  123. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/transforms/chunking.py +0 -0
  124. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/transforms/code_review.py +0 -0
  125. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/transforms/docker_image.py +0 -0
  126. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/transforms/fetch.py +0 -0
  127. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/transforms/from_deps.py +0 -0
  128. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/transforms/matrix.py +0 -0
  129. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/transforms/notify.py +0 -0
  130. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/transforms/run/__init__.py +0 -0
  131. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/transforms/run/common.py +0 -0
  132. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/transforms/run/index_search.py +0 -0
  133. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/transforms/run/run_task.py +0 -0
  134. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/transforms/run/toolchain.py +0 -0
  135. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/transforms/task.py +0 -0
  136. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/transforms/task_context.py +0 -0
  137. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/util/__init__.py +0 -0
  138. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/util/archive.py +0 -0
  139. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/util/attributes.py +0 -0
  140. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/util/cached_tasks.py +0 -0
  141. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/util/caches.py +0 -0
  142. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/util/copy.py +0 -0
  143. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/util/dependencies.py +0 -0
  144. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/util/docker.py +0 -0
  145. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/util/hash.py +0 -0
  146. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/util/json.py +0 -0
  147. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/util/keyed_by.py +0 -0
  148. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/util/path.py +0 -0
  149. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/util/python_path.py +0 -0
  150. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/util/readonlydict.py +0 -0
  151. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/util/set_name.py +0 -0
  152. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/util/shell.py +0 -0
  153. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/util/task_context.py +0 -0
  154. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/util/taskcluster.py +0 -0
  155. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/util/taskgraph.py +0 -0
  156. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/util/templates.py +0 -0
  157. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/util/treeherder.py +0 -0
  158. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/util/vcs.py +0 -0
  159. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/util/verify.py +0 -0
  160. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/util/workertypes.py +0 -0
  161. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/src/taskgraph/util/yaml.py +0 -0
  162. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/config.yml +0 -0
  163. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/docker/REGISTRY +0 -0
  164. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/docker/decision/Dockerfile +0 -0
  165. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/docker/decision/HASH +0 -0
  166. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/docker/decision/README.md +0 -0
  167. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/docker/decision/VERSION +0 -0
  168. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/docker/decision/system-setup.sh +0 -0
  169. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/docker/fetch/Dockerfile +0 -0
  170. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/docker/image_builder/README.rst +0 -0
  171. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/docker/index-task/Dockerfile +0 -0
  172. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/docker/index-task/README +0 -0
  173. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/docker/index-task/insert-indexes.js +0 -0
  174. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/docker/python/Dockerfile +0 -0
  175. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/docker/run-task/Dockerfile +0 -0
  176. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/docker/run-task/system-setup.sh +0 -0
  177. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/docker/skopeo/Dockerfile +0 -0
  178. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/docker/skopeo/policy.json +0 -0
  179. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/docker/skopeo/push_image.sh +0 -0
  180. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/kinds/check/kind.yml +0 -0
  181. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/kinds/codecov/kind.yml +0 -0
  182. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/kinds/complete/kind.yml +0 -0
  183. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/kinds/doc/kind.yml +0 -0
  184. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/kinds/docker-image/kind.yml +0 -0
  185. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/kinds/fetch/kind.yml +0 -0
  186. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/kinds/push-image/kind.yml +0 -0
  187. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/kinds/test/kind.yml +0 -0
  188. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/kinds/test/linux.yml +0 -0
  189. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/kinds/test/windows.yml +0 -0
  190. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/scripts/codecov-upload.py +0 -0
  191. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/self_taskgraph/__init__.py +0 -0
  192. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/self_taskgraph/custom_parameters.py +0 -0
  193. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/self_taskgraph/custom_target_tasks.py +0 -0
  194. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/self_taskgraph/transforms/add_pr_route.py +0 -0
  195. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/self_taskgraph/transforms/push_image.py +0 -0
  196. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/test/params/main-repo-pull-request-untrusted.yml +0 -0
  197. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/test/params/main-repo-pull-request.yml +0 -0
  198. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/test/params/main-repo-push.yml +0 -0
  199. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/test/params/main-repo-release-pytest-taskgraph.yml +0 -0
  200. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/taskcluster/test/params/main-repo-release-taskcluster-taskgraph.yml +0 -0
  201. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/template/cookiecutter.json +0 -0
  202. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/template/hooks/post_gen_project.py +0 -0
  203. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/template/{{cookiecutter.project_name}}/taskcluster/config.yml +0 -0
  204. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/template/{{cookiecutter.project_name}}/taskcluster/docker/linux/Dockerfile +0 -0
  205. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/template/{{cookiecutter.project_name}}/taskcluster/kinds/docker-image/kind.yml +0 -0
  206. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/template/{{cookiecutter.project_name}}/taskcluster/kinds/hello/kind.yml +0 -0
  207. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/template/{{cookiecutter.project_name}}/taskcluster/{{cookiecutter.project_slug}}_taskgraph/transforms/hello.py +0 -0
  208. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/__init__.py +0 -0
  209. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/automationrelevance.json +0 -0
  210. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/conftest.py +0 -0
  211. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/data/task_context.yml +0 -0
  212. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/data/taskcluster/config.yml +0 -0
  213. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/data/taskcluster/docker/hello-world/Dockerfile +0 -0
  214. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/data/taskcluster/docker/hello-world-tag/Dockerfile +0 -0
  215. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/data/taskcluster/docker/hello-world-tag/REGISTRY +0 -0
  216. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/data/taskcluster/docker/hello-world-tag/VERSION +0 -0
  217. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/data/taskcluster/kinds/docker-image/kind.yml +0 -0
  218. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/data/taskcluster/scripts/toolchain/run.ps1 +0 -0
  219. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/data/taskcluster/scripts/toolchain/run.sh +0 -0
  220. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/data/taskcluster/test_taskgraph/transforms/foo.py +0 -0
  221. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/data/testmod/thing.py +0 -0
  222. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/mockedopen.py +0 -0
  223. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_actions_rebuild_cached_tasks.py +0 -0
  224. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_actions_registry.py +0 -0
  225. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_config.py +0 -0
  226. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_create.py +0 -0
  227. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_decision.py +0 -0
  228. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_docker.py +0 -0
  229. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_generator.py +0 -0
  230. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_graph.py +0 -0
  231. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_main.py +0 -0
  232. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_morph.py +0 -0
  233. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_optimize.py +0 -0
  234. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_optimize_strategies.py +0 -0
  235. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_parameters.py +0 -0
  236. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_target_tasks.py +0 -0
  237. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_taskgraph.py +0 -0
  238. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_transform_chunking.py +0 -0
  239. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_transform_docker_image.py +0 -0
  240. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_transform_task_context.py +0 -0
  241. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_transforms_base.py +0 -0
  242. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_transforms_cached_tasks.py +0 -0
  243. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_transforms_fetch.py +0 -0
  244. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_transforms_from_deps.py +0 -0
  245. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_transforms_matrix.py +0 -0
  246. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_transforms_notify.py +0 -0
  247. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_transforms_run.py +0 -0
  248. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_transforms_run_run_task.py +0 -0
  249. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_transforms_run_toolchain.py +0 -0
  250. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_transforms_task.py +0 -0
  251. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_util_archive.py +0 -0
  252. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_util_attributes.py +0 -0
  253. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_util_cached_tasks.py +0 -0
  254. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_util_copy.py +0 -0
  255. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_util_dependencies.py +0 -0
  256. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_util_docker.py +0 -0
  257. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_util_json.py +0 -0
  258. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_util_keyed_by.py +0 -0
  259. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_util_parameterization.py +0 -0
  260. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_util_path.py +0 -0
  261. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_util_python_path.py +0 -0
  262. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_util_readonlydict.py +0 -0
  263. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_util_taskcluster.py +0 -0
  264. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_util_templates.py +0 -0
  265. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_util_time.py +0 -0
  266. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_util_treeherder.py +0 -0
  267. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_util_vcs.py +0 -0
  268. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_util_verify.py +0 -0
  269. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_util_workertypes.py +0 -0
  270. {taskcluster_taskgraph-24.3.0 → taskcluster_taskgraph-24.4.0}/test/test_util_yaml.py +0 -0
@@ -42,7 +42,7 @@ jobs:
42
42
  uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
43
43
  # Initializes the CodeQL tools for scanning.
44
44
  - name: Initialize CodeQL
45
- uses: github/codeql-action/init@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9
45
+ uses: github/codeql-action/init@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4.38.2
46
46
  with:
47
47
  languages: ${{ matrix.language }}
48
48
  # If you wish to specify custom queries, you can do so here or in a config file.
@@ -55,7 +55,7 @@ jobs:
55
55
  # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
56
56
  # If this step fails, then you should remove it and run the build manually (see below)
57
57
  - name: Autobuild
58
- uses: github/codeql-action/autobuild@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9
58
+ uses: github/codeql-action/autobuild@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4.38.2
59
59
 
60
60
  # ℹ️ Command-line programs to run using the OS shell.
61
61
  # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@@ -67,4 +67,4 @@ jobs:
67
67
  # echo "Run, Build Application using script"
68
68
  # ./location_of_script_within_repo/buildscript.sh
69
69
  - name: Perform CodeQL Analysis
70
- uses: github/codeql-action/analyze@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9
70
+ uses: github/codeql-action/analyze@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4.38.2
@@ -19,7 +19,7 @@ jobs:
19
19
  id-token: write # required for OIDC authentication with CodSpeed
20
20
  steps:
21
21
  - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
22
- - uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
22
+ - uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
23
23
  with:
24
24
  python-version: "3.12"
25
25
  - name: Install dependencies
@@ -13,13 +13,13 @@ repos:
13
13
  exclude: template
14
14
  - id: check-added-large-files
15
15
  - repo: https://github.com/astral-sh/ruff-pre-commit
16
- rev: v0.16.5
16
+ rev: v0.16.9
17
17
  hooks:
18
18
  - id: ruff
19
19
  args: [--fix, --exit-non-zero-on-fix]
20
20
  - id: ruff-format
21
21
  - repo: https://github.com/astral-sh/uv-pre-commit
22
- rev: 0.12.8
22
+ rev: 0.12.19
23
23
  hooks:
24
24
  - id: uv-lock
25
25
  - repo: https://github.com/adrienverge/yamllint.git
@@ -1,5 +1,27 @@
1
1
  # Change Log
2
2
 
3
+ ## [24.4.0] - 2026-10-05
4
+
5
+ ### Added
6
+
7
+ - Merge concurrently extracted fetches in a fixed order in `fetch-content`
8
+ - Hook point in `run-task` before the task payload
9
+ - Prefix `run_python_script` output in `run-task` with `[script <timestamp>]`
10
+
11
+ ### Changed
12
+
13
+ - `taskgraph init` template and tutorial docs now default to the `public_restricted` PR policy
14
+
15
+ ### Fixed
16
+
17
+ - `filter_for_git_branch` target task filter now works with untrusted PRs
18
+ - Update `@taskcluster/client` dependency to v110 (#1060)
19
+ - perf: compute `optionally_keyed_by` fields once per Schema class (#1049)
20
+ - perf: speed up resolving task definition references (#1051)
21
+ - perf: cache parsed relative time strings (#1052)
22
+ - perf: cache the visit order of graphs (#1053)
23
+ - perf: stop re-parsing the full task graph in the decision task (#1055)
24
+
3
25
  ## [24.3.0] - 2026-09-17
4
26
 
5
27
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: taskcluster-taskgraph
3
- Version: 24.3.0
3
+ Version: 24.4.0
4
4
  Summary: Build taskcluster taskgraphs
5
5
  Project-URL: Repository, https://github.com/taskcluster/taskgraph
6
6
  Project-URL: Issues, https://github.com/taskcluster/taskgraph/issues
@@ -96,9 +96,17 @@ project
96
96
 
97
97
  level
98
98
  ~~~~~
99
- The `SCM level`_ associated with this tree.
100
-
101
- .. _SCM level: https://www.mozilla.org/en-US/about/governance/policies/commit/access-policy/
99
+ The trust level associated with this task group. Trust levels provide a
100
+ convenient way to segregate resources such as worker-pools, secrets and
101
+ caches based on how the task group was triggered. This creates security
102
+ boundaries between various degrees of trust.
103
+
104
+ The meaning of a trust level can vary from project to project, but typically
105
+ level 1 is the lowest trust and corresponds to pull requests from external
106
+ contributors. Level 2 is a degree higher and denotes pull requests from repo
107
+ collaborators or pushes to unprotected branches. Level 3 is the highest
108
+ degree of trust and is reserved for pushes to protected branches and
109
+ releases.
102
110
 
103
111
  Target Set
104
112
  ----------
@@ -79,7 +79,7 @@ here is the recommended method:
79
79
  version: 1
80
80
  reporting: checks-v1
81
81
  policy:
82
- pullRequests: collaborators
82
+ pullRequests: public_restricted
83
83
  tasks:
84
84
  -
85
85
 
@@ -109,7 +109,7 @@ here is the recommended method:
109
109
  $if: 'tasks_for == "github-push"'
110
110
  then: '${event.pusher.email}'
111
111
  else:
112
- $if: 'tasks_for == "github-pull-request"'
112
+ $if: 'tasks_for[:19] == "github-pull-request"'
113
113
  then: '${event.pull_request.user.login}@users.noreply.github.com'
114
114
  else:
115
115
  $if: 'tasks_for == "github-release"'
@@ -118,22 +118,22 @@ here is the recommended method:
118
118
  $if: 'tasks_for == "github-push"'
119
119
  then: '${event.repository.html_url}'
120
120
  else:
121
- $if: 'tasks_for == "github-pull-request"'
121
+ $if: 'tasks_for[:19] == "github-pull-request"'
122
122
  then: '${event.pull_request.base.repo.html_url}'
123
123
  repoUrl:
124
124
  $if: 'tasks_for == "github-push"'
125
125
  then: '${event.repository.html_url}'
126
126
  else:
127
- $if: 'tasks_for == "github-pull-request"'
127
+ $if: 'tasks_for[:19] == "github-pull-request"'
128
128
  then: '${event.pull_request.head.repo.html_url}'
129
129
  project:
130
130
  $if: 'tasks_for == "github-push"'
131
131
  then: '${event.repository.name}'
132
132
  else:
133
- $if: 'tasks_for == "github-pull-request"'
133
+ $if: 'tasks_for[:19] == "github-pull-request"'
134
134
  then: '${event.pull_request.head.repo.name}'
135
135
  headBranch:
136
- $if: 'tasks_for == "github-pull-request"'
136
+ $if: 'tasks_for[:19] == "github-pull-request"'
137
137
  then: ${event.pull_request.head.ref}
138
138
  else:
139
139
  $if: 'tasks_for == "github-push"'
@@ -142,7 +142,7 @@ here is the recommended method:
142
142
  $if: 'tasks_for == "github-push"'
143
143
  then: '${event.after}'
144
144
  else:
145
- $if: 'tasks_for == "github-pull-request"'
145
+ $if: 'tasks_for[:19] == "github-pull-request"'
146
146
  then: '${event.pull_request.head.sha}'
147
147
 
148
148
  This isn't strictly necessary, but the format of the various Github events
@@ -165,7 +165,7 @@ here is the recommended method:
165
165
  in:
166
166
  $if: >
167
167
  tasks_for == "github-push" && headBranch == "main"
168
- || (tasks_for == "github-pull-request" && ${event.action} in ["opened", "reopened", "synchronize"])
168
+ || (tasks_for[:19] == "github-pull-request" && ${event.action} in ["opened", "reopened", "synchronize"])
169
169
  then:
170
170
  # Task definition goes here. Since there is no "else" clause, if
171
171
  # the above if statement evaluates to false, there will be no
@@ -236,9 +236,11 @@ here is the recommended method:
236
236
  # while ${headBranch[11:]} strips out 'refs/heads/'
237
237
  - 'assume:repo:${repoUrl[8:]}:branch:${headBranch[11:]}'
238
238
  else:
239
- $if: 'tasks_for == "github-pull-request"'
239
+ $if: 'tasks_for[:19] == "github-pull-request"'
240
240
  then:
241
- - 'assume:repo:github.com/${event.pull_request.base.repo.full_name}:pull-request'
241
+ # ${tasks_for[7:]} strips the 'github-' prefix, leaving
242
+ # either 'pull-request' or 'pull-request-untrusted'.
243
+ - 'assume:repo:github.com/${event.pull_request.base.repo.full_name}:${tasks_for[7:]}'
242
244
 
243
245
  Notice how we assume different roles depending on whether the task is
244
246
  coming from a push or a pull request. This is useful when you have tasks
@@ -246,6 +248,17 @@ here is the recommended method:
246
248
  accidentally running on a pull request! By using different scopes, you can
247
249
  ensure it won't ever happen.
248
250
 
251
+ With the ``public_restricted`` policy set above, Github reports pull
252
+ requests from repository collaborators with ``tasks_for ==
253
+ "github-pull-request"`` and pull requests from everyone else with
254
+ ``tasks_for == "github-pull-request-untrusted"``. Slicing ``tasks_for[7:]``
255
+ turns those into the role names ``pull-request`` and
256
+ ``pull-request-untrusted``, so you can grant non-collaborator pull
257
+ requests a more restricted set of scopes than collaborator ones. This
258
+ matters because collapsing that distinction (e.g. by using the ``public``
259
+ policy) means any external contributor's pull request gets the same
260
+ scopes as a trusted collaborator's.
261
+
249
262
  The roles assumed above may vary depending on the Taskcluster
250
263
  configuration.
251
264
 
@@ -310,7 +323,7 @@ here is the recommended method:
310
323
  # running your command
311
324
  MYREPO_PIP_REQUIREMENTS: taskcluster/requirements.txt
312
325
  REPOSITORIES: {$json: {myrepo: "MyRepo"}}
313
- - $if: 'tasks_for in ["github-pull-request"]'
326
+ - $if: 'tasks_for[:19] == "github-pull-request"'
314
327
  then:
315
328
  MYREPO_PULL_REQUEST_NUMBER: '${event.pull_request.number}'
316
329
  command:
@@ -2,7 +2,7 @@
2
2
  version: 1
3
3
  reporting: checks-v1
4
4
  policy:
5
- pullRequests: collaborators
5
+ pullRequests: public_restricted
6
6
  tasks:
7
7
  - $let:
8
8
  # Variable definitions
@@ -13,7 +13,7 @@ tasks:
13
13
  $if: 'tasks_for == "github-push"'
14
14
  then: '${event.pusher.email}'
15
15
  else:
16
- $if: 'tasks_for == "github-pull-request"'
16
+ $if: 'tasks_for[:19] == "github-pull-request"'
17
17
  then: '${event.pull_request.user.login}@users.noreply.github.com'
18
18
  else:
19
19
  $if: 'tasks_for == "github-release"'
@@ -22,22 +22,22 @@ tasks:
22
22
  $if: 'tasks_for == "github-push"'
23
23
  then: '${event.repository.html_url}'
24
24
  else:
25
- $if: 'tasks_for == "github-pull-request"'
25
+ $if: 'tasks_for[:19] == "github-pull-request"'
26
26
  then: '${event.pull_request.base.repo.html_url}'
27
27
  repoUrl:
28
28
  $if: 'tasks_for == "github-push"'
29
29
  then: '${event.repository.html_url}'
30
30
  else:
31
- $if: 'tasks_for == "github-pull-request"'
31
+ $if: 'tasks_for[:19] == "github-pull-request"'
32
32
  then: '${event.pull_request.head.repo.html_url}'
33
33
  project:
34
34
  $if: 'tasks_for == "github-push"'
35
35
  then: '${event.repository.name}'
36
36
  else:
37
- $if: 'tasks_for == "github-pull-request"'
37
+ $if: 'tasks_for[:19] == "github-pull-request"'
38
38
  then: '${event.pull_request.head.repo.name}'
39
39
  headBranch:
40
- $if: 'tasks_for == "github-pull-request"'
40
+ $if: 'tasks_for[:19] == "github-pull-request"'
41
41
  then: ${event.pull_request.head.ref}
42
42
  else:
43
43
  $if: 'tasks_for == "github-push"'
@@ -46,13 +46,13 @@ tasks:
46
46
  $if: 'tasks_for == "github-push"'
47
47
  then: '${event.after}'
48
48
  else:
49
- $if: 'tasks_for == "github-pull-request"'
49
+ $if: 'tasks_for[:19] == "github-pull-request"'
50
50
  then: '${event.pull_request.head.sha}'
51
51
  in:
52
52
  # Guard that controls when to schedule tasks.
53
53
  $if: >
54
54
  tasks_for == "github-push" && headBranch == "main"
55
- || (tasks_for == "github-pull-request" && ${event.action} in ["opened", "reopened", "synchronize"])
55
+ || (tasks_for[:19] == "github-pull-request" && ${event.action} in ["opened", "reopened", "synchronize"])
56
56
  then:
57
57
  # Task Definition
58
58
  taskId: '${ownTaskId}'
@@ -74,9 +74,14 @@ tasks:
74
74
  # while ${headBranch[11:]} strips out 'refs/heads/'
75
75
  - 'assume:repo:${repoUrl[8:]}:branch:${headBranch[11:]}'
76
76
  else:
77
- $if: 'tasks_for == "github-pull-request"'
77
+ $if: 'tasks_for[:19] == "github-pull-request"'
78
78
  then:
79
- - 'assume:repo:github.com/${event.pull_request.base.repo.full_name}:pull-request'
79
+ # ${tasks_for[7:]} strips the 'github-' prefix, leaving
80
+ # 'pull-request' or 'pull-request-untrusted'. With the
81
+ # 'public_restricted' policy these map to two separate
82
+ # roles, so pull requests from collaborators get more
83
+ # scopes than those from non-collaborators.
84
+ - 'assume:repo:github.com/${event.pull_request.base.repo.full_name}:${tasks_for[7:]}'
80
85
  payload:
81
86
  image:
82
87
  mozillareleases/taskgraph:decision-cf4b4b4baff57d84c1f9ec8fcd70c9839b70a7d66e6430a6c41ffe67252faa19@sha256:425e07f6813804483bc5a7258288a7684d182617ceeaa0176901ccc7702dfe28
@@ -97,7 +102,7 @@ tasks:
97
102
  # bootstrapped
98
103
  MYREPO_PIP_REQUIREMENTS: taskcluster/requirements.txt
99
104
  REPOSITORIES: {$json: {myrepo: "MyRepo"}}
100
- - $if: 'tasks_for in ["github-pull-request"]'
105
+ - $if: 'tasks_for[:19] == "github-pull-request"'
101
106
  then:
102
107
  MYREPO_PULL_REQUEST_NUMBER: '${event.pull_request.number}'
103
108
  command:
@@ -1,7 +1,7 @@
1
1
  ### Project
2
2
  [project]
3
3
  name = "taskcluster-taskgraph"
4
- version = "24.3.0"
4
+ version = "24.4.0"
5
5
  description = "Build taskcluster taskgraphs"
6
6
  readme = "README.rst"
7
7
  authors = [
@@ -17,7 +17,6 @@ from taskgraph.actions import render_actions_json
17
17
  from taskgraph.create import create_tasks
18
18
  from taskgraph.generator import TaskGraphGenerator
19
19
  from taskgraph.parameters import Parameters, get_version
20
- from taskgraph.taskgraph import TaskGraph
21
20
  from taskgraph.util import json
22
21
  from taskgraph.util.python_path import find_object
23
22
  from taskgraph.util.schema import Schema, validate_schema
@@ -131,9 +130,6 @@ def taskgraph_decision(options, parameters=None):
131
130
  "runnable-jobs.json", full_task_graph_to_runnable_tasks(full_task_json)
132
131
  )
133
132
 
134
- # this is just a test to check whether the from_json() function is working
135
- _, _ = TaskGraph.from_json(full_task_json)
136
-
137
133
  # write out the target task set to allow reproducing this as input
138
134
  write_artifact("target-tasks.json", list(tgg.target_task_set.tasks.keys()))
139
135
 
@@ -107,6 +107,15 @@ class Graph(_Graph):
107
107
  f"Dependency loop detected involving the following nodes: {loopy_nodes}"
108
108
  )
109
109
 
110
+ @functools.cache
111
+ def _visit_order(self, reverse):
112
+ """
113
+ Return the order in which `_visit` yields nodes as a tuple. The graph
114
+ is immutable, so this is cached to avoid sorting it again every time
115
+ it is visited.
116
+ """
117
+ return tuple(self._visit(reverse))
118
+
110
119
  def visit_postorder(self):
111
120
  """
112
121
  Generate a sequence of nodes in postorder, such that every node is
@@ -114,14 +123,14 @@ class Graph(_Graph):
114
123
 
115
124
  Raises an exception if the graph contains a cycle.
116
125
  """
117
- return self._visit(False)
126
+ return iter(self._visit_order(False))
118
127
 
119
128
  def visit_preorder(self):
120
129
  """
121
130
  Like visit_postorder, but in reverse: evrey node is visited *before*
122
131
  any nodes it links to.
123
132
  """
124
- return self._visit(True)
133
+ return iter(self._visit_order(True))
125
134
 
126
135
  @functools.cache
127
136
  def links_and_reverse_links_dict(self):
@@ -78,7 +78,7 @@ def optimize_task_graph(
78
78
 
79
79
  # Gather each relevant task's index
80
80
  indexes = set()
81
- for label in target_task_graph.graph.visit_postorder():
81
+ for label in target_task_graph.tasks:
82
82
  if label in do_not_optimize:
83
83
  continue
84
84
  _, strategy, arg = optimizations(label)
@@ -157,7 +157,7 @@ def remove_tasks(
157
157
  opt_counts = defaultdict(int)
158
158
  opt_reasons = {}
159
159
  removed = set()
160
- dependents_of = target_task_graph.graph.reverse_links_dict()
160
+ _, dependents_of = target_task_graph.graph.links_and_reverse_links_dict()
161
161
  tasks = target_task_graph.tasks
162
162
  prune_candidates = set()
163
163
 
@@ -683,6 +683,36 @@ def repack_archive(
683
683
  )
684
684
 
685
685
 
686
+ def merge_tree(src, dest):
687
+ """Move the contents of the src directory into dest and remove src.
688
+
689
+ Directories present on both sides are merged entry by entry and take
690
+ the mode from src. Any other path present on both sides is replaced by
691
+ the one from src.
692
+ """
693
+ dest.mkdir(parents=True, exist_ok=True)
694
+ os.chmod(src, stat.S_IMODE(os.stat(src).st_mode) | stat.S_IWUSR)
695
+ for entry in os.scandir(src):
696
+ target = dest / entry.name
697
+ if (
698
+ entry.is_dir(follow_symlinks=False)
699
+ and target.is_dir()
700
+ and not target.is_symlink()
701
+ ):
702
+ mode = stat.S_IMODE(entry.stat(follow_symlinks=False).st_mode)
703
+ merge_tree(pathlib.Path(entry.path), target)
704
+ os.chmod(target, mode)
705
+ continue
706
+ if target.is_symlink() or target.exists():
707
+ log(f"{target} is provided by more than one fetch, replacing it")
708
+ if target.is_dir() and not target.is_symlink():
709
+ shutil.rmtree(target)
710
+ else:
711
+ target.unlink()
712
+ os.replace(entry.path, target)
713
+ src.rmdir()
714
+
715
+
686
716
  def fetch_and_extract(url, dest_dir, extract=True, sha256=None, size=None):
687
717
  """Fetch a URL and extract it to a destination path.
688
718
 
@@ -708,15 +738,25 @@ def fetch_and_extract(url, dest_dir, extract=True, sha256=None, size=None):
708
738
 
709
739
 
710
740
  def fetch_urls(downloads):
711
- """Fetch URLs pairs to a pathlib.Path."""
712
- with concurrent.futures.ThreadPoolExecutor(CONCURRENCY) as e:
713
- fs = []
714
-
715
- for download in downloads:
716
- fs.append(e.submit(fetch_and_extract, *download))
741
+ """Fetch URLs pairs to a pathlib.Path.
717
742
 
718
- for f in fs:
719
- f.result()
743
+ Each fetch is downloaded and extracted into a staging directory under
744
+ its destination, all in parallel. The staging directories are then
745
+ merged into the destinations sequentially, in the order the fetches
746
+ were given. Two archives never write to the same directory at the
747
+ same time, and when they contain the same path the later fetch wins.
748
+ """
749
+ with concurrent.futures.ThreadPoolExecutor(CONCURRENCY) as e:
750
+ extractions = []
751
+ for url, dest_dir, *rest in downloads:
752
+ staging_dir = pathlib.Path(tempfile.mkdtemp(prefix=".fetch.", dir=dest_dir))
753
+ future = e.submit(fetch_and_extract, url, staging_dir, *rest)
754
+ extractions.append((future, staging_dir, dest_dir))
755
+
756
+ for future, staging_dir, dest_dir in extractions:
757
+ future.result()
758
+ log(f"Merging {staging_dir} into {dest_dir}")
759
+ merge_tree(staging_dir, dest_dir)
720
760
 
721
761
 
722
762
  def _git_checkout_github_archive(
@@ -22,6 +22,7 @@ import json
22
22
  import os
23
23
  import platform
24
24
  import re
25
+ import runpy
25
26
  import shutil
26
27
  import socket
27
28
  import stat
@@ -30,6 +31,7 @@ import sys
30
31
  import tempfile
31
32
  import threading
32
33
  import time
34
+ import traceback
33
35
  import urllib.error
34
36
  import urllib.request
35
37
  from pathlib import Path
@@ -112,16 +114,58 @@ IS_WINDOWS = os.name == "nt"
112
114
  NULL_REVISION = "0000000000000000000000000000000000000000"
113
115
 
114
116
 
115
- def print_line(prefix, m):
117
+ def format_line(prefix, m):
116
118
  now = (
117
119
  datetime.datetime.now(tz=datetime.timezone.utc)
118
120
  .isoformat(timespec="milliseconds")
119
121
  .encode("utf-8")
120
122
  )
121
- sys.stdout.buffer.write(b"[%s %s] %s" % (prefix, now, m))
123
+ return b"[%s %s] %s" % (prefix, now, m)
124
+
125
+
126
+ def print_line(prefix, m):
127
+ sys.stdout.buffer.write(format_line(prefix, m))
122
128
  sys.stdout.buffer.flush()
123
129
 
124
130
 
131
+ class _PrefixedLineWriter:
132
+ """File-like object that prefixes each complete line written to it
133
+ with the current time, before forwarding it to the given buffer."""
134
+
135
+ def __init__(self, prefix, buffer):
136
+ self.prefix = prefix
137
+ self.buffer = buffer
138
+ self._pending = ""
139
+
140
+ def write(self, s):
141
+ self._pending += s
142
+ *lines, self._pending = self._pending.split("\n")
143
+ for line in lines:
144
+ self.buffer.write(format_line(self.prefix, b"%s\n" % line.encode("utf-8")))
145
+ self.buffer.flush()
146
+ return len(s)
147
+
148
+ def flush(self):
149
+ if self._pending:
150
+ self.buffer.write(format_line(self.prefix, self._pending.encode("utf-8")))
151
+ self._pending = ""
152
+ self.buffer.flush()
153
+
154
+
155
+ @contextlib.contextmanager
156
+ def prefix_output(prefix):
157
+ """Redirect stdout/stderr so each line written is prefixed with the
158
+ current time, like output from `run_command`."""
159
+ writer = _PrefixedLineWriter(prefix, sys.stdout.buffer)
160
+ old_stdout, old_stderr = sys.stdout, sys.stderr
161
+ sys.stdout = sys.stderr = writer
162
+ try:
163
+ yield
164
+ finally:
165
+ writer.flush()
166
+ sys.stdout, sys.stderr = old_stdout, old_stderr
167
+
168
+
125
169
  def reap_zombies(main_subprocess):
126
170
  """Wait for main_subprocess to exit, while awaiting any other child processes"""
127
171
  while main_subprocess.poll() is None:
@@ -319,6 +363,24 @@ def run_command(prefix, args, *, extra_env=None, cwd=None, stdin_data=None):
319
363
  return p.wait()
320
364
 
321
365
 
366
+ def run_python_script(path):
367
+ """Execute a Python script in-process."""
368
+ print_line(
369
+ b"setup",
370
+ b"running python script: %s\n" % path.encode("utf-8"),
371
+ )
372
+ try:
373
+ with prefix_output(b"script"):
374
+ runpy.run_path(path)
375
+ except Exception:
376
+ print_line(
377
+ b"setup",
378
+ b"script %s failed:\n%s"
379
+ % (path.encode("utf-8"), traceback.format_exc().encode("utf-8")),
380
+ )
381
+ sys.exit(1)
382
+
383
+
322
384
  def get_posix_user_group(user, group):
323
385
  import grp # noqa: PLC0415
324
386
  import pwd # noqa: PLC0415
@@ -1668,6 +1730,7 @@ def main(args):
1668
1730
  "MOZ_FETCHES_DIR",
1669
1731
  "MOZ_PYTHON_HOME",
1670
1732
  "MOZ_UV_HOME",
1733
+ "RUN_TASK_PRE_COMMAND_HOOK",
1671
1734
  "PIP_CACHE_DIR",
1672
1735
  "UPLOAD_DIR",
1673
1736
  "UV_CACHE_DIR",
@@ -1691,6 +1754,9 @@ def main(args):
1691
1754
  # fetches to grab dependencies.
1692
1755
  install_pip_requirements(repositories)
1693
1756
 
1757
+ if hook_path := os.environ.get("RUN_TASK_PRE_COMMAND_HOOK"):
1758
+ run_python_script(hook_path)
1759
+
1694
1760
  return run_command(b"task", task_args, cwd=args.task_cwd)
1695
1761
 
1696
1762
 
@@ -53,7 +53,7 @@ def filter_for_git_branch(task, parameters):
53
53
  return True
54
54
 
55
55
  # Pull requests usually have arbitrary names, let's not filter git branches on them.
56
- if parameters["tasks_for"] == "github-pull-request":
56
+ if parameters["tasks_for"].startswith("github-pull-request"):
57
57
  return True
58
58
 
59
59
  run_on_git_branches = set(task.attributes.get("run_on_git_branches", ["all"]))
@@ -15,20 +15,18 @@ ARTIFACT_REFERENCE_PATTERN = re.compile("<([^/]+)/([^>]+)>")
15
15
 
16
16
  def _recurse(val, param_fns):
17
17
  def recurse(val):
18
- if isinstance(val, list):
19
- return [recurse(v) for v in val]
20
- elif isinstance(val, dict):
18
+ if isinstance(val, dict):
21
19
  if len(val) == 1:
22
- for param_key, param_fn in param_fns.items():
23
- if set(val.keys()) == {param_key}:
24
- if isinstance(val[param_key], dict):
25
- # handle `{"task-reference": {"<foo>": "bar"}}`
26
- return {
27
- param_fn(key): recurse(v)
28
- for key, v in val[param_key].items()
29
- }
30
- return param_fn(val[param_key])
20
+ ((key, value),) = val.items()
21
+ param_fn = param_fns.get(key)
22
+ if param_fn is not None:
23
+ if isinstance(value, dict):
24
+ # handle `{"task-reference": {"<foo>": "bar"}}`
25
+ return {param_fn(k): recurse(v) for k, v in value.items()}
26
+ return param_fn(value)
31
27
  return {k: recurse(v) for k, v in val.items()}
28
+ elif isinstance(val, list):
29
+ return [recurse(v) for v in val]
32
30
  else:
33
31
  return val
34
32