taskcluster-taskgraph 17.2.0__tar.gz → 17.2.1__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 (267) hide show
  1. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/.pre-commit-config.yaml +3 -1
  2. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/CHANGELOG.md +8 -0
  3. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/PKG-INFO +1 -1
  4. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/packages/pytest-taskgraph/src/pytest_taskgraph/fixtures/gen.py +14 -1
  5. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/pyproject.toml +1 -1
  6. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/actions/cancel.py +2 -10
  7. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/actions/cancel_all.py +2 -10
  8. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/optimize/base.py +1 -0
  9. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/run-task/run-task +5 -4
  10. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/transforms/task.py +2 -138
  11. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/util/taskcluster.py +3 -7
  12. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/util/verify.py +130 -0
  13. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/kinds/codecov/kind.yml +3 -0
  14. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/kinds/complete/kind.yml +6 -0
  15. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/kinds/test/kind.yml +3 -1
  16. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_optimize.py +9 -3
  17. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_transforms_task.py +0 -81
  18. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_util_verify.py +52 -14
  19. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/uv.lock +1 -1
  20. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/.codespell-ignore-words.txt +0 -0
  21. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/.github/CODEOWNERS +0 -0
  22. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/.github/dependabot.yml +0 -0
  23. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/.github/workflows/codeql-analysis.yml +0 -0
  24. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/.github/workflows/pre-commit-autoupdate.yml +0 -0
  25. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/.github/workflows/pre-commit.yml +0 -0
  26. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/.github/workflows/pypi-publish.yml +0 -0
  27. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/.gitignore +0 -0
  28. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/.readthedocs.yaml +0 -0
  29. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/.taskcluster.yml +0 -0
  30. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/.yamllint +0 -0
  31. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/CODE_OF_CONDUCT.md +0 -0
  32. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/CONTRIBUTING.rst +0 -0
  33. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/LICENSE +0 -0
  34. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/Makefile +0 -0
  35. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/README.rst +0 -0
  36. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/concepts/index.rst +0 -0
  37. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/concepts/kind.rst +0 -0
  38. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/concepts/loading.rst +0 -0
  39. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/concepts/optimization.rst +0 -0
  40. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/concepts/overview.rst +0 -0
  41. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/concepts/scopes.rst +0 -0
  42. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/concepts/task-graphs.rst +0 -0
  43. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/concepts/transforms.rst +0 -0
  44. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/conf.py +0 -0
  45. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/contributing.rst +0 -0
  46. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/glossary.rst +0 -0
  47. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/howto/bootstrap-taskgraph.rst +0 -0
  48. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/howto/create-actions.rst +0 -0
  49. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/howto/create-tasks.rst +0 -0
  50. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/howto/debugging.rst +0 -0
  51. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/howto/docker.rst +0 -0
  52. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/howto/index.rst +0 -0
  53. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/howto/load-task-locally.rst +0 -0
  54. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/howto/resolve-keyed-by.rst +0 -0
  55. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/howto/run-locally.rst +0 -0
  56. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/howto/send-notifications.rst +0 -0
  57. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/howto/use-fetches.rst +0 -0
  58. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/index.rst +0 -0
  59. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/reference/cli.rst +0 -0
  60. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/reference/index.rst +0 -0
  61. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/reference/migrations.rst +0 -0
  62. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/reference/optimization-strategies.rst +0 -0
  63. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/reference/parameters.rst +0 -0
  64. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/reference/source/modules.rst +0 -0
  65. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/reference/source/taskgraph.actions.rst +0 -0
  66. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/reference/source/taskgraph.loader.rst +0 -0
  67. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/reference/source/taskgraph.optimize.rst +0 -0
  68. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/reference/source/taskgraph.rst +0 -0
  69. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/reference/source/taskgraph.transforms.rst +0 -0
  70. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/reference/source/taskgraph.transforms.run.rst +0 -0
  71. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/reference/source/taskgraph.util.rst +0 -0
  72. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/reference/transforms/chunking.rst +0 -0
  73. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/reference/transforms/from_deps.rst +0 -0
  74. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/reference/transforms/index.rst +0 -0
  75. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/reference/transforms/matrix.rst +0 -0
  76. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/reference/transforms/task_context.rst +0 -0
  77. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/tutorials/connecting-taskcluster.rst +0 -0
  78. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/tutorials/creating-a-task-graph.rst +0 -0
  79. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/tutorials/example-taskcluster.yml +0 -0
  80. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/tutorials/getting-started.rst +0 -0
  81. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/docs/tutorials/index.rst +0 -0
  82. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/make.bat +0 -0
  83. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/packages/pytest-taskgraph/README.md +0 -0
  84. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/packages/pytest-taskgraph/pyproject.toml +0 -0
  85. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/packages/pytest-taskgraph/src/pytest_taskgraph/__init__.py +0 -0
  86. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/packages/pytest-taskgraph/src/pytest_taskgraph/fixtures/vcs.py +0 -0
  87. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/packages/sphinx-taskgraph/README.md +0 -0
  88. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/packages/sphinx-taskgraph/pyproject.toml +0 -0
  89. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/packages/sphinx-taskgraph/src/sphinx_taskgraph/__init__.py +0 -0
  90. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/packages/sphinx-taskgraph/src/sphinx_taskgraph/autoschema.py +0 -0
  91. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/__init__.py +0 -0
  92. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/actions/__init__.py +0 -0
  93. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/actions/add_new_jobs.py +0 -0
  94. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/actions/rebuild_cached_tasks.py +0 -0
  95. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/actions/registry.py +0 -0
  96. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/actions/retrigger.py +0 -0
  97. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/actions/util.py +0 -0
  98. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/config.py +0 -0
  99. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/create.py +0 -0
  100. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/decision.py +0 -0
  101. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/docker.py +0 -0
  102. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/filter_tasks.py +0 -0
  103. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/generator.py +0 -0
  104. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/graph.py +0 -0
  105. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/loader/__init__.py +0 -0
  106. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/loader/default.py +0 -0
  107. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/loader/transform.py +0 -0
  108. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/main.py +0 -0
  109. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/morph.py +0 -0
  110. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/optimize/__init__.py +0 -0
  111. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/optimize/strategies.py +0 -0
  112. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/parameters.py +0 -0
  113. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/run-task/fetch-content +0 -0
  114. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/run-task/hgrc +0 -0
  115. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/run-task/robustcheckout.py +0 -0
  116. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/target_tasks.py +0 -0
  117. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/task.py +0 -0
  118. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/taskgraph.py +0 -0
  119. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/transforms/__init__.py +0 -0
  120. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/transforms/base.py +0 -0
  121. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/transforms/cached_tasks.py +0 -0
  122. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/transforms/chunking.py +0 -0
  123. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/transforms/code_review.py +0 -0
  124. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/transforms/docker_image.py +0 -0
  125. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/transforms/fetch.py +0 -0
  126. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/transforms/from_deps.py +0 -0
  127. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/transforms/matrix.py +0 -0
  128. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/transforms/notify.py +0 -0
  129. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/transforms/run/__init__.py +0 -0
  130. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/transforms/run/common.py +0 -0
  131. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/transforms/run/index_search.py +0 -0
  132. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/transforms/run/run_task.py +0 -0
  133. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/transforms/run/toolchain.py +0 -0
  134. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/transforms/task_context.py +0 -0
  135. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/util/__init__.py +0 -0
  136. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/util/archive.py +0 -0
  137. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/util/attributes.py +0 -0
  138. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/util/cached_tasks.py +0 -0
  139. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/util/caches.py +0 -0
  140. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/util/copy.py +0 -0
  141. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/util/dependencies.py +0 -0
  142. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/util/docker.py +0 -0
  143. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/util/hash.py +0 -0
  144. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/util/json.py +0 -0
  145. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/util/keyed_by.py +0 -0
  146. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/util/parameterization.py +0 -0
  147. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/util/path.py +0 -0
  148. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/util/python_path.py +0 -0
  149. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/util/readonlydict.py +0 -0
  150. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/util/schema.py +0 -0
  151. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/util/set_name.py +0 -0
  152. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/util/shell.py +0 -0
  153. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/util/taskgraph.py +0 -0
  154. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/util/templates.py +0 -0
  155. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/util/time.py +0 -0
  156. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/util/treeherder.py +0 -0
  157. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/util/vcs.py +0 -0
  158. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/util/workertypes.py +0 -0
  159. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/src/taskgraph/util/yaml.py +0 -0
  160. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/config.yml +0 -0
  161. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/docker/REGISTRY +0 -0
  162. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/docker/decision/Dockerfile +0 -0
  163. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/docker/decision/HASH +0 -0
  164. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/docker/decision/README.md +0 -0
  165. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/docker/decision/VERSION +0 -0
  166. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/docker/decision/system-setup.sh +0 -0
  167. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/docker/fetch/Dockerfile +0 -0
  168. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/docker/image_builder/README.rst +0 -0
  169. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/docker/index-task/Dockerfile +0 -0
  170. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/docker/index-task/README +0 -0
  171. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/docker/index-task/insert-indexes.js +0 -0
  172. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/docker/index-task/package.json +0 -0
  173. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/docker/index-task/yarn.lock +0 -0
  174. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/docker/python/Dockerfile +0 -0
  175. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/docker/run-task/Dockerfile +0 -0
  176. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/docker/run-task/system-setup.sh +0 -0
  177. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/docker/skopeo/Dockerfile +0 -0
  178. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/docker/skopeo/policy.json +0 -0
  179. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/docker/skopeo/push_image.sh +0 -0
  180. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/kinds/check/kind.yml +0 -0
  181. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/kinds/doc/kind.yml +0 -0
  182. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/kinds/docker-image/kind.yml +0 -0
  183. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/kinds/fetch/kind.yml +0 -0
  184. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/kinds/push-image/kind.yml +0 -0
  185. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/scripts/codecov-upload.py +0 -0
  186. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/scripts/external_tools/tooltool.py +0 -0
  187. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/self_taskgraph/__init__.py +0 -0
  188. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/self_taskgraph/custom_parameters.py +0 -0
  189. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/self_taskgraph/custom_target_tasks.py +0 -0
  190. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/self_taskgraph/transforms/add_pr_route.py +0 -0
  191. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/self_taskgraph/transforms/push_image.py +0 -0
  192. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/test/params/main-repo-pull-request-untrusted.yml +0 -0
  193. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/test/params/main-repo-pull-request.yml +0 -0
  194. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/test/params/main-repo-push.yml +0 -0
  195. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/test/params/main-repo-release-pytest-taskgraph.yml +0 -0
  196. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/taskcluster/test/params/main-repo-release-taskcluster-taskgraph.yml +0 -0
  197. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/template/cookiecutter.json +0 -0
  198. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/template/hooks/post_gen_project.py +0 -0
  199. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/template/{{cookiecutter.project_name}}/taskcluster/config.yml +0 -0
  200. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/template/{{cookiecutter.project_name}}/taskcluster/docker/linux/Dockerfile +0 -0
  201. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/template/{{cookiecutter.project_name}}/taskcluster/kinds/docker-image/kind.yml +0 -0
  202. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/template/{{cookiecutter.project_name}}/taskcluster/kinds/hello/kind.yml +0 -0
  203. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/template/{{cookiecutter.project_name}}/taskcluster/{{cookiecutter.project_slug}}_taskgraph/transforms/hello.py +0 -0
  204. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/template/{{cookiecutter.project_name}}/taskcluster.github.yml +0 -0
  205. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/__init__.py +0 -0
  206. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/automationrelevance.json +0 -0
  207. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/conftest.py +0 -0
  208. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/data/task_context.yml +0 -0
  209. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/data/taskcluster/config.yml +0 -0
  210. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/data/taskcluster/docker/hello-world/Dockerfile +0 -0
  211. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/data/taskcluster/docker/hello-world-tag/Dockerfile +0 -0
  212. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/data/taskcluster/docker/hello-world-tag/REGISTRY +0 -0
  213. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/data/taskcluster/docker/hello-world-tag/VERSION +0 -0
  214. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/data/taskcluster/kinds/docker-image/kind.yml +0 -0
  215. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/data/taskcluster/scripts/toolchain/run.ps1 +0 -0
  216. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/data/taskcluster/scripts/toolchain/run.sh +0 -0
  217. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/data/taskcluster/test_taskgraph/transforms/foo.py +0 -0
  218. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/data/testmod/thing.py +0 -0
  219. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/mockedopen.py +0 -0
  220. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_actions_rebuild_cached_tasks.py +0 -0
  221. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_actions_registry.py +0 -0
  222. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_config.py +0 -0
  223. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_create.py +0 -0
  224. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_decision.py +0 -0
  225. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_docker.py +0 -0
  226. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_generator.py +0 -0
  227. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_graph.py +0 -0
  228. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_main.py +0 -0
  229. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_morph.py +0 -0
  230. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_optimize_strategies.py +0 -0
  231. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_parameters.py +0 -0
  232. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_scripts_fetch_content.py +0 -0
  233. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_scripts_run_task.py +0 -0
  234. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_target_tasks.py +0 -0
  235. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_taskgraph.py +0 -0
  236. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_transform_chunking.py +0 -0
  237. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_transform_docker_image.py +0 -0
  238. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_transform_task_context.py +0 -0
  239. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_transforms_base.py +0 -0
  240. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_transforms_cached_tasks.py +0 -0
  241. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_transforms_fetch.py +0 -0
  242. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_transforms_from_deps.py +0 -0
  243. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_transforms_matrix.py +0 -0
  244. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_transforms_notify.py +0 -0
  245. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_transforms_run.py +0 -0
  246. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_transforms_run_run_task.py +0 -0
  247. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_transforms_run_toolchain.py +0 -0
  248. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_util_archive.py +0 -0
  249. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_util_attributes.py +0 -0
  250. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_util_cached_tasks.py +0 -0
  251. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_util_copy.py +0 -0
  252. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_util_dependencies.py +0 -0
  253. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_util_docker.py +0 -0
  254. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_util_json.py +0 -0
  255. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_util_keyed_by.py +0 -0
  256. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_util_parameterization.py +0 -0
  257. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_util_path.py +0 -0
  258. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_util_python_path.py +0 -0
  259. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_util_readonlydict.py +0 -0
  260. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_util_schema.py +0 -0
  261. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_util_taskcluster.py +0 -0
  262. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_util_templates.py +0 -0
  263. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_util_time.py +0 -0
  264. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_util_treeherder.py +0 -0
  265. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_util_vcs.py +0 -0
  266. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_util_workertypes.py +0 -0
  267. {taskcluster_taskgraph-17.2.0 → taskcluster_taskgraph-17.2.1}/test/test_util_yaml.py +0 -0
@@ -41,11 +41,13 @@ repos:
41
41
  hooks:
42
42
  - id: conventional-pre-commit
43
43
  stages: [commit-msg]
44
- # TODO remove 'fetch-content' once Gecko no longer needs to use it with Python 3.8
44
+ # TODO remove 'fetch-content' and 'run-task' once Gecko no longer needs to use
45
+ # them with Python 3.8:
45
46
  # https://bugzilla.mozilla.org/show_bug.cgi?id=1990567#c7
46
47
  exclude: |
47
48
  (?x)^(
48
49
  src/taskgraph/run-task/fetch-content |
49
50
  src/taskgraph/run-task/robustcheckout.py |
51
+ src/taskgraph/run-task/run-task |
50
52
  taskcluster/scripts/external_tools
51
53
  )
@@ -1,5 +1,13 @@
1
1
  # Change Log
2
2
 
3
+ ## [17.2.1] - 2025-10-31
4
+
5
+ ### Fixed
6
+
7
+ - Exception when using `run-task` script on Windows
8
+ - `run-task` script temporarily supports Python 3.8 again
9
+ - Optimization phase updates `dependencies` property in `Task` objects
10
+
3
11
  ## [17.2.0] - 2025-10-30
4
12
 
5
13
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: taskcluster-taskgraph
3
- Version: 17.2.0
3
+ Version: 17.2.1
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
@@ -32,8 +32,12 @@ def fake_loader(kind, path, config, parameters, loaded_tasks, write_artifacts):
32
32
  "i": i,
33
33
  "metadata": {"name": f"{kind}-t-{i}"},
34
34
  "deadline": "soon",
35
+ "workerType": "linux",
36
+ "provisionerId": "prov",
35
37
  },
36
38
  "dependencies": dependencies,
39
+ "if-dependencies": [],
40
+ "soft-dependencies": [],
37
41
  }
38
42
  if "task-defaults" in config:
39
43
  task = merge(config["task-defaults"], task)
@@ -250,6 +254,7 @@ def make_task(
250
254
  task_id=None,
251
255
  dependencies=None,
252
256
  if_dependencies=None,
257
+ soft_dependencies=None,
253
258
  attributes=None,
254
259
  ):
255
260
  task_def = task_def or {
@@ -258,7 +263,9 @@ def make_task(
258
263
  }
259
264
  task = Task(
260
265
  attributes=attributes or {},
266
+ dependencies=dependencies or {},
261
267
  if_dependencies=if_dependencies or [],
268
+ soft_dependencies=soft_dependencies or [],
262
269
  kind=kind,
263
270
  label=label,
264
271
  task=task_def,
@@ -266,7 +273,13 @@ def make_task(
266
273
  task.optimization = optimization
267
274
  task.task_id = task_id
268
275
  if dependencies is not None:
269
- task.task["dependencies"] = sorted(dependencies)
276
+ # The dependencies dict is converted from a dict to a list during the
277
+ # optimization phase. This is pretty confusing and means this utility
278
+ # might break assumptions about the format of 'dependencies'.
279
+ if isinstance(dependencies, dict):
280
+ task.task["dependencies"] = sorted(dependencies.values())
281
+ else:
282
+ task.task["dependencies"] = sorted(dependencies)
270
283
  return task
271
284
 
272
285
 
@@ -1,7 +1,7 @@
1
1
  ### Project
2
2
  [project]
3
3
  name = "taskcluster-taskgraph"
4
- version = "17.2.0"
4
+ version = "17.2.1"
5
5
  description = "Build taskcluster taskgraphs"
6
6
  readme = "README.rst"
7
7
  authors = [
@@ -5,8 +5,6 @@
5
5
 
6
6
  import logging
7
7
 
8
- import requests
9
-
10
8
  from taskcluster import TaskclusterRestFailure
11
9
  from taskgraph.util.taskcluster import cancel_task
12
10
 
@@ -28,14 +26,8 @@ def cancel_action(parameters, graph_config, input, task_group_id, task_id):
28
26
  # only cancel tasks with the level-specific schedulerId.
29
27
  try:
30
28
  cancel_task(task_id)
31
- except (requests.HTTPError, TaskclusterRestFailure) as e:
32
- status_code = None
33
- if isinstance(e, requests.HTTPError):
34
- status_code = e.response.status_code if e.response else None
35
- elif isinstance(e, TaskclusterRestFailure):
36
- status_code = e.status_code
37
-
38
- if status_code == 409:
29
+ except TaskclusterRestFailure as e:
30
+ if e.status_code == 409:
39
31
  # A 409 response indicates that this task is past its deadline. It
40
32
  # cannot be cancelled at this time, but it's also not running
41
33
  # anymore, so we can ignore this error.
@@ -7,8 +7,6 @@ import logging
7
7
  import os
8
8
  from concurrent import futures
9
9
 
10
- import requests
11
-
12
10
  from taskcluster import TaskclusterRestFailure
13
11
  from taskgraph.util.taskcluster import (
14
12
  CONCURRENCY,
@@ -37,14 +35,8 @@ def cancel_all_action(parameters, graph_config, input, task_group_id, task_id):
37
35
  logger.info(f"Cancelling task {task_id}")
38
36
  try:
39
37
  cancel_task(task_id)
40
- except (requests.HTTPError, TaskclusterRestFailure) as e:
41
- status_code = None
42
- if isinstance(e, requests.HTTPError):
43
- status_code = e.response.status_code if e.response else None
44
- elif isinstance(e, TaskclusterRestFailure):
45
- status_code = e.status_code
46
-
47
- if status_code == 409:
38
+ except TaskclusterRestFailure as e:
39
+ if e.status_code == 409:
48
40
  # A 409 response indicates that this task is past its deadline. It
49
41
  # cannot be cancelled at this time, but it's also not running
50
42
  # anymore, so we can ignore this error.
@@ -437,6 +437,7 @@ def get_subgraph(
437
437
  )
438
438
  deps = task.task.setdefault("dependencies", [])
439
439
  deps.extend(sorted(named_task_dependencies.values()))
440
+ task.dependencies.update(named_task_dependencies)
440
441
  tasks_by_taskid[task.task_id] = task
441
442
 
442
443
  # resolve edges to taskIds
@@ -16,12 +16,10 @@ current time to improve log usefulness.
16
16
  import argparse
17
17
  import datetime
18
18
  import errno
19
- import grp
20
19
  import io
21
20
  import json
22
21
  import os
23
22
  import platform
24
- import pwd
25
23
  import re
26
24
  import shutil
27
25
  import socket
@@ -33,7 +31,7 @@ import time
33
31
  import urllib.error
34
32
  import urllib.request
35
33
  from pathlib import Path
36
- from typing import Optional
34
+ from typing import Dict, Optional
37
35
 
38
36
  SECRET_BASEURL_TPL = "{}/secrets/v1/secret/{{}}".format(
39
37
  os.environ.get("TASKCLUSTER_PROXY_URL", "http://taskcluster").rstrip("/")
@@ -311,6 +309,9 @@ def run_command(prefix, args, *, extra_env=None, cwd=None):
311
309
 
312
310
 
313
311
  def get_posix_user_group(user, group):
312
+ import grp # noqa: PLC0415
313
+ import pwd # noqa: PLC0415
314
+
314
315
  try:
315
316
  user_record = pwd.getpwnam(user)
316
317
  except KeyError:
@@ -572,7 +573,7 @@ def git_fetch(
572
573
  remote: str = "origin",
573
574
  tags: bool = False,
574
575
  shallow: bool = False,
575
- env: Optional[dict[str, str]] = None,
576
+ env: Optional[Dict[str, str]] = None,
576
577
  ):
577
578
  args = ["git", "fetch"]
578
579
  if tags:
@@ -11,7 +11,6 @@ complexities of worker implementations, scopes, and treeherder annotations.
11
11
  import functools
12
12
  import hashlib
13
13
  import os
14
- import re
15
14
  import time
16
15
  from copy import deepcopy
17
16
  from dataclasses import dataclass
@@ -20,7 +19,6 @@ from typing import Callable
20
19
 
21
20
  from voluptuous import All, Any, Extra, NotIn, Optional, Required
22
21
 
23
- from taskgraph import MAX_DEPENDENCIES
24
22
  from taskgraph.transforms.base import TransformSequence
25
23
  from taskgraph.util.hash import hash_path
26
24
  from taskgraph.util.keyed_by import evaluate_keyed_by
@@ -44,7 +42,7 @@ RUN_TASK = os.path.join(
44
42
 
45
43
 
46
44
  @functools.cache
47
- def _run_task_suffix():
45
+ def run_task_suffix():
48
46
  """String to append to cache names under control of run-task."""
49
47
  return hash_path(RUN_TASK)[0:20]
50
48
 
@@ -715,7 +713,7 @@ def build_docker_worker_payload(config, task, task_def):
715
713
  cache_version = "v3"
716
714
 
717
715
  if run_task:
718
- suffix = f"{cache_version}-{_run_task_suffix()}"
716
+ suffix = f"{cache_version}-{run_task_suffix()}"
719
717
 
720
718
  if out_of_tree_image:
721
719
  name_hash = hashlib.sha256(
@@ -763,8 +761,6 @@ def build_docker_worker_payload(config, task, task_def):
763
761
  if capabilities:
764
762
  payload["capabilities"] = capabilities
765
763
 
766
- check_caches_are_volumes(task)
767
-
768
764
 
769
765
  @payload_builder(
770
766
  "generic-worker",
@@ -1457,135 +1453,3 @@ def chain_of_trust(config, tasks):
1457
1453
  "task-reference": "<docker-image>"
1458
1454
  }
1459
1455
  yield task
1460
-
1461
-
1462
- @transforms.add
1463
- def check_task_identifiers(config, tasks):
1464
- """Ensures that all tasks have well defined identifiers:
1465
- ``^[a-zA-Z0-9_-]{1,38}$``
1466
- """
1467
- e = re.compile("^[a-zA-Z0-9_-]{1,38}$")
1468
- for task in tasks:
1469
- for attrib in ("workerType", "provisionerId"):
1470
- if not e.match(task["task"][attrib]):
1471
- raise Exception(
1472
- "task {}.{} is not a valid identifier: {}".format(
1473
- task["label"], attrib, task["task"][attrib]
1474
- )
1475
- )
1476
- yield task
1477
-
1478
-
1479
- @transforms.add
1480
- def check_task_dependencies(config, tasks):
1481
- """Ensures that tasks don't have more than 100 dependencies."""
1482
- for task in tasks:
1483
- number_of_dependencies = (
1484
- len(task["dependencies"])
1485
- + len(task["if-dependencies"])
1486
- + len(task["soft-dependencies"])
1487
- )
1488
- if number_of_dependencies > MAX_DEPENDENCIES:
1489
- raise Exception(
1490
- "task {}/{} has too many dependencies ({} > {})".format(
1491
- config.kind,
1492
- task["label"],
1493
- number_of_dependencies,
1494
- MAX_DEPENDENCIES,
1495
- )
1496
- )
1497
- yield task
1498
-
1499
-
1500
- def check_caches_are_volumes(task):
1501
- """Ensures that all cache paths are defined as volumes.
1502
-
1503
- Caches and volumes are the only filesystem locations whose content
1504
- isn't defined by the Docker image itself. Some caches are optional
1505
- depending on the task environment. We want paths that are potentially
1506
- caches to have as similar behavior regardless of whether a cache is
1507
- used. To help enforce this, we require that all paths used as caches
1508
- to be declared as Docker volumes. This check won't catch all offenders.
1509
- But it is better than nothing.
1510
- """
1511
- volumes = set(task["worker"]["volumes"])
1512
- paths = {c["mount-point"] for c in task["worker"].get("caches", [])}
1513
- missing = paths - volumes
1514
-
1515
- if not missing:
1516
- return
1517
-
1518
- raise Exception(
1519
- "task {} (image {}) has caches that are not declared as "
1520
- "Docker volumes: {} "
1521
- "(have you added them as VOLUMEs in the Dockerfile?)".format(
1522
- task["label"], task["worker"]["docker-image"], ", ".join(sorted(missing))
1523
- )
1524
- )
1525
-
1526
-
1527
- @transforms.add
1528
- def check_run_task_caches(config, tasks):
1529
- """Audit for caches requiring run-task.
1530
-
1531
- run-task manages caches in certain ways. If a cache managed by run-task
1532
- is used by a non run-task task, it could cause problems. So we audit for
1533
- that and make sure certain cache names are exclusive to run-task.
1534
-
1535
- IF YOU ARE TEMPTED TO MAKE EXCLUSIONS TO THIS POLICY, YOU ARE LIKELY
1536
- CONTRIBUTING TECHNICAL DEBT AND WILL HAVE TO SOLVE MANY OF THE PROBLEMS
1537
- THAT RUN-TASK ALREADY SOLVES. THINK LONG AND HARD BEFORE DOING THAT.
1538
- """
1539
- re_reserved_caches = re.compile(
1540
- """^
1541
- (checkouts|tooltool-cache)
1542
- """,
1543
- re.VERBOSE,
1544
- )
1545
-
1546
- cache_prefix = "{trust_domain}-level-{level}-".format(
1547
- trust_domain=config.graph_config["trust-domain"],
1548
- level=config.params["level"],
1549
- )
1550
-
1551
- suffix = _run_task_suffix()
1552
-
1553
- for task in tasks:
1554
- payload = task["task"].get("payload", {})
1555
- command = payload.get("command") or [""]
1556
-
1557
- main_command = command[0] if isinstance(command[0], str) else ""
1558
- run_task = main_command.endswith("run-task")
1559
-
1560
- for cache in payload.get("cache", {}).get(
1561
- "task-reference", payload.get("cache", {})
1562
- ):
1563
- if not cache.startswith(cache_prefix):
1564
- raise Exception(
1565
- "{} is using a cache ({}) which is not appropriate "
1566
- "for its trust-domain and level. It should start with {}.".format(
1567
- task["label"], cache, cache_prefix
1568
- )
1569
- )
1570
-
1571
- cache = cache[len(cache_prefix) :]
1572
-
1573
- if not re_reserved_caches.match(cache):
1574
- continue
1575
-
1576
- if not run_task:
1577
- raise Exception(
1578
- f"{task['label']} is using a cache ({cache}) reserved for run-task "
1579
- "change the task to use run-task or use a different "
1580
- "cache name"
1581
- )
1582
-
1583
- if suffix not in cache:
1584
- raise Exception(
1585
- f"{task['label']} is using a cache ({cache}) reserved for run-task "
1586
- "but the cache name is not dependent on the contents "
1587
- "of run-task; change the cache name to conform to the "
1588
- "naming requirements"
1589
- )
1590
-
1591
- yield task
@@ -467,15 +467,11 @@ def get_ancestors(task_ids: Union[list[str], str]) -> dict[str, str]:
467
467
  for task_id in task_ids:
468
468
  try:
469
469
  task_def = get_task_definition(task_id)
470
- except (requests.HTTPError, taskcluster.TaskclusterRestFailure) as e:
470
+ except taskcluster.TaskclusterRestFailure as e:
471
471
  # Task has most likely expired, which means it's no longer a
472
472
  # dependency for the purposes of this function.
473
- if isinstance(e, requests.HTTPError):
474
- if e.response and e.response.status_code == 404:
475
- continue
476
- elif isinstance(e, taskcluster.TaskclusterRestFailure):
477
- if e.status_code == 404:
478
- continue
473
+ if e.status_code == 404:
474
+ continue
479
475
  raise e
480
476
 
481
477
  dependencies = task_def.get("dependencies", [])
@@ -4,15 +4,18 @@
4
4
 
5
5
 
6
6
  import logging
7
+ import re
7
8
  import sys
8
9
  import warnings
9
10
  from abc import ABC, abstractmethod
10
11
  from dataclasses import dataclass, field
11
12
  from typing import Callable, Union
12
13
 
14
+ from taskgraph import MAX_DEPENDENCIES
13
15
  from taskgraph.config import GraphConfig
14
16
  from taskgraph.parameters import Parameters
15
17
  from taskgraph.taskgraph import TaskGraph
18
+ from taskgraph.transforms.task import run_task_suffix
16
19
  from taskgraph.util.attributes import match_run_on_projects
17
20
  from taskgraph.util.treeherder import join_symbol
18
21
 
@@ -301,6 +304,133 @@ def verify_toolchain_alias(task, taskgraph, scratch_pad, graph_config, parameter
301
304
  scratch_pad[key] = task.label
302
305
 
303
306
 
307
+ RE_RESERVED_CACHES = re.compile(r"^(checkouts|tooltool-cache)", re.VERBOSE)
308
+
309
+
310
+ @verifications.add("full_task_graph")
311
+ def verify_run_task_caches(task, taskgraph, scratch_pad, graph_config, parameters):
312
+ """Audit for caches requiring run-task.
313
+
314
+ run-task manages caches in certain ways. If a cache managed by run-task
315
+ is used by a non run-task task, it could cause problems. So we audit for
316
+ that and make sure certain cache names are exclusive to run-task.
317
+
318
+ IF YOU ARE TEMPTED TO MAKE EXCLUSIONS TO THIS POLICY, YOU ARE LIKELY
319
+ CONTRIBUTING TECHNICAL DEBT AND WILL HAVE TO SOLVE MANY OF THE PROBLEMS
320
+ THAT RUN-TASK ALREADY SOLVES. THINK LONG AND HARD BEFORE DOING THAT.
321
+ """
322
+ if task is None:
323
+ return
324
+
325
+ cache_prefix = "{trust_domain}-level-{level}-".format(
326
+ trust_domain=graph_config["trust-domain"],
327
+ level=parameters["level"],
328
+ )
329
+
330
+ suffix = run_task_suffix()
331
+
332
+ payload = task.task.get("payload", {})
333
+ command = payload.get("command") or [""]
334
+
335
+ main_command = command[0] if isinstance(command[0], str) else ""
336
+ run_task = main_command.endswith("run-task")
337
+
338
+ for cache in payload.get("cache", {}).get(
339
+ "task-reference", payload.get("cache", {})
340
+ ):
341
+ if not cache.startswith(cache_prefix):
342
+ raise Exception(
343
+ f"{task.label} is using a cache ({cache}) which is not appropriate "
344
+ f"for its trust-domain and level. It should start with {cache_prefix}."
345
+ )
346
+
347
+ cache = cache[len(cache_prefix) :]
348
+
349
+ if not RE_RESERVED_CACHES.match(cache):
350
+ continue
351
+
352
+ if not run_task:
353
+ raise Exception(
354
+ f"{task['label']} is using a cache ({cache}) reserved for run-task "
355
+ "change the task to use run-task or use a different "
356
+ "cache name"
357
+ )
358
+
359
+ if suffix not in cache:
360
+ raise Exception(
361
+ f"{task['label']} is using a cache ({cache}) reserved for run-task "
362
+ "but the cache name is not dependent on the contents "
363
+ "of run-task; change the cache name to conform to the "
364
+ "naming requirements"
365
+ )
366
+
367
+
368
+ @verifications.add("full_task_graph")
369
+ def verify_task_identifiers(task, taskgraph, scratch_pad, graph_config, parameters):
370
+ """Ensures that all tasks have well defined identifiers:
371
+ ``^[a-zA-Z0-9_-]{1,38}$``
372
+ """
373
+ if task is None:
374
+ return
375
+
376
+ e = re.compile("^[a-zA-Z0-9_-]{1,38}$")
377
+ for attrib in ("workerType", "provisionerId"):
378
+ if not e.match(task.task[attrib]):
379
+ raise Exception(
380
+ f"task {task.label}.{attrib} is not a valid identifier: {task.task[attrib]}"
381
+ )
382
+
383
+
384
+ @verifications.add("full_task_graph")
385
+ def verify_task_dependencies(task, taskgraph, scratch_pad, graph_config, parameters):
386
+ """Ensures that tasks don't have more than 100 dependencies."""
387
+ if task is None:
388
+ return
389
+
390
+ number_of_dependencies = (
391
+ len(task.dependencies) + len(task.if_dependencies) + len(task.soft_dependencies)
392
+ )
393
+ if number_of_dependencies > MAX_DEPENDENCIES:
394
+ raise Exception(
395
+ f"task {task.label} has too many dependencies ({number_of_dependencies} > {MAX_DEPENDENCIES})"
396
+ )
397
+
398
+
399
+ @verifications.add("full_task_graph")
400
+ def verify_caches_are_volumes(task, taskgraph, scratch_pad, graph_config, parameters):
401
+ """Ensures that all cache paths are defined as volumes.
402
+
403
+ Caches and volumes are the only filesystem locations whose content
404
+ isn't defined by the Docker image itself. Some caches are optional
405
+ depending on the task environment. We want paths that are potentially
406
+ caches to have as similar behavior regardless of whether a cache is
407
+ used. To help enforce this, we require that all paths used as caches
408
+ to be declared as Docker volumes. This check won't catch all offenders.
409
+ But it is better than nothing.
410
+ """
411
+ if task is None:
412
+ return
413
+
414
+ taskdef = task.task
415
+ if taskdef.get("worker", {}).get("implementation") != "docker-worker":
416
+ return
417
+
418
+ volumes = set(taskdef["worker"]["volumes"])
419
+ paths = {c["mount-point"] for c in taskdef["worker"].get("caches", [])}
420
+ missing = paths - volumes
421
+
422
+ if missing:
423
+ raise Exception(
424
+ "task {} (image {}) has caches that are not declared as "
425
+ "Docker volumes: {} "
426
+ "(have you added them as VOLUMEs in the Dockerfile?)".format(
427
+ task.label,
428
+ taskdef["worker"]["docker-image"],
429
+ ", ".join(sorted(missing)),
430
+ )
431
+ )
432
+
433
+
304
434
  @verifications.add("optimized_task_graph")
305
435
  def verify_always_optimized(task, taskgraph, scratch_pad, graph_config, parameters):
306
436
  """
@@ -21,6 +21,9 @@ tasks:
21
21
  group-by: all
22
22
  unique-kinds: false
23
23
  set-name: null
24
+ with-attributes:
25
+ # exclude free-threaded python until it is officially supported
26
+ python: ["314", "313", "312", "311", "310", "39"]
24
27
  fetches:
25
28
  test:
26
29
  - artifact: coverage.py{matrix[python]}
@@ -21,3 +21,9 @@ tasks:
21
21
  group-by: all
22
22
  set-name: false
23
23
  unique-kinds: false
24
+ with-attributes:
25
+ # exclude free-threaded python until it is officially supported
26
+ python: ["314", "313", "312", "311", "310", "39"]
27
+ # needs to be added explicitly until we can drop the `with-attributes` above
28
+ dependencies:
29
+ check-type: check-type
@@ -41,8 +41,10 @@ tasks:
41
41
  description: "Run unit tests with py{matrix[python]}"
42
42
  matrix:
43
43
  set-name: "unit-py{matrix[python]}"
44
- substitution-fields: [description, run.command, treeherder, worker]
44
+ substitution-fields: [description, run.command, treeherder, worker, attributes]
45
45
  python: ["314t", "314", "313", "312", "311", "310", "39"]
46
+ attributes:
47
+ python: "{matrix[python]}"
46
48
  worker:
47
49
  artifacts:
48
50
  - type: file
@@ -410,8 +410,10 @@ def test_replace_tasks(
410
410
  {},
411
411
  make_opt_graph(
412
412
  make_task("t1", task_id="tid1", dependencies={}),
413
- make_task("t2", task_id="tid2", dependencies={"tid1"}),
414
- make_task("t3", task_id="tid3", dependencies={"tid1", "tid2"}),
413
+ make_task("t2", task_id="tid2", dependencies={"dep": "tid1"}),
414
+ make_task(
415
+ "t3", task_id="tid3", dependencies={"dep": "tid2", "dep2": "tid1"}
416
+ ),
415
417
  ("tid3", "tid2", "dep"),
416
418
  ("tid3", "tid1", "dep2"),
417
419
  ("tid2", "tid1", "dep"),
@@ -438,7 +440,11 @@ def test_replace_tasks(
438
440
  "label_to_taskid": {"t1": "e1", "t2": "e2"},
439
441
  },
440
442
  # expectations
441
- make_opt_graph(make_task("t3", task_id="tid1", dependencies={"e1", "e2"})),
443
+ make_opt_graph(
444
+ make_task(
445
+ "t3", task_id="tid1", dependencies={"dep": "e2", "dep2": "e1"}
446
+ )
447
+ ),
442
448
  {"t1": "e1", "t2": "e2", "t3": "tid1"},
443
449
  id="replaced",
444
450
  ),