taskcluster-taskgraph 11.2.1__tar.gz → 11.2.3__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 (246) hide show
  1. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/.pre-commit-config.yaml +2 -2
  2. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/CHANGELOG.md +18 -0
  3. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/PKG-INFO +2 -1
  4. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/pyproject.toml +1 -0
  5. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/__init__.py +1 -1
  6. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/run-task/fetch-content +50 -4
  7. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/run-task/run-task +3 -2
  8. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/docker/decision/Dockerfile +0 -3
  9. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/docker/decision/system-setup.sh +4 -2
  10. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/docker/python/Dockerfile +2 -2
  11. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/docker/run-task/Dockerfile +3 -0
  12. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/kinds/docker-image/kind.yml +5 -1
  13. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/kinds/test/kind.yml +1 -1
  14. taskcluster_taskgraph-11.2.3/test/test_scripts_fetch_content.py +178 -0
  15. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_scripts_run_task.py +5 -1
  16. taskcluster_taskgraph-11.2.1/setup.py +0 -52
  17. taskcluster_taskgraph-11.2.1/test/test_scripts_fetch_content.py +0 -96
  18. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/.codespell-ignore-words.txt +0 -0
  19. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/.github/workflows/codeql-analysis.yml +0 -0
  20. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/.github/workflows/pypi-publish.yml +0 -0
  21. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/.gitignore +0 -0
  22. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/.hatch_build.py +0 -0
  23. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/.readthedocs.yaml +0 -0
  24. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/.taskcluster.yml +0 -0
  25. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/.yamllint +0 -0
  26. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/CODE_OF_CONDUCT.md +0 -0
  27. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/CONTRIBUTING.rst +0 -0
  28. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/LICENSE +0 -0
  29. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/MANIFEST.in +0 -0
  30. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/Makefile +0 -0
  31. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/README.rst +0 -0
  32. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/concepts/index.rst +0 -0
  33. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/concepts/kind.rst +0 -0
  34. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/concepts/loading.rst +0 -0
  35. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/concepts/optimization.rst +0 -0
  36. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/concepts/scopes.rst +0 -0
  37. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/concepts/task-graphs.rst +0 -0
  38. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/concepts/taskcluster.rst +0 -0
  39. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/concepts/transforms.rst +0 -0
  40. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/conf.py +0 -0
  41. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/contributing.rst +0 -0
  42. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/glossary.rst +0 -0
  43. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/howto/bootstrap-taskgraph.rst +0 -0
  44. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/howto/create-actions.rst +0 -0
  45. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/howto/create-tasks.rst +0 -0
  46. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/howto/debugging.rst +0 -0
  47. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/howto/docker.rst +0 -0
  48. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/howto/index.rst +0 -0
  49. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/howto/run-locally.rst +0 -0
  50. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/howto/send-notifications.rst +0 -0
  51. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/howto/use-fetches.rst +0 -0
  52. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/index.rst +0 -0
  53. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/reference/cli.rst +0 -0
  54. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/reference/index.rst +0 -0
  55. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/reference/migrations.rst +0 -0
  56. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/reference/optimization-strategies.rst +0 -0
  57. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/reference/parameters.rst +0 -0
  58. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/reference/source/modules.rst +0 -0
  59. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/reference/source/taskgraph.actions.rst +0 -0
  60. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/reference/source/taskgraph.loader.rst +0 -0
  61. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/reference/source/taskgraph.optimize.rst +0 -0
  62. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/reference/source/taskgraph.rst +0 -0
  63. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/reference/source/taskgraph.transforms.rst +0 -0
  64. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/reference/source/taskgraph.transforms.run.rst +0 -0
  65. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/reference/source/taskgraph.util.rst +0 -0
  66. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/reference/transforms/chunking.rst +0 -0
  67. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/reference/transforms/from_deps.rst +0 -0
  68. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/reference/transforms/index.rst +0 -0
  69. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/reference/transforms/task_context.rst +0 -0
  70. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/tutorials/connecting-taskcluster.rst +0 -0
  71. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/tutorials/creating-a-task-graph.rst +0 -0
  72. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/tutorials/example-taskcluster.yml +0 -0
  73. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/tutorials/getting-started.rst +0 -0
  74. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/docs/tutorials/index.rst +0 -0
  75. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/make.bat +0 -0
  76. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/actions/__init__.py +0 -0
  77. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/actions/add_new_jobs.py +0 -0
  78. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/actions/cancel.py +0 -0
  79. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/actions/cancel_all.py +0 -0
  80. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/actions/rebuild_cached_tasks.py +0 -0
  81. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/actions/registry.py +0 -0
  82. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/actions/retrigger.py +0 -0
  83. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/actions/util.py +0 -0
  84. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/config.py +0 -0
  85. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/create.py +0 -0
  86. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/decision.py +0 -0
  87. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/docker.py +0 -0
  88. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/filter_tasks.py +0 -0
  89. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/generator.py +0 -0
  90. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/graph.py +0 -0
  91. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/loader/__init__.py +0 -0
  92. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/loader/default.py +0 -0
  93. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/loader/transform.py +0 -0
  94. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/main.py +0 -0
  95. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/morph.py +0 -0
  96. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/optimize/__init__.py +0 -0
  97. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/optimize/base.py +0 -0
  98. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/optimize/strategies.py +0 -0
  99. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/parameters.py +0 -0
  100. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/run-task/hgrc +0 -0
  101. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/run-task/robustcheckout.py +0 -0
  102. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/target_tasks.py +0 -0
  103. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/task.py +0 -0
  104. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/taskgraph.py +0 -0
  105. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/transforms/__init__.py +0 -0
  106. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/transforms/base.py +0 -0
  107. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/transforms/cached_tasks.py +0 -0
  108. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/transforms/chunking.py +0 -0
  109. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/transforms/code_review.py +0 -0
  110. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/transforms/docker_image.py +0 -0
  111. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/transforms/fetch.py +0 -0
  112. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/transforms/from_deps.py +0 -0
  113. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/transforms/notify.py +0 -0
  114. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/transforms/run/__init__.py +0 -0
  115. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/transforms/run/common.py +0 -0
  116. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/transforms/run/index_search.py +0 -0
  117. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/transforms/run/run_task.py +0 -0
  118. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/transforms/run/toolchain.py +0 -0
  119. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/transforms/task.py +0 -0
  120. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/transforms/task_context.py +0 -0
  121. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/util/__init__.py +0 -0
  122. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/util/archive.py +0 -0
  123. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/util/attributes.py +0 -0
  124. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/util/cached_tasks.py +0 -0
  125. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/util/copy.py +0 -0
  126. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/util/dependencies.py +0 -0
  127. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/util/docker.py +0 -0
  128. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/util/hash.py +0 -0
  129. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/util/keyed_by.py +0 -0
  130. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/util/parameterization.py +0 -0
  131. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/util/path.py +0 -0
  132. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/util/python_path.py +0 -0
  133. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/util/readonlydict.py +0 -0
  134. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/util/schema.py +0 -0
  135. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/util/set_name.py +0 -0
  136. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/util/shell.py +0 -0
  137. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/util/taskcluster.py +0 -0
  138. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/util/taskgraph.py +0 -0
  139. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/util/templates.py +0 -0
  140. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/util/time.py +0 -0
  141. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/util/treeherder.py +0 -0
  142. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/util/vcs.py +0 -0
  143. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/util/verify.py +0 -0
  144. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/util/workertypes.py +0 -0
  145. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/src/taskgraph/util/yaml.py +0 -0
  146. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/config.yml +0 -0
  147. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/docker/REGISTRY +0 -0
  148. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/docker/decision/HASH +0 -0
  149. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/docker/decision/README.md +0 -0
  150. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/docker/decision/VERSION +0 -0
  151. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/docker/fetch/Dockerfile +0 -0
  152. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/docker/image_builder/README.rst +0 -0
  153. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/docker/index-task/Dockerfile +0 -0
  154. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/docker/index-task/README +0 -0
  155. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/docker/index-task/insert-indexes.js +0 -0
  156. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/docker/index-task/package.json +0 -0
  157. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/docker/index-task/yarn.lock +0 -0
  158. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/docker/run-task/system-setup.sh +0 -0
  159. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/docker/skopeo/Dockerfile +0 -0
  160. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/docker/skopeo/policy.json +0 -0
  161. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/docker/skopeo/push_image.sh +0 -0
  162. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/kinds/check/kind.yml +0 -0
  163. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/kinds/codecov/kind.yml +0 -0
  164. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/kinds/doc/kind.yml +0 -0
  165. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/kinds/fetch/kind.yml +0 -0
  166. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/kinds/push-image/kind.yml +0 -0
  167. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/scripts/codecov-upload.py +0 -0
  168. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/scripts/external_tools/tooltool.py +0 -0
  169. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/self_taskgraph/transforms/push_image.py +0 -0
  170. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/self_taskgraph/transforms/test.py +0 -0
  171. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/test/params/main-repo-pull-request-untrusted.yml +0 -0
  172. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/test/params/main-repo-pull-request.yml +0 -0
  173. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/test/params/main-repo-push.yml +0 -0
  174. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/taskcluster/test/params/main-repo-release.yml +0 -0
  175. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/template/cookiecutter.json +0 -0
  176. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/template/hooks/post_gen_project.py +0 -0
  177. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/template/{{cookiecutter.project_name}}/taskcluster/config.yml +0 -0
  178. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/template/{{cookiecutter.project_name}}/taskcluster/docker/linux/Dockerfile +0 -0
  179. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/template/{{cookiecutter.project_name}}/taskcluster/kinds/docker-image/kind.yml +0 -0
  180. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/template/{{cookiecutter.project_name}}/taskcluster/kinds/hello/kind.yml +0 -0
  181. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/template/{{cookiecutter.project_name}}/taskcluster/{{cookiecutter.project_slug}}_taskgraph/transforms/hello.py +0 -0
  182. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/template/{{cookiecutter.project_name}}/taskcluster.github.yml +0 -0
  183. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/template/{{cookiecutter.project_name}}/taskcluster.hgmo.yml +0 -0
  184. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/__init__.py +0 -0
  185. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/automationrelevance.json +0 -0
  186. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/conftest.py +0 -0
  187. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/data/task_context.yml +0 -0
  188. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/data/taskcluster/config.yml +0 -0
  189. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/data/taskcluster/docker/hello-world/Dockerfile +0 -0
  190. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/data/taskcluster/docker/hello-world-tag/Dockerfile +0 -0
  191. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/data/taskcluster/docker/hello-world-tag/REGISTRY +0 -0
  192. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/data/taskcluster/docker/hello-world-tag/VERSION +0 -0
  193. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/data/taskcluster/scripts/toolchain/run.ps1 +0 -0
  194. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/data/taskcluster/scripts/toolchain/run.sh +0 -0
  195. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/data/taskcluster/test_taskgraph/transforms/foo.py +0 -0
  196. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/data/testmod/thing.py +0 -0
  197. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/fixtures/gen.py +0 -0
  198. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/fixtures/vcs.py +0 -0
  199. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/mockedopen.py +0 -0
  200. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_actions_rebuild_cached_tasks.py +0 -0
  201. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_actions_registry.py +0 -0
  202. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_config.py +0 -0
  203. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_create.py +0 -0
  204. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_decision.py +0 -0
  205. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_docker.py +0 -0
  206. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_generator.py +0 -0
  207. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_graph.py +0 -0
  208. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_main.py +0 -0
  209. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_morph.py +0 -0
  210. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_optimize.py +0 -0
  211. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_optimize_strategies.py +0 -0
  212. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_parameters.py +0 -0
  213. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_target_tasks.py +0 -0
  214. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_taskgraph.py +0 -0
  215. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_transform_chunking.py +0 -0
  216. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_transform_docker_image.py +0 -0
  217. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_transform_task_context.py +0 -0
  218. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_transforms_base.py +0 -0
  219. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_transforms_cached_tasks.py +0 -0
  220. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_transforms_fetch.py +0 -0
  221. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_transforms_from_deps.py +0 -0
  222. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_transforms_notify.py +0 -0
  223. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_transforms_run.py +0 -0
  224. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_transforms_run_run_task.py +0 -0
  225. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_transforms_run_toolchain.py +0 -0
  226. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_transforms_task.py +0 -0
  227. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_util_archive.py +0 -0
  228. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_util_attributes.py +0 -0
  229. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_util_cached_tasks.py +0 -0
  230. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_util_copy.py +0 -0
  231. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_util_dependencies.py +0 -0
  232. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_util_docker.py +0 -0
  233. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_util_parameterization.py +0 -0
  234. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_util_path.py +0 -0
  235. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_util_python_path.py +0 -0
  236. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_util_readonlydict.py +0 -0
  237. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_util_schema.py +0 -0
  238. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_util_taskcluster.py +0 -0
  239. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_util_templates.py +0 -0
  240. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_util_time.py +0 -0
  241. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_util_treeherder.py +0 -0
  242. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_util_vcs.py +0 -0
  243. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_util_verify.py +0 -0
  244. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_util_workertypes.py +0 -0
  245. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/test/test_util_yaml.py +0 -0
  246. {taskcluster_taskgraph-11.2.1 → taskcluster_taskgraph-11.2.3}/uv.lock +0 -0
@@ -7,7 +7,7 @@ ci:
7
7
  autoupdate_schedule: monthly
8
8
  repos:
9
9
  - repo: https://github.com/pre-commit/pre-commit-hooks
10
- rev: v4.6.0
10
+ rev: v5.0.0
11
11
  hooks:
12
12
  - id: trailing-whitespace
13
13
  - id: end-of-file-fixer
@@ -15,7 +15,7 @@ repos:
15
15
  exclude: template
16
16
  - id: check-added-large-files
17
17
  - repo: https://github.com/astral-sh/ruff-pre-commit
18
- rev: v0.6.3
18
+ rev: v0.6.9
19
19
  hooks:
20
20
  - id: ruff
21
21
  args: [--fix, --exit-non-zero-on-fix]
@@ -1,5 +1,23 @@
1
1
  # Change Log
2
2
 
3
+ ## [11.2.3] - 2024-10-16
4
+
5
+ ### Fixed
6
+
7
+ - A couple more regressions with the Decision image
8
+ - Cleaned up temporary `uv` lockfile owend by root
9
+ - Added another `--no-cache` flag to a `uv` command
10
+ - `run-task` now installs packages to user site dir when installing requirements with `uv`
11
+ - Fetch tasks using `static-url` will now properly rename non-archive files
12
+
13
+ ## [11.2.2] - 2024-10-15
14
+
15
+ ### Fixed
16
+
17
+ - Regression in Decision image where `taskgraph` was no longer on the $PATH
18
+ - Decision image no longer contains root owned `uv` cache
19
+ - `uv` now included in the `run-task` image
20
+
3
21
  ## [11.2.1] - 2024-10-03
4
22
 
5
23
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: taskcluster-taskgraph
3
- Version: 11.2.1
3
+ Version: 11.2.3
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
@@ -14,6 +14,7 @@ Classifier: Programming Language :: Python :: 3.9
14
14
  Classifier: Programming Language :: Python :: 3.10
15
15
  Classifier: Programming Language :: Python :: 3.11
16
16
  Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
17
18
  Classifier: Topic :: Software Development
18
19
  Requires-Python: >=3.8
19
20
  Requires-Dist: appdirs>=1.4
@@ -15,6 +15,7 @@ classifiers = [
15
15
  "Programming Language :: Python :: 3.10",
16
16
  "Programming Language :: Python :: 3.11",
17
17
  "Programming Language :: Python :: 3.12",
18
+ "Programming Language :: Python :: 3.13",
18
19
  "Topic :: Software Development",
19
20
  ]
20
21
  requires-python = ">=3.8"
@@ -2,7 +2,7 @@
2
2
  # License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  # file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
4
 
5
- __version__ = "11.2.1"
5
+ __version__ = "11.2.3"
6
6
 
7
7
  # Maximum number of dependencies a single task can have
8
8
  # https://docs.taskcluster.net/docs/reference/platform/queue/api#createTask
@@ -435,11 +435,49 @@ def extract_archive(path, dest_dir):
435
435
  log("%s extracted in %.3fs" % (path, time.time() - t0))
436
436
 
437
437
 
438
+ def should_repack_archive(orig: pathlib.Path, dest: pathlib.Path, strip_components=0, add_prefix="") -> bool:
439
+ """
440
+ Determines whether we should attempt to repack an archive based on the naming conventions used
441
+ in the original file path, the destination file path, and any modifications such as stripping
442
+ components or adding a prefix.
443
+ """
444
+
445
+ if strip_components or add_prefix:
446
+ # If strip_components or add_prefix is specified, we should always repack.
447
+ return True
448
+
449
+ if orig.suffixes == dest.suffixes:
450
+ # If all suffixes are exactly the same, then a rename will suffice.
451
+ return False
452
+
453
+ if dest.suffixes[-2:] == [".tar", ".zst"]:
454
+ # If the destination is a ".tar.zst" file then we will always try to repack it ourselves.
455
+ return True
456
+
457
+ if orig.suffix == dest.suffix:
458
+ # If the final suffix is the same, this is likely just a rename.
459
+ #
460
+ # This may be a case where multiple suffixes were detected unnecessarily due to the file name
461
+ # containing a semantic version. For example the file "python-3.8.10-amd64.exe" would be detected
462
+ # to have three suffixes [".8", ".10-amd64", ".exe"]. Changing this to "python.exe" should be a
463
+ # simple rename, rather than a repack.
464
+ #
465
+ # In this case, we will try to determine if the original path has a supported archive suffix.
466
+ # If the original path is detected to be an archive, we will try to repack, otherwise rename.
467
+ return archive_type(orig) is not None
468
+
469
+ # Otherwise, if the paths aren't the same, assume it's an archive and try to repack.
470
+ #
471
+ # It would be best to fail early if the repack fails than to fail during a test because a renamed
472
+ # file was incorrect type after all.
473
+ return True
474
+
475
+
438
476
  def repack_archive(
439
477
  orig: pathlib.Path, dest: pathlib.Path, strip_components=0, prefix=""
440
478
  ):
441
479
  assert orig != dest
442
- log("Repacking as %s" % dest)
480
+ log(f"Repacking {orig} as {dest}")
443
481
  orig_typ, ifh = open_stream(orig)
444
482
  typ = archive_type(dest)
445
483
  if not typ:
@@ -534,6 +572,9 @@ def repack_archive(
534
572
  # We only change compression here. The tar stream is unchanged.
535
573
  ctx.copy_stream(ifh, fh)
536
574
 
575
+ else:
576
+ raise Exception(f"Attempt to repack an archive of unsupported type {orig_typ}")
577
+
537
578
 
538
579
  def fetch_and_extract(url, dest_dir, extract=True, sha256=None, size=None):
539
580
  """Fetch a URL and extract it to a destination path.
@@ -773,8 +814,13 @@ def command_static_url(args):
773
814
  if gpg_sig_url:
774
815
  gpg_verify_path(dl_dest, gpg_key, gpg_signature)
775
816
 
776
- if dl_dest != dest or args.strip_components or args.add_prefix:
777
- repack_archive(dl_dest, dest, args.strip_components, args.add_prefix)
817
+ if dl_dest != dest:
818
+ if should_repack_archive(dl_dest, dest, args.strip_components, args.add_prefix):
819
+ repack_archive(dl_dest, dest, args.strip_components, args.add_prefix)
820
+ else:
821
+ log(f"Renaming {dl_dest} to {dest}")
822
+ dl_dest.rename(dest)
823
+
778
824
  except Exception:
779
825
  try:
780
826
  dl_dest.unlink()
@@ -783,7 +829,7 @@ def command_static_url(args):
783
829
 
784
830
  raise
785
831
 
786
- if dl_dest != dest:
832
+ if dl_dest != dest and dl_dest.exists():
787
833
  log("Removing %s" % dl_dest)
788
834
  dl_dest.unlink()
789
835
 
@@ -1012,9 +1012,10 @@ def install_pip_requirements(repositories):
1012
1012
 
1013
1013
  # TODO: Stop using system Python (#381)
1014
1014
  if shutil.which("uv"):
1015
- cmd = ["uv", "pip", "install", "--python", sys.executable, "--break-system-packages"]
1015
+ user_site_dir = subprocess.run([sys.executable, "-msite", "--user-site"], capture_output=True, text=True).stdout.strip()
1016
+ cmd = ["uv", "pip", "install", "--python", sys.executable, "--target", user_site_dir]
1016
1017
  else:
1017
- cmd = [sys.executable, "-mpip", "install", "--break-system-packages"]
1018
+ cmd = [sys.executable, "-mpip", "install", "--user", "--break-system-packages"]
1018
1019
 
1019
1020
  if os.environ.get("PIP_DISABLE_REQUIRE_HASHES") != "1":
1020
1021
  cmd.append("--require-hashes")
@@ -1,9 +1,6 @@
1
1
  FROM $DOCKER_IMAGE_PARENT
2
2
  LABEL maintainer="Release Engineering <release+taskgraph@mozilla.com>"
3
3
 
4
- # Keep uv version in sync with python image
5
- COPY --from=ghcr.io/astral-sh/uv:0.4.9 /uv /bin/uv
6
-
7
4
  ENV UV_PROJECT_ENVIRONMENT=/setup/taskgraph
8
5
 
9
6
  # %include src
@@ -9,11 +9,13 @@ apt-get install -y --force-yes --no-install-recommends \
9
9
  python3-pip
10
10
 
11
11
  pushd /setup/taskgraph
12
- uv export --no-dev > /setup/requirements.txt
13
- uv pip install --system --break-system-packages -r /setup/requirements.txt
12
+ uv export --no-cache --no-dev > /setup/requirements.txt
13
+ uv pip install --no-cache --system --break-system-packages -r /setup/requirements.txt
14
+ uv pip install --no-cache --system --break-system-packages --no-deps .
14
15
  popd
15
16
 
16
17
  apt-get clean
17
18
  apt-get autoclean
18
19
  rm -rf /var/lib/apt/lists/
19
20
  rm -rf /setup
21
+ rm /tmp/uv-*.lock
@@ -28,8 +28,8 @@ ENV SHELL=/bin/bash \
28
28
  HOME=/builds/worker \
29
29
  PATH=/builds/worker/.local/bin:$PATH
30
30
 
31
- # Keep uv version in sync with decision image
32
- COPY --from=ghcr.io/astral-sh/uv:0.4.9 /uv /bin/uv
31
+ # %ARG UV_VERSION
32
+ COPY --from=ghcr.io/astral-sh/uv:$UV_VERSION /uv /bin/uv
33
33
  # %ARG PYTHON_VERSIONS
34
34
  RUN uv python install $PYTHON_VERSIONS
35
35
 
@@ -16,5 +16,8 @@ ENV PATH=/builds/worker/bin:$PATH \
16
16
  SHELL=/bin/bash \
17
17
  HOME=/builds/worker
18
18
 
19
+ # %ARG UV_VERSION
20
+ COPY --from=ghcr.io/astral-sh/uv:$UV_VERSION /uv /bin/uv
21
+
19
22
  # Set a default command useful for debugging
20
23
  CMD ["/bin/bash", "--login"]
@@ -10,6 +10,10 @@ transforms:
10
10
  - taskgraph.transforms.cached_tasks:transforms
11
11
  - taskgraph.transforms.task:transforms
12
12
 
13
+ task-defaults:
14
+ args:
15
+ UV_VERSION: 0.4.9
16
+
13
17
  # make a task for each docker-image we might want. For the moment, since we
14
18
  # write artifacts for each, these are whitelisted, but ideally that will change
15
19
  # (to use subdirectory clones of the proper directory), at which point we can
@@ -26,7 +30,7 @@ tasks:
26
30
  python:
27
31
  symbol: I(py)
28
32
  args:
29
- PYTHON_VERSIONS: "3.12 3.11 3.10 3.9 3.8"
33
+ PYTHON_VERSIONS: "3.13 3.12 3.11 3.10 3.9 3.8"
30
34
  run-task:
31
35
  symbol: I(rt)
32
36
  skopeo:
@@ -40,7 +40,7 @@ tasks:
40
40
  description: "Run `unit tests` to validate the latest changes"
41
41
  attributes:
42
42
  artifact_prefix: public
43
- python-versions: ["3.12", "3.11", "3.10", "3.9", "3.8"]
43
+ python-versions: ["3.13", "3.12", "3.11", "3.10", "3.9", "3.8"]
44
44
  run:
45
45
  command: >-
46
46
  uv run coverage run --data-file $MOZ_ARTIFACT_DIR/coverage --context=$PYTHON_VERSION -m pytest -vv
@@ -0,0 +1,178 @@
1
+ import os
2
+ import pathlib
3
+ import urllib.request
4
+ from importlib.machinery import SourceFileLoader
5
+ from importlib.util import module_from_spec, spec_from_loader
6
+ from unittest.mock import MagicMock
7
+
8
+ import pytest
9
+
10
+ import taskgraph
11
+
12
+
13
+ @pytest.fixture(scope="module")
14
+ def fetch_content_mod():
15
+ spec = spec_from_loader(
16
+ "fetch-content",
17
+ SourceFileLoader(
18
+ "fetch-content",
19
+ os.path.join(
20
+ os.path.dirname(taskgraph.__file__), "run-task", "fetch-content"
21
+ ),
22
+ ),
23
+ )
24
+ assert spec
25
+ assert spec.loader
26
+ mod = module_from_spec(spec)
27
+ spec.loader.exec_module(mod)
28
+ return mod
29
+
30
+
31
+ @pytest.mark.parametrize(
32
+ "url,sha256,size,headers,raises",
33
+ (
34
+ pytest.param(
35
+ "https://example.com",
36
+ "c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2",
37
+ 6,
38
+ ["User-Agent: foobar"],
39
+ False,
40
+ id="valid",
41
+ ),
42
+ pytest.param(
43
+ "https://example.com",
44
+ "abcdef",
45
+ 6,
46
+ ["User-Agent: foobar"],
47
+ True,
48
+ id="invalid sha256",
49
+ ),
50
+ pytest.param(
51
+ "https://example.com",
52
+ "c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2",
53
+ 123,
54
+ ["User-Agent: foobar"],
55
+ True,
56
+ id="invalid size",
57
+ ),
58
+ ),
59
+ )
60
+ def test_stream_download(
61
+ monkeypatch, fetch_content_mod, url, sha256, size, headers, raises
62
+ ):
63
+ def mock_urlopen(req, timeout=None, *, cafile=None):
64
+ assert req._full_url == url
65
+ assert timeout is not None
66
+ if headers:
67
+ assert len(req.headers) == len(headers)
68
+ for header in headers:
69
+ k, v = header.split(":")
70
+ k = k.lower().capitalize().strip()
71
+ assert k in req.headers
72
+ assert req.headers[k] == v.strip()
73
+
74
+ # create a mock context manager
75
+ cm = MagicMock()
76
+ cm.getcode.return_value = 200
77
+
78
+ def getheader(field):
79
+ if field.lower() == "content-length":
80
+ return size
81
+
82
+ # simulates chunking
83
+ cm.getheader = getheader
84
+ cm.read.side_effect = [b"foo", b"bar", None]
85
+ cm.__enter__.return_value = cm
86
+ return cm
87
+
88
+ monkeypatch.setattr(urllib.request, "urlopen", mock_urlopen)
89
+
90
+ result = b""
91
+ try:
92
+ for chunk in fetch_content_mod.stream_download(url, sha256, size, headers):
93
+ result += chunk
94
+ assert result == b"foobar"
95
+ except fetch_content_mod.IntegrityError:
96
+ if not raises:
97
+ raise
98
+
99
+
100
+ @pytest.mark.parametrize(
101
+ "expected,orig,dest,strip_components,add_prefix",
102
+ [
103
+ # Archives to repack
104
+ (True, pathlib.Path("archive"), pathlib.Path("archive.tar.zst"), 0, ""),
105
+ (True, pathlib.Path("archive.tar"), pathlib.Path("archive.tar.zst"), 0, ""),
106
+ (True, pathlib.Path("archive.tgz"), pathlib.Path("archive.tar.zst"), 0, ""),
107
+ (True, pathlib.Path("archive.zip"), pathlib.Path("archive.tar.zst"), 0, ""),
108
+ (True, pathlib.Path("archive.tar.xz"), pathlib.Path("archive.tar.zst"), 0, ""),
109
+ (True, pathlib.Path("archive.zst"), pathlib.Path("archive.tar.zst"), 0, ""),
110
+ # Path is exactly the same
111
+ (False, pathlib.Path("archive"), pathlib.Path("archive"), 0, ""),
112
+ (False, pathlib.Path("file.txt"), pathlib.Path("file.txt"), 0, ""),
113
+ (False, pathlib.Path("archive.tar"), pathlib.Path("archive.tar"), 0, ""),
114
+ (False, pathlib.Path("archive.tgz"), pathlib.Path("archive.tgz"), 0, ""),
115
+ (False, pathlib.Path("archive.zip"), pathlib.Path("archive.zip"), 0, ""),
116
+ (
117
+ False,
118
+ pathlib.Path("archive.tar.zst"),
119
+ pathlib.Path("archive.tar.zst"),
120
+ 0,
121
+ "",
122
+ ),
123
+ (
124
+ False,
125
+ pathlib.Path("archive-before.tar.zst"),
126
+ pathlib.Path("archive-after.tar.zst"),
127
+ 0,
128
+ "",
129
+ ),
130
+ (
131
+ False,
132
+ pathlib.Path("before.foo.bar.baz"),
133
+ pathlib.Path("after.foo.bar.baz"),
134
+ 0,
135
+ "",
136
+ ),
137
+ # Non-default values for strip_components and add_prefix parameters
138
+ (True, pathlib.Path("archive.tar.zst"), pathlib.Path("archive.tar.zst"), 1, ""),
139
+ (
140
+ True,
141
+ pathlib.Path("archive.tar.zst"),
142
+ pathlib.Path("archive.tar.zst"),
143
+ 0,
144
+ "prefix",
145
+ ),
146
+ (
147
+ True,
148
+ pathlib.Path("archive.tar.zst"),
149
+ pathlib.Path("archive.tar.zst"),
150
+ 1,
151
+ "prefix",
152
+ ),
153
+ # Real edge cases that should not be repacks
154
+ (
155
+ False,
156
+ pathlib.Path("python-3.8.10-amd64.exe"),
157
+ pathlib.Path("python.exe"),
158
+ 0,
159
+ "",
160
+ ),
161
+ (
162
+ False,
163
+ pathlib.Path("9ee26e91-9b52-44ba-8d30-c0230dd587b2.bin"),
164
+ pathlib.Path("model.esen.intgemm.alphas.bin"),
165
+ 0,
166
+ "",
167
+ ),
168
+ ],
169
+ )
170
+ def test_should_repack_archive(
171
+ fetch_content_mod, orig, dest, expected, strip_components, add_prefix
172
+ ):
173
+ assert (
174
+ fetch_content_mod.should_repack_archive(
175
+ orig, dest, strip_components, add_prefix
176
+ )
177
+ == expected
178
+ ), f"Failed for orig: {orig}, dest: {dest}, strip_components: {strip_components}, add_prefix: {add_prefix}, expected {expected} but received {not expected}"
@@ -1,5 +1,6 @@
1
1
  import io
2
2
  import os
3
+ import site
3
4
  import stat
4
5
  import subprocess
5
6
  import sys
@@ -85,6 +86,7 @@ def test_install_pip_requirements(
85
86
  sys.executable,
86
87
  "-mpip",
87
88
  "install",
89
+ "--user",
88
90
  "--break-system-packages",
89
91
  "--require-hashes",
90
92
  "-r",
@@ -105,6 +107,7 @@ def test_install_pip_requirements(
105
107
  sys.executable,
106
108
  "-mpip",
107
109
  "install",
110
+ "--user",
108
111
  "--break-system-packages",
109
112
  "--require-hashes",
110
113
  "-r",
@@ -137,7 +140,8 @@ def test_install_pip_requirements_with_uv(
137
140
  "install",
138
141
  "--python",
139
142
  sys.executable,
140
- "--break-system-packages",
143
+ "--target",
144
+ site.getusersitepackages(),
141
145
  "--require-hashes",
142
146
  "-r",
143
147
  str(req),
@@ -1,52 +0,0 @@
1
- import os
2
- from distutils.util import convert_path
3
-
4
- from setuptools import find_packages, setup
5
-
6
- project_dir = os.path.abspath(os.path.dirname(__file__))
7
-
8
- namespace = {}
9
- version_file = convert_path("src/taskgraph/__init__.py")
10
- with open(version_file) as fh:
11
- exec(fh.read(), namespace)
12
-
13
- with open(os.path.join(project_dir, "requirements/base.in")) as fp:
14
- requirements = fp.read().splitlines()
15
-
16
- with open(os.path.join(project_dir, "README.rst")) as fh:
17
- long_description = fh.read()
18
-
19
- setup(
20
- name="taskcluster-taskgraph",
21
- version=namespace["__version__"],
22
- description="Build taskcluster taskgraphs",
23
- long_description=long_description,
24
- url="https://github.com/taskcluster/taskgraph",
25
- packages=find_packages("src"),
26
- package_dir={"": "src"},
27
- install_requires=requirements,
28
- extras_require={
29
- "load-image": ["zstandard"],
30
- },
31
- classifiers=[
32
- "Development Status :: 5 - Production/Stable",
33
- "Environment :: Console",
34
- "License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)",
35
- "Programming Language :: Python :: 3.8",
36
- "Programming Language :: Python :: 3.9",
37
- "Programming Language :: Python :: 3.10",
38
- "Programming Language :: Python :: 3.11",
39
- "Programming Language :: Python :: 3.12",
40
- "Topic :: Software Development",
41
- ],
42
- entry_points={"console_scripts": ["taskgraph = taskgraph.main:main"]},
43
- package_data={
44
- "taskgraph": [
45
- "run-task/run-task",
46
- "run-task/fetch-content",
47
- "run-task/hgrc",
48
- "run-task/robustcheckout.py",
49
- ],
50
- "taskgraph.test": ["automationrelevance.json"],
51
- },
52
- )
@@ -1,96 +0,0 @@
1
- import os
2
- import urllib.request
3
- from importlib.machinery import SourceFileLoader
4
- from importlib.util import module_from_spec, spec_from_loader
5
- from unittest.mock import MagicMock
6
-
7
- import pytest
8
-
9
- import taskgraph
10
-
11
-
12
- @pytest.fixture(scope="module")
13
- def fetch_content_mod():
14
- spec = spec_from_loader(
15
- "fetch-content",
16
- SourceFileLoader(
17
- "fetch-content",
18
- os.path.join(
19
- os.path.dirname(taskgraph.__file__), "run-task", "fetch-content"
20
- ),
21
- ),
22
- )
23
- assert spec
24
- assert spec.loader
25
- mod = module_from_spec(spec)
26
- spec.loader.exec_module(mod)
27
- return mod
28
-
29
-
30
- @pytest.mark.parametrize(
31
- "url,sha256,size,headers,raises",
32
- (
33
- pytest.param(
34
- "https://example.com",
35
- "c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2",
36
- 6,
37
- ["User-Agent: foobar"],
38
- False,
39
- id="valid",
40
- ),
41
- pytest.param(
42
- "https://example.com",
43
- "abcdef",
44
- 6,
45
- ["User-Agent: foobar"],
46
- True,
47
- id="invalid sha256",
48
- ),
49
- pytest.param(
50
- "https://example.com",
51
- "c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2",
52
- 123,
53
- ["User-Agent: foobar"],
54
- True,
55
- id="invalid size",
56
- ),
57
- ),
58
- )
59
- def test_stream_download(
60
- monkeypatch, fetch_content_mod, url, sha256, size, headers, raises
61
- ):
62
- def mock_urlopen(req, timeout=None, *, cafile=None):
63
- assert req._full_url == url
64
- assert timeout is not None
65
- if headers:
66
- assert len(req.headers) == len(headers)
67
- for header in headers:
68
- k, v = header.split(":")
69
- k = k.lower().capitalize().strip()
70
- assert k in req.headers
71
- assert req.headers[k] == v.strip()
72
-
73
- # create a mock context manager
74
- cm = MagicMock()
75
- cm.getcode.return_value = 200
76
-
77
- def getheader(field):
78
- if field.lower() == "content-length":
79
- return size
80
-
81
- # simulates chunking
82
- cm.getheader = getheader
83
- cm.read.side_effect = [b"foo", b"bar", None]
84
- cm.__enter__.return_value = cm
85
- return cm
86
-
87
- monkeypatch.setattr(urllib.request, "urlopen", mock_urlopen)
88
-
89
- result = b""
90
- try:
91
- for chunk in fetch_content_mod.stream_download(url, sha256, size, headers):
92
- result += chunk
93
- assert result == b"foobar"
94
- except fetch_content_mod.IntegrityError:
95
- if not raises:
96
- raise