taskcluster-taskgraph 16.2.0__tar.gz → 17.0.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 (268) hide show
  1. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/CHANGELOG.md +36 -0
  2. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/PKG-INFO +3 -4
  3. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/reference/migrations.rst +32 -0
  4. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/pyproject.toml +3 -4
  5. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/actions/cancel.py +9 -2
  6. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/actions/cancel_all.py +9 -2
  7. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/actions/registry.py +2 -2
  8. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/actions/retrigger.py +14 -11
  9. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/actions/util.py +2 -1
  10. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/config.py +1 -2
  11. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/decision.py +2 -79
  12. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/docker.py +8 -7
  13. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/generator.py +2 -2
  14. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/graph.py +53 -17
  15. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/main.py +2 -2
  16. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/morph.py +1 -1
  17. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/optimize/base.py +9 -7
  18. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/optimize/strategies.py +3 -1
  19. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/parameters.py +1 -1
  20. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/run-task/fetch-content +25 -15
  21. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/run-task/run-task +125 -76
  22. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/task.py +7 -7
  23. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/taskgraph.py +2 -3
  24. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/transforms/base.py +5 -5
  25. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/transforms/run/common.py +3 -3
  26. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/transforms/task.py +3 -3
  27. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/util/caches.py +3 -3
  28. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/util/dependencies.py +4 -3
  29. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/util/docker.py +2 -2
  30. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/util/hash.py +3 -3
  31. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/util/keyed_by.py +4 -3
  32. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/util/parameterization.py +4 -4
  33. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/util/taskcluster.py +18 -15
  34. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/util/templates.py +3 -3
  35. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/util/vcs.py +39 -19
  36. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/util/verify.py +3 -3
  37. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/util/workertypes.py +2 -2
  38. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/kinds/docker-image/kind.yml +1 -1
  39. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/kinds/test/kind.yml +1 -1
  40. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_decision.py +2 -89
  41. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_scripts_run_task.py +213 -62
  42. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_transforms_from_deps.py +1 -2
  43. taskcluster_taskgraph-17.0.0/test/test_util_archive.py +181 -0
  44. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_util_taskcluster.py +19 -4
  45. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_util_vcs.py +82 -0
  46. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/uv.lock +138 -1807
  47. taskcluster_taskgraph-16.2.0/test/test_util_archive.py +0 -174
  48. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/.codespell-ignore-words.txt +0 -0
  49. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/.github/CODEOWNERS +0 -0
  50. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/.github/dependabot.yml +0 -0
  51. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/.github/workflows/codeql-analysis.yml +0 -0
  52. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/.github/workflows/pre-commit-autoupdate.yml +0 -0
  53. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/.github/workflows/pre-commit.yml +0 -0
  54. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/.github/workflows/pypi-publish.yml +0 -0
  55. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/.gitignore +0 -0
  56. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/.pre-commit-config.yaml +0 -0
  57. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/.readthedocs.yaml +0 -0
  58. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/.taskcluster.yml +0 -0
  59. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/.yamllint +0 -0
  60. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/CODE_OF_CONDUCT.md +0 -0
  61. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/CONTRIBUTING.rst +0 -0
  62. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/LICENSE +0 -0
  63. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/Makefile +0 -0
  64. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/README.rst +0 -0
  65. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/concepts/index.rst +0 -0
  66. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/concepts/kind.rst +0 -0
  67. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/concepts/loading.rst +0 -0
  68. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/concepts/optimization.rst +0 -0
  69. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/concepts/overview.rst +0 -0
  70. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/concepts/scopes.rst +0 -0
  71. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/concepts/task-graphs.rst +0 -0
  72. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/concepts/transforms.rst +0 -0
  73. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/conf.py +0 -0
  74. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/contributing.rst +0 -0
  75. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/glossary.rst +0 -0
  76. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/howto/bootstrap-taskgraph.rst +0 -0
  77. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/howto/create-actions.rst +0 -0
  78. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/howto/create-tasks.rst +0 -0
  79. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/howto/debugging.rst +0 -0
  80. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/howto/docker.rst +0 -0
  81. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/howto/index.rst +0 -0
  82. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/howto/load-task-locally.rst +0 -0
  83. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/howto/resolve-keyed-by.rst +0 -0
  84. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/howto/run-locally.rst +0 -0
  85. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/howto/send-notifications.rst +0 -0
  86. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/howto/use-fetches.rst +0 -0
  87. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/index.rst +0 -0
  88. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/reference/cli.rst +0 -0
  89. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/reference/index.rst +0 -0
  90. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/reference/optimization-strategies.rst +0 -0
  91. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/reference/parameters.rst +0 -0
  92. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/reference/source/modules.rst +0 -0
  93. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/reference/source/taskgraph.actions.rst +0 -0
  94. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/reference/source/taskgraph.loader.rst +0 -0
  95. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/reference/source/taskgraph.optimize.rst +0 -0
  96. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/reference/source/taskgraph.rst +0 -0
  97. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/reference/source/taskgraph.transforms.rst +0 -0
  98. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/reference/source/taskgraph.transforms.run.rst +0 -0
  99. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/reference/source/taskgraph.util.rst +0 -0
  100. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/reference/transforms/chunking.rst +0 -0
  101. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/reference/transforms/from_deps.rst +0 -0
  102. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/reference/transforms/index.rst +0 -0
  103. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/reference/transforms/matrix.rst +0 -0
  104. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/reference/transforms/task_context.rst +0 -0
  105. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/tutorials/connecting-taskcluster.rst +0 -0
  106. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/tutorials/creating-a-task-graph.rst +0 -0
  107. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/tutorials/example-taskcluster.yml +0 -0
  108. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/tutorials/getting-started.rst +0 -0
  109. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/docs/tutorials/index.rst +0 -0
  110. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/make.bat +0 -0
  111. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/packages/pytest-taskgraph/README.md +0 -0
  112. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/packages/pytest-taskgraph/pyproject.toml +0 -0
  113. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/packages/pytest-taskgraph/src/pytest_taskgraph/__init__.py +0 -0
  114. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/packages/pytest-taskgraph/src/pytest_taskgraph/fixtures/gen.py +0 -0
  115. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/packages/pytest-taskgraph/src/pytest_taskgraph/fixtures/vcs.py +0 -0
  116. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/packages/sphinx-taskgraph/README.md +0 -0
  117. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/packages/sphinx-taskgraph/pyproject.toml +0 -0
  118. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/packages/sphinx-taskgraph/src/sphinx_taskgraph/__init__.py +0 -0
  119. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/packages/sphinx-taskgraph/src/sphinx_taskgraph/autoschema.py +0 -0
  120. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/__init__.py +0 -0
  121. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/actions/__init__.py +0 -0
  122. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/actions/add_new_jobs.py +0 -0
  123. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/actions/rebuild_cached_tasks.py +0 -0
  124. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/create.py +0 -0
  125. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/filter_tasks.py +0 -0
  126. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/loader/__init__.py +0 -0
  127. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/loader/default.py +0 -0
  128. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/loader/transform.py +0 -0
  129. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/optimize/__init__.py +0 -0
  130. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/run-task/hgrc +0 -0
  131. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/run-task/robustcheckout.py +0 -0
  132. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/target_tasks.py +0 -0
  133. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/transforms/__init__.py +0 -0
  134. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/transforms/cached_tasks.py +0 -0
  135. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/transforms/chunking.py +0 -0
  136. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/transforms/code_review.py +0 -0
  137. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/transforms/docker_image.py +0 -0
  138. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/transforms/fetch.py +0 -0
  139. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/transforms/from_deps.py +0 -0
  140. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/transforms/matrix.py +0 -0
  141. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/transforms/notify.py +0 -0
  142. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/transforms/run/__init__.py +0 -0
  143. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/transforms/run/index_search.py +0 -0
  144. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/transforms/run/run_task.py +0 -0
  145. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/transforms/run/toolchain.py +0 -0
  146. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/transforms/task_context.py +0 -0
  147. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/util/__init__.py +0 -0
  148. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/util/archive.py +0 -0
  149. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/util/attributes.py +0 -0
  150. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/util/cached_tasks.py +0 -0
  151. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/util/copy.py +0 -0
  152. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/util/json.py +0 -0
  153. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/util/path.py +0 -0
  154. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/util/python_path.py +0 -0
  155. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/util/readonlydict.py +0 -0
  156. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/util/schema.py +0 -0
  157. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/util/set_name.py +0 -0
  158. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/util/shell.py +0 -0
  159. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/util/taskgraph.py +0 -0
  160. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/util/time.py +0 -0
  161. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/util/treeherder.py +0 -0
  162. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/src/taskgraph/util/yaml.py +0 -0
  163. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/config.yml +0 -0
  164. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/docker/REGISTRY +0 -0
  165. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/docker/decision/Dockerfile +0 -0
  166. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/docker/decision/HASH +0 -0
  167. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/docker/decision/README.md +0 -0
  168. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/docker/decision/VERSION +0 -0
  169. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/docker/decision/system-setup.sh +0 -0
  170. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/docker/fetch/Dockerfile +0 -0
  171. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/docker/image_builder/README.rst +0 -0
  172. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/docker/index-task/Dockerfile +0 -0
  173. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/docker/index-task/README +0 -0
  174. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/docker/index-task/insert-indexes.js +0 -0
  175. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/docker/index-task/package.json +0 -0
  176. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/docker/index-task/yarn.lock +0 -0
  177. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/docker/python/Dockerfile +0 -0
  178. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/docker/run-task/Dockerfile +0 -0
  179. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/docker/run-task/system-setup.sh +0 -0
  180. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/docker/skopeo/Dockerfile +0 -0
  181. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/docker/skopeo/policy.json +0 -0
  182. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/docker/skopeo/push_image.sh +0 -0
  183. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/kinds/check/kind.yml +0 -0
  184. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/kinds/codecov/kind.yml +0 -0
  185. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/kinds/complete/kind.yml +0 -0
  186. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/kinds/doc/kind.yml +0 -0
  187. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/kinds/fetch/kind.yml +0 -0
  188. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/kinds/push-image/kind.yml +0 -0
  189. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/scripts/codecov-upload.py +0 -0
  190. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/scripts/external_tools/tooltool.py +0 -0
  191. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/self_taskgraph/__init__.py +0 -0
  192. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/self_taskgraph/custom_parameters.py +0 -0
  193. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/self_taskgraph/custom_target_tasks.py +0 -0
  194. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/self_taskgraph/transforms/add_pr_route.py +0 -0
  195. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/self_taskgraph/transforms/push_image.py +0 -0
  196. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/test/params/main-repo-pull-request-untrusted.yml +0 -0
  197. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/test/params/main-repo-pull-request.yml +0 -0
  198. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/test/params/main-repo-push.yml +0 -0
  199. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/test/params/main-repo-release-pytest-taskgraph.yml +0 -0
  200. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/taskcluster/test/params/main-repo-release-taskcluster-taskgraph.yml +0 -0
  201. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/template/cookiecutter.json +0 -0
  202. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/template/hooks/post_gen_project.py +0 -0
  203. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/template/{{cookiecutter.project_name}}/taskcluster/config.yml +0 -0
  204. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/template/{{cookiecutter.project_name}}/taskcluster/docker/linux/Dockerfile +0 -0
  205. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/template/{{cookiecutter.project_name}}/taskcluster/kinds/docker-image/kind.yml +0 -0
  206. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/template/{{cookiecutter.project_name}}/taskcluster/kinds/hello/kind.yml +0 -0
  207. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/template/{{cookiecutter.project_name}}/taskcluster/{{cookiecutter.project_slug}}_taskgraph/transforms/hello.py +0 -0
  208. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/template/{{cookiecutter.project_name}}/taskcluster.github.yml +0 -0
  209. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/__init__.py +0 -0
  210. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/automationrelevance.json +0 -0
  211. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/conftest.py +0 -0
  212. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/data/task_context.yml +0 -0
  213. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/data/taskcluster/config.yml +0 -0
  214. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/data/taskcluster/docker/hello-world/Dockerfile +0 -0
  215. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/data/taskcluster/docker/hello-world-tag/Dockerfile +0 -0
  216. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/data/taskcluster/docker/hello-world-tag/REGISTRY +0 -0
  217. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/data/taskcluster/docker/hello-world-tag/VERSION +0 -0
  218. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/data/taskcluster/kinds/docker-image/kind.yml +0 -0
  219. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/data/taskcluster/scripts/toolchain/run.ps1 +0 -0
  220. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/data/taskcluster/scripts/toolchain/run.sh +0 -0
  221. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/data/taskcluster/test_taskgraph/transforms/foo.py +0 -0
  222. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/data/testmod/thing.py +0 -0
  223. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/mockedopen.py +0 -0
  224. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_actions_rebuild_cached_tasks.py +0 -0
  225. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_actions_registry.py +0 -0
  226. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_config.py +0 -0
  227. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_create.py +0 -0
  228. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_docker.py +0 -0
  229. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_generator.py +0 -0
  230. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_graph.py +0 -0
  231. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_main.py +0 -0
  232. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_morph.py +0 -0
  233. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_optimize.py +0 -0
  234. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_optimize_strategies.py +0 -0
  235. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_parameters.py +0 -0
  236. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_scripts_fetch_content.py +0 -0
  237. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_target_tasks.py +0 -0
  238. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_taskgraph.py +0 -0
  239. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_transform_chunking.py +0 -0
  240. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_transform_docker_image.py +0 -0
  241. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_transform_task_context.py +0 -0
  242. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_transforms_base.py +0 -0
  243. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_transforms_cached_tasks.py +0 -0
  244. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_transforms_fetch.py +0 -0
  245. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_transforms_matrix.py +0 -0
  246. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_transforms_notify.py +0 -0
  247. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_transforms_run.py +0 -0
  248. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_transforms_run_run_task.py +0 -0
  249. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_transforms_run_toolchain.py +0 -0
  250. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_transforms_task.py +0 -0
  251. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_util_attributes.py +0 -0
  252. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_util_cached_tasks.py +0 -0
  253. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_util_copy.py +0 -0
  254. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_util_dependencies.py +0 -0
  255. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_util_docker.py +0 -0
  256. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_util_json.py +0 -0
  257. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_util_keyed_by.py +0 -0
  258. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_util_parameterization.py +0 -0
  259. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_util_path.py +0 -0
  260. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_util_python_path.py +0 -0
  261. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_util_readonlydict.py +0 -0
  262. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_util_schema.py +0 -0
  263. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_util_templates.py +0 -0
  264. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_util_time.py +0 -0
  265. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_util_treeherder.py +0 -0
  266. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_util_verify.py +0 -0
  267. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_util_workertypes.py +0 -0
  268. {taskcluster_taskgraph-16.2.0 → taskcluster_taskgraph-17.0.0}/test/test_util_yaml.py +0 -0
@@ -1,4 +1,40 @@
1
1
  # Change Log
2
+
3
+ ## [17.0.0] - 2025-10-17
4
+
5
+ ### Changed
6
+
7
+ - BREAKING CHANGE: Dropped support for Python 3.8
8
+ - BREAKING CHANGE: `base_ref` parameter no longer gets reset to default branch by Decision task
9
+ - BREAKING CHANGE: `base_rev` parameter no longer gets reset to merge-base by Decision task
10
+ - BREAKING CHANGE: `run-task` script no longer fetches or checks out `base_ref` parameter
11
+ - BREAKING CHANGE: `run-task` script no longer fetches all heads if `head_ref` was not specified
12
+
13
+ ### Added
14
+
15
+ - `run-task` now supports shallow Git clones
16
+ - Improved support for shallow clones in `repo.get_changed_files()`
17
+
18
+ ### Perf
19
+
20
+ - Improvements to graph traversal logic and caching
21
+
22
+ ### Fixed
23
+
24
+ - Bug in `retrigger-multiple` action's schema definition
25
+ - `run-task` no longer fetches head ref twice in some scenarios
26
+ - `run-task` avoids fetching tags in some scenarios when not necessary
27
+ - `run-task` properly normalizes `head_ref` before checking it out
28
+ - Appropriate exception now being caught in various `taskcluster` call sites
29
+
30
+ ## [16.2.1] - 2025-10-14
31
+
32
+ ### Fixed
33
+
34
+ - `run-task` script now cleans up zombie processes
35
+ - Fixed regression to `taskgraph.util.taskcluster.list_artifacts`
36
+ - Fixed regression to `taskgraph.util.taskcluster.get_artifact`
37
+
2
38
  ## [16.2.0] - 2025-09-26
3
39
 
4
40
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: taskcluster-taskgraph
3
- Version: 16.2.0
3
+ Version: 17.0.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
@@ -9,14 +9,13 @@ License-File: LICENSE
9
9
  Classifier: Development Status :: 5 - Production/Stable
10
10
  Classifier: Environment :: Console
11
11
  Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)
12
- Classifier: Programming Language :: Python :: 3.8
13
12
  Classifier: Programming Language :: Python :: 3.9
14
13
  Classifier: Programming Language :: Python :: 3.10
15
14
  Classifier: Programming Language :: Python :: 3.11
16
15
  Classifier: Programming Language :: Python :: 3.12
17
16
  Classifier: Programming Language :: Python :: 3.13
18
17
  Classifier: Topic :: Software Development
19
- Requires-Python: >=3.8
18
+ Requires-Python: >=3.9
20
19
  Requires-Dist: appdirs>=1.4
21
20
  Requires-Dist: cookiecutter~=2.1
22
21
  Requires-Dist: json-e>=2.7
@@ -26,7 +25,7 @@ Requires-Dist: redo>=2.0
26
25
  Requires-Dist: requests>=2.25
27
26
  Requires-Dist: slugid>=2.0
28
27
  Requires-Dist: taskcluster-urls>=11.0
29
- Requires-Dist: taskcluster>=55.0
28
+ Requires-Dist: taskcluster>=91.0
30
29
  Requires-Dist: voluptuous>=0.12.1
31
30
  Provides-Extra: load-image
32
31
  Requires-Dist: zstandard; extra == 'load-image'
@@ -3,6 +3,38 @@ Migration Guide
3
3
 
4
4
  This page can help when migrating Taskgraph across major versions.
5
5
 
6
+ 16.x -> 17.x
7
+ ------------
8
+
9
+ * Upgrade to Python 3.9 or above.
10
+ * The ``base_ref`` parameter could now be ``None`` if it wasn't explicitly
11
+ passed into the Decision task. If this was relied upon, do the following
12
+ instead:
13
+
14
+ .. code-block:: python
15
+
16
+ from taskgraph.util.vcs import get_repository
17
+
18
+ repo = get_repository()
19
+ base_ref = repo.default_branch
20
+
21
+ * The ``base_rev`` parameter is no longer being reset to the merge-base. This
22
+ means in some cases, ``base_rev`` might not actually be an ancestor of
23
+ ``head_rev``. If you need the merge-base, you can use:
24
+
25
+ .. code-block:: python
26
+
27
+ from taskgraph.util.vcs import get_repository
28
+
29
+ repo = get_repository()
30
+ base_rev = repo.find_latest_common_revision(parameters["base_rev"], parameters["head_rev"])
31
+
32
+ * The ``base_ref`` is no longer being fetched by ``run-task``. If you were
33
+ relying on it, you can run ``git fetch origin <base_ref>`` in a subprocess.
34
+ * The ``run-task`` scripts no longer fetches all heads when ``head_ref`` isn't
35
+ specified. If this behaviour was relied upon, you can run
36
+ ``git fetch +refs/heads/*:refs/remotes/work/*`` in a subprocess.
37
+
6
38
  15.x -> 16.x
7
39
  ------------
8
40
 
@@ -1,7 +1,7 @@
1
1
  ### Project
2
2
  [project]
3
3
  name = "taskcluster-taskgraph"
4
- version = "16.2.0"
4
+ version = "17.0.0"
5
5
  description = "Build taskcluster taskgraphs"
6
6
  readme = "README.rst"
7
7
  authors = [
@@ -11,7 +11,6 @@ classifiers = [
11
11
  "Development Status :: 5 - Production/Stable",
12
12
  "Environment :: Console",
13
13
  "License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)",
14
- "Programming Language :: Python :: 3.8",
15
14
  "Programming Language :: Python :: 3.9",
16
15
  "Programming Language :: Python :: 3.10",
17
16
  "Programming Language :: Python :: 3.11",
@@ -19,7 +18,7 @@ classifiers = [
19
18
  "Programming Language :: Python :: 3.13",
20
19
  "Topic :: Software Development",
21
20
  ]
22
- requires-python = ">=3.8"
21
+ requires-python = ">=3.9"
23
22
  dependencies = [
24
23
  "appdirs>=1.4",
25
24
  "cookiecutter~=2.1",
@@ -29,7 +28,7 @@ dependencies = [
29
28
  "redo>=2.0",
30
29
  "requests>=2.25",
31
30
  "slugid>=2.0",
32
- "taskcluster>=55.0",
31
+ "taskcluster>=91.0",
33
32
  "taskcluster-urls>=11.0",
34
33
  "voluptuous>=0.12.1",
35
34
  ]
@@ -7,6 +7,7 @@ import logging
7
7
 
8
8
  import requests
9
9
 
10
+ from taskcluster import TaskclusterRestFailure
10
11
  from taskgraph.util.taskcluster import cancel_task
11
12
 
12
13
  from .registry import register_callback_action
@@ -27,8 +28,14 @@ def cancel_action(parameters, graph_config, input, task_group_id, task_id):
27
28
  # only cancel tasks with the level-specific schedulerId.
28
29
  try:
29
30
  cancel_task(task_id)
30
- except requests.HTTPError as e:
31
- if e.response.status_code == 409:
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:
32
39
  # A 409 response indicates that this task is past its deadline. It
33
40
  # cannot be cancelled at this time, but it's also not running
34
41
  # anymore, so we can ignore this error.
@@ -9,6 +9,7 @@ from concurrent import futures
9
9
 
10
10
  import requests
11
11
 
12
+ from taskcluster import TaskclusterRestFailure
12
13
  from taskgraph.util.taskcluster import (
13
14
  CONCURRENCY,
14
15
  cancel_task,
@@ -36,8 +37,14 @@ def cancel_all_action(parameters, graph_config, input, task_group_id, task_id):
36
37
  logger.info(f"Cancelling task {task_id}")
37
38
  try:
38
39
  cancel_task(task_id)
39
- except requests.HTTPError as e:
40
- if e.response.status_code == 409:
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:
41
48
  # A 409 response indicates that this task is past its deadline. It
42
49
  # cannot be cancelled at this time, but it's also not running
43
50
  # anymore, so we can ignore this error.
@@ -30,13 +30,13 @@ def is_json(data):
30
30
  return True
31
31
 
32
32
 
33
- @functools.lru_cache(maxsize=None)
33
+ @functools.cache
34
34
  def read_taskcluster_yml(filename):
35
35
  """Load and parse .taskcluster.yml, cached to save some time"""
36
36
  return yaml.load_yaml(filename)
37
37
 
38
38
 
39
- @functools.lru_cache(maxsize=None)
39
+ @functools.cache
40
40
  def hash_taskcluster_yml(filename):
41
41
  """
42
42
  Generate a hash of the given .taskcluster.yml. This is the first 10 digits
@@ -233,17 +233,20 @@ def _rerun_task(task_id, label):
233
233
  "requests": {
234
234
  "type": "array",
235
235
  "items": {
236
- "tasks": {
237
- "type": "array",
238
- "description": "An array of task labels",
239
- "items": {"type": "string"},
240
- },
241
- "times": {
242
- "type": "integer",
243
- "minimum": 1,
244
- "maximum": 100,
245
- "title": "Times",
246
- "description": "How many times to run each task.",
236
+ "type": "object",
237
+ "properties": {
238
+ "tasks": {
239
+ "type": "array",
240
+ "description": "An array of task labels",
241
+ "items": {"type": "string"},
242
+ },
243
+ "times": {
244
+ "type": "integer",
245
+ "minimum": 1,
246
+ "maximum": 100,
247
+ "title": "Times",
248
+ "description": "How many times to run each task.",
249
+ },
247
250
  },
248
251
  "additionalProperties": False,
249
252
  },
@@ -11,6 +11,7 @@ from concurrent import futures
11
11
  from functools import reduce
12
12
 
13
13
  from requests.exceptions import HTTPError
14
+ from taskcluster.exceptions import TaskclusterRestFailure
14
15
 
15
16
  from taskgraph import create
16
17
  from taskgraph.decision import read_artifact, rename_artifact, write_artifact
@@ -36,7 +37,7 @@ def fetch_graph_and_labels(parameters, graph_config, task_group_id=None):
36
37
  try:
37
38
  # Look up the decision_task id in the index
38
39
  decision_task_id = find_decision_task(parameters, graph_config)
39
- except KeyError:
40
+ except (KeyError, TaskclusterRestFailure):
40
41
  if not task_group_id:
41
42
  raise
42
43
  # Not found (e.g. from github-pull-request), fall back to the task group id.
@@ -8,7 +8,6 @@ import os
8
8
  import sys
9
9
  from dataclasses import dataclass
10
10
  from pathlib import Path
11
- from typing import Dict
12
11
 
13
12
  from voluptuous import ALLOW_EXTRA, All, Any, Extra, Length, Optional, Required
14
13
 
@@ -113,7 +112,7 @@ graph_config_schema = Schema(
113
112
 
114
113
  @dataclass(frozen=True, eq=False)
115
114
  class GraphConfig:
116
- _config: Dict
115
+ _config: dict
117
116
  root_dir: str
118
117
 
119
118
  _PATH_MODIFIED = False
@@ -21,7 +21,7 @@ from taskgraph.taskgraph import TaskGraph
21
21
  from taskgraph.util import json
22
22
  from taskgraph.util.python_path import find_object
23
23
  from taskgraph.util.schema import Schema, validate_schema
24
- from taskgraph.util.vcs import Repository, get_repository
24
+ from taskgraph.util.vcs import get_repository
25
25
  from taskgraph.util.yaml import load_yaml
26
26
 
27
27
  logger = logging.getLogger(__name__)
@@ -192,25 +192,10 @@ def get_decision_parameters(graph_config, options):
192
192
  except UnicodeDecodeError:
193
193
  commit_message = ""
194
194
 
195
- parameters["base_ref"] = _determine_more_accurate_base_ref(
196
- repo,
197
- candidate_base_ref=options.get("base_ref"),
198
- head_ref=options.get("head_ref"),
199
- base_rev=options.get("base_rev"),
200
- )
201
-
202
- parameters["base_rev"] = _determine_more_accurate_base_rev(
203
- repo,
204
- base_ref=parameters["base_ref"],
205
- candidate_base_rev=options.get("base_rev"),
206
- head_rev=options.get("head_rev"),
207
- env_prefix=_get_env_prefix(graph_config),
208
- )
209
-
210
195
  # Define default filter list, as most configurations shouldn't need
211
196
  # custom filters.
212
197
  parameters["files_changed"] = repo.get_changed_files(
213
- rev=parameters["head_rev"], base_rev=parameters["base_rev"]
198
+ rev=parameters["head_rev"], base=parameters["base_rev"]
214
199
  )
215
200
  parameters["filters"] = [
216
201
  "target_tasks_method",
@@ -284,68 +269,6 @@ def get_decision_parameters(graph_config, options):
284
269
  return result
285
270
 
286
271
 
287
- def _determine_more_accurate_base_ref(repo, candidate_base_ref, head_ref, base_rev):
288
- base_ref = candidate_base_ref
289
-
290
- if not candidate_base_ref:
291
- base_ref = repo.default_branch
292
- elif candidate_base_ref == head_ref and base_rev == Repository.NULL_REVISION:
293
- logger.info(
294
- "base_ref and head_ref are identical but base_rev equals the null revision. "
295
- "This is a new branch but Github didn't identify its actual base."
296
- )
297
- base_ref = repo.default_branch
298
-
299
- if base_ref != candidate_base_ref:
300
- logger.info(
301
- f'base_ref has been reset from "{candidate_base_ref}" to "{base_ref}".'
302
- )
303
-
304
- return base_ref
305
-
306
-
307
- def _determine_more_accurate_base_rev(
308
- repo, base_ref, candidate_base_rev, head_rev, env_prefix
309
- ):
310
- if not candidate_base_rev:
311
- logger.info("base_rev is not set.")
312
- base_ref_or_rev = base_ref
313
- elif candidate_base_rev == Repository.NULL_REVISION:
314
- logger.info("base_rev equals the null revision. This branch is a new one.")
315
- base_ref_or_rev = base_ref
316
- elif not repo.does_revision_exist_locally(candidate_base_rev):
317
- logger.warning(
318
- "base_rev does not exist locally. It is likely because the branch was force-pushed. "
319
- "taskgraph is not able to assess how many commits were changed and assumes it is only "
320
- f"the last one. Please set the {env_prefix.upper()}_BASE_REV environment variable "
321
- "in the decision task and provide `--base-rev` to taskgraph."
322
- )
323
- base_ref_or_rev = base_ref
324
- else:
325
- base_ref_or_rev = candidate_base_rev
326
-
327
- if base_ref_or_rev == base_ref:
328
- logger.info(
329
- f'Using base_ref "{base_ref}" to determine latest common revision...'
330
- )
331
-
332
- base_rev = repo.find_latest_common_revision(base_ref_or_rev, head_rev)
333
- if base_rev != candidate_base_rev:
334
- if base_ref_or_rev == candidate_base_rev:
335
- logger.info("base_rev is not an ancestor of head_rev.")
336
-
337
- logger.info(
338
- f'base_rev has been reset from "{candidate_base_rev}" to "{base_rev}".'
339
- )
340
-
341
- return base_rev
342
-
343
-
344
- def _get_env_prefix(graph_config):
345
- repo_keys = list(graph_config["taskgraph"].get("repositories", {}).keys())
346
- return repo_keys[0] if repo_keys else ""
347
-
348
-
349
272
  def set_try_config(parameters, task_config_file):
350
273
  if os.path.isfile(task_config_file):
351
274
  logger.info(f"using try tasks from {task_config_file}")
@@ -11,10 +11,11 @@ import subprocess
11
11
  import sys
12
12
  import tarfile
13
13
  import tempfile
14
+ from collections.abc import Generator
14
15
  from io import BytesIO
15
16
  from pathlib import Path
16
17
  from textwrap import dedent
17
- from typing import Any, Dict, Generator, List, Optional, Union
18
+ from typing import Any, Optional, Union
18
19
 
19
20
  from taskcluster.exceptions import TaskclusterRestFailure
20
21
 
@@ -246,7 +247,7 @@ def build_image(
246
247
 
247
248
  def load_image(
248
249
  url: str, imageName: Optional[str] = None, imageTag: Optional[str] = None
249
- ) -> Dict[str, str]:
250
+ ) -> dict[str, str]:
250
251
  """Load docker image from URL as imageName:tag.
251
252
 
252
253
  Downloads a zstd-compressed docker image tarball from the given URL and
@@ -286,7 +287,7 @@ def load_image(
286
287
  else:
287
288
  imageTag = "latest"
288
289
 
289
- info: Dict[str, str] = {}
290
+ info: dict[str, str] = {}
290
291
 
291
292
  def download_and_modify_image() -> Generator[bytes, None, None]:
292
293
  # This function downloads and edits the downloaded tar file on the fly.
@@ -377,14 +378,14 @@ def load_image(
377
378
  return info
378
379
 
379
380
 
380
- def _index(l: List, s: str) -> Optional[int]:
381
+ def _index(l: list, s: str) -> Optional[int]:
381
382
  try:
382
383
  return l.index(s)
383
384
  except ValueError:
384
385
  pass
385
386
 
386
387
 
387
- def _resolve_image(image: Union[str, Dict[str, str]], graph_config: GraphConfig) -> str:
388
+ def _resolve_image(image: Union[str, dict[str, str]], graph_config: GraphConfig) -> str:
388
389
  image_task_id = None
389
390
 
390
391
  # Standard case, image comes from the task definition.
@@ -419,12 +420,12 @@ def _resolve_image(image: Union[str, Dict[str, str]], graph_config: GraphConfig)
419
420
 
420
421
  def load_task(
421
422
  graph_config: GraphConfig,
422
- task: Union[str, Dict[str, Any]],
423
+ task: Union[str, dict[str, Any]],
423
424
  remove: bool = True,
424
425
  user: Optional[str] = None,
425
426
  custom_image: Optional[str] = None,
426
427
  interactive: Optional[bool] = False,
427
- volumes: Optional[Dict[str, str]] = None,
428
+ volumes: Optional[dict[str, str]] = None,
428
429
  ) -> int:
429
430
  """Load and run a task interactively in a Docker container.
430
431
 
@@ -14,7 +14,7 @@ from concurrent.futures import (
14
14
  wait,
15
15
  )
16
16
  from dataclasses import dataclass
17
- from typing import Callable, Dict, Optional, Union
17
+ from typing import Callable, Optional, Union
18
18
 
19
19
  from . import filter_tasks
20
20
  from .config import GraphConfig, load_graph_config
@@ -42,7 +42,7 @@ class KindNotFound(Exception):
42
42
  class Kind:
43
43
  name: str
44
44
  path: str
45
- config: Dict
45
+ config: dict
46
46
  graph_config: GraphConfig
47
47
 
48
48
  def _get_loader(self) -> Callable:
@@ -4,12 +4,19 @@
4
4
 
5
5
 
6
6
  import collections
7
+ import functools
7
8
  from dataclasses import dataclass
8
- from typing import FrozenSet
9
+
10
+ from .util.readonlydict import ReadOnlyDict
9
11
 
10
12
 
11
13
  @dataclass(frozen=True)
12
- class Graph:
14
+ class _Graph:
15
+ nodes: frozenset
16
+ edges: frozenset
17
+
18
+
19
+ class Graph(_Graph):
13
20
  """Generic representation of a directed acyclic graph with labeled edges
14
21
  connecting the nodes. Graph operations are implemented in a functional
15
22
  manner, so the data structure is immutable.
@@ -24,8 +31,8 @@ class Graph:
24
31
  node `left` to node `right`..
25
32
  """
26
33
 
27
- nodes: FrozenSet
28
- edges: FrozenSet
34
+ def __init__(self, nodes, edges):
35
+ super().__init__(frozenset(nodes), frozenset(edges))
29
36
 
30
37
  def transitive_closure(self, nodes, reverse=False):
31
38
  """Return the transitive closure of <nodes>: the graph containing all
@@ -68,23 +75,28 @@ class Graph:
68
75
  add_nodes = {(left if reverse else right) for (left, right, _) in add_edges}
69
76
  new_nodes = nodes | add_nodes
70
77
  new_edges = edges | add_edges
71
- return Graph(new_nodes, new_edges) # type: ignore
78
+ return Graph(new_nodes, new_edges)
72
79
 
73
80
  def _visit(self, reverse):
74
- queue = collections.deque(sorted(self.nodes))
75
- links_by_node = self.reverse_links_dict() if reverse else self.links_dict()
76
- seen = set()
81
+ forward_links, reverse_links = self.links_and_reverse_links_dict()
82
+
83
+ dependencies = reverse_links if reverse else forward_links
84
+ dependents = forward_links if reverse else reverse_links
85
+
86
+ indegree = {node: len(dependencies[node]) for node in self.nodes}
87
+
88
+ queue = collections.deque(
89
+ node for node, degree in indegree.items() if degree == 0
90
+ )
91
+
77
92
  while queue:
78
93
  node = queue.popleft()
79
- if node in seen:
80
- continue
81
- links = links_by_node[node]
82
- if all((n in seen) for n in links):
83
- seen.add(node)
84
- yield node
85
- else:
86
- queue.extend(n for n in links if n not in seen)
87
- queue.append(node)
94
+ yield node
95
+
96
+ for dependent in dependents[node]:
97
+ indegree[dependent] -= 1
98
+ if indegree[dependent] == 0:
99
+ queue.append(dependent)
88
100
 
89
101
  def visit_postorder(self):
90
102
  """
@@ -103,6 +115,30 @@ class Graph:
103
115
  """
104
116
  return self._visit(True)
105
117
 
118
+ @functools.cache
119
+ def links_and_reverse_links_dict(self):
120
+ """
121
+ Return both links and reverse_links dictionaries.
122
+ Returns a (forward_links, reverse_links) tuple where forward_links maps
123
+ each node to the set of nodes it links to, and reverse_links maps each
124
+ node to the set of nodes linking to it.
125
+
126
+ Because the return value is cached, this function returns a pair of
127
+ `ReadOnlyDict` instead of defaultdicts like its `links_dict` and
128
+ `reverse_links_dict` counterparts to avoid consumers modifying the
129
+ cached value by mistake.
130
+ """
131
+ forward = {node: set() for node in self.nodes}
132
+ reverse = {node: set() for node in self.nodes}
133
+ for left, right, _ in self.edges:
134
+ forward[left].add(right)
135
+ reverse[right].add(left)
136
+
137
+ return (
138
+ ReadOnlyDict({key: frozenset(value) for key, value in forward.items()}),
139
+ ReadOnlyDict({key: frozenset(value) for key, value in reverse.items()}),
140
+ )
141
+
106
142
  def links_dict(self):
107
143
  """
108
144
  Return a dictionary mapping each node to a set of the nodes it links to
@@ -16,7 +16,7 @@ from collections import namedtuple
16
16
  from concurrent.futures import ProcessPoolExecutor, as_completed
17
17
  from pathlib import Path
18
18
  from textwrap import dedent
19
- from typing import Any, List
19
+ from typing import Any
20
20
  from urllib.parse import urlparse
21
21
 
22
22
  import appdirs
@@ -412,7 +412,7 @@ def show_taskgraph(options):
412
412
  overrides = {
413
413
  "target-kinds": options.get("target_kinds"),
414
414
  }
415
- parameters: List[Any[str, Parameters]] = options.pop("parameters")
415
+ parameters: list[Any[str, Parameters]] = options.pop("parameters")
416
416
  if not parameters:
417
417
  parameters = [
418
418
  parameters_loader(None, strict=False, overrides=overrides)
@@ -51,7 +51,7 @@ def amend_taskgraph(taskgraph, label_to_taskid, to_add):
51
51
  for depname, dep in task.dependencies.items():
52
52
  new_edges.add((task.task_id, dep, depname))
53
53
 
54
- taskgraph = TaskGraph(new_tasks, Graph(set(new_tasks), new_edges)) # type: ignore
54
+ taskgraph = TaskGraph(new_tasks, Graph(frozenset(new_tasks), new_edges))
55
55
  return taskgraph, label_to_taskid
56
56
 
57
57
 
@@ -15,7 +15,6 @@ import datetime
15
15
  import logging
16
16
  from abc import ABCMeta, abstractmethod
17
17
  from collections import defaultdict
18
- from typing import Dict, Set
19
18
 
20
19
  from slugid import nice as slugid
21
20
 
@@ -298,8 +297,9 @@ def replace_tasks(
298
297
 
299
298
  opt_counts = defaultdict(int)
300
299
  replaced = set()
301
- dependents_of = target_task_graph.graph.reverse_links_dict()
302
- dependencies_of = target_task_graph.graph.links_dict()
300
+ dependencies_of, dependents_of = (
301
+ target_task_graph.graph.links_and_reverse_links_dict()
302
+ )
303
303
 
304
304
  for label in target_task_graph.graph.visit_postorder():
305
305
  logger.debug(f"replace_tasks: {label}")
@@ -367,9 +367,9 @@ def replace_tasks(
367
367
 
368
368
  def get_subgraph(
369
369
  target_task_graph: TaskGraph,
370
- removed_tasks: Set[str],
371
- replaced_tasks: Set[str],
372
- label_to_taskid: Dict[str, str],
370
+ removed_tasks: set[str],
371
+ replaced_tasks: set[str],
372
+ label_to_taskid: dict[str, str],
373
373
  decision_task_id: str,
374
374
  ):
375
375
  """
@@ -452,7 +452,9 @@ def get_subgraph(
452
452
  if left in tasks_by_taskid and right in tasks_by_taskid
453
453
  }
454
454
 
455
- return TaskGraph(tasks_by_taskid, Graph(set(tasks_by_taskid), edges_by_taskid)) # type: ignore
455
+ return TaskGraph(
456
+ tasks_by_taskid, Graph(frozenset(tasks_by_taskid), edges_by_taskid)
457
+ )
456
458
 
457
459
 
458
460
  @register_strategy("never")
@@ -1,6 +1,8 @@
1
1
  import logging
2
2
  from datetime import datetime
3
3
 
4
+ from taskcluster.exceptions import TaskclusterRestFailure
5
+
4
6
  from taskgraph.optimize.base import OptimizationStrategy, register_strategy
5
7
  from taskgraph.util.path import match as match_path
6
8
  from taskgraph.util.taskcluster import find_task_id, status_task
@@ -64,7 +66,7 @@ class IndexSearch(OptimizationStrategy):
64
66
  continue
65
67
 
66
68
  return task_id
67
- except KeyError:
69
+ except (KeyError, TaskclusterRestFailure):
68
70
  # go on to the next index path
69
71
  pass
70
72