taskcluster-taskgraph 21.0.0__tar.gz → 23.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.
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/.pre-commit-config.yaml +3 -4
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/.taskcluster.yml +0 -1
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/CHANGELOG.md +27 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/PKG-INFO +1 -1
- taskcluster_taskgraph-23.0.0/docs/howto/define-schemas.rst +156 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/howto/index.rst +1 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/migrations.rst +15 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/pyproject.toml +1 -2
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/actions/registry.py +16 -1
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/config.py +3 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/decision.py +1 -1
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/parameters.py +95 -50
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/run-task/fetch-content +4 -3
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/run-task/run-task +1 -14
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/taskgraph.py +0 -3
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/from_deps.py +40 -40
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/task.py +0 -5
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/schema.py +81 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/vcs.py +36 -4
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/self_taskgraph/custom_parameters.py +9 -6
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/conftest.py +15 -2
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_actions_registry.py +73 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_decision.py +3 -1
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_main.py +27 -1
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_parameters.py +8 -13
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_scripts_fetch_content.py +80 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_scripts_run_task.py +0 -46
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_taskgraph.py +2 -3
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_schema.py +51 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_vcs.py +11 -9
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/uv.lock +1 -1
- taskcluster_taskgraph-21.0.0/taskcluster/scripts/external_tools/tooltool.py +0 -1502
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/.codespell-ignore-words.txt +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/.github/CODEOWNERS +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/.github/dependabot.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/.github/workflows/codeql-analysis.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/.github/workflows/pre-commit-autoupdate.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/.github/workflows/pre-commit.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/.github/workflows/pypi-publish.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/.gitignore +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/.readthedocs.yaml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/.yamllint +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/CODE_OF_CONDUCT.md +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/CONTRIBUTING.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/LICENSE +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/Makefile +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/README.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/concepts/index.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/concepts/kind.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/concepts/loading.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/concepts/optimization.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/concepts/overview.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/concepts/scopes.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/concepts/task-graphs.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/concepts/transforms.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/conf.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/contributing.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/glossary.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/howto/bootstrap-taskgraph.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/howto/create-actions.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/howto/create-tasks.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/howto/debugging.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/howto/docker.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/howto/load-task-locally.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/howto/resolve-keyed-by.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/howto/run-locally.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/howto/send-notifications.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/howto/use-fetches.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/index.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/cli.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/index.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/optimization-strategies.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/parameters.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/source/modules.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/source/taskgraph.actions.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/source/taskgraph.loader.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/source/taskgraph.optimize.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/source/taskgraph.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/source/taskgraph.transforms.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/source/taskgraph.transforms.run.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/source/taskgraph.util.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/transforms/chunking.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/transforms/from_deps.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/transforms/index.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/transforms/matrix.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/transforms/task_context.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/tutorials/connecting-taskcluster.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/tutorials/creating-a-task-graph.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/tutorials/example-taskcluster.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/tutorials/getting-started.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/docs/tutorials/index.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/make.bat +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/packages/pytest-taskgraph/README.md +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/packages/pytest-taskgraph/pyproject.toml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/packages/pytest-taskgraph/src/pytest_taskgraph/__init__.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/packages/pytest-taskgraph/src/pytest_taskgraph/fixtures/gen.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/packages/pytest-taskgraph/src/pytest_taskgraph/fixtures/vcs.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/packages/sphinx-taskgraph/README.md +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/packages/sphinx-taskgraph/pyproject.toml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/packages/sphinx-taskgraph/src/sphinx_taskgraph/__init__.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/packages/sphinx-taskgraph/src/sphinx_taskgraph/autoschema.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/__init__.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/actions/__init__.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/actions/add_new_jobs.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/actions/cancel.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/actions/cancel_all.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/actions/rebuild_cached_tasks.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/actions/retrigger.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/actions/util.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/create.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/docker.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/filter_tasks.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/generator.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/graph.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/loader/__init__.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/loader/default.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/loader/transform.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/main.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/morph.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/optimize/__init__.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/optimize/base.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/optimize/strategies.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/run-task/hgrc +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/run-task/robustcheckout.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/target_tasks.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/task.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/__init__.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/base.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/cached_tasks.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/chunking.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/code_review.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/docker_image.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/fetch.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/matrix.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/notify.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/run/__init__.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/run/common.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/run/index_search.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/run/run_task.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/run/toolchain.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/task_context.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/__init__.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/archive.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/attributes.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/cached_tasks.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/caches.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/copy.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/dependencies.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/docker.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/hash.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/json.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/keyed_by.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/parameterization.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/path.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/python_path.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/readonlydict.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/set_name.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/shell.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/taskcluster.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/taskgraph.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/templates.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/time.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/treeherder.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/verify.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/workertypes.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/yaml.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/config.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/REGISTRY +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/decision/Dockerfile +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/decision/HASH +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/decision/README.md +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/decision/VERSION +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/decision/system-setup.sh +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/fetch/Dockerfile +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/image_builder/README.rst +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/index-task/Dockerfile +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/index-task/README +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/index-task/insert-indexes.js +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/index-task/package.json +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/index-task/yarn.lock +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/python/Dockerfile +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/run-task/Dockerfile +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/run-task/system-setup.sh +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/skopeo/Dockerfile +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/skopeo/policy.json +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/skopeo/push_image.sh +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/kinds/check/kind.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/kinds/codecov/kind.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/kinds/complete/kind.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/kinds/doc/kind.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/kinds/docker-image/kind.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/kinds/fetch/kind.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/kinds/push-image/kind.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/kinds/test/kind.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/kinds/test/linux.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/kinds/test/windows.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/scripts/codecov-upload.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/self_taskgraph/__init__.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/self_taskgraph/custom_target_tasks.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/self_taskgraph/transforms/add_pr_route.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/self_taskgraph/transforms/push_image.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/test/params/main-repo-pull-request-untrusted.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/test/params/main-repo-pull-request.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/test/params/main-repo-push.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/test/params/main-repo-release-pytest-taskgraph.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/test/params/main-repo-release-taskcluster-taskgraph.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/template/cookiecutter.json +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/template/hooks/post_gen_project.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/template/{{cookiecutter.project_name}}/taskcluster/config.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/template/{{cookiecutter.project_name}}/taskcluster/docker/linux/Dockerfile +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/template/{{cookiecutter.project_name}}/taskcluster/kinds/docker-image/kind.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/template/{{cookiecutter.project_name}}/taskcluster/kinds/hello/kind.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/template/{{cookiecutter.project_name}}/taskcluster/{{cookiecutter.project_slug}}_taskgraph/transforms/hello.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/template/{{cookiecutter.project_name}}/taskcluster.github.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/__init__.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/automationrelevance.json +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/data/task_context.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/data/taskcluster/config.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/data/taskcluster/docker/hello-world/Dockerfile +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/data/taskcluster/docker/hello-world-tag/Dockerfile +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/data/taskcluster/docker/hello-world-tag/REGISTRY +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/data/taskcluster/docker/hello-world-tag/VERSION +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/data/taskcluster/kinds/docker-image/kind.yml +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/data/taskcluster/scripts/toolchain/run.ps1 +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/data/taskcluster/scripts/toolchain/run.sh +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/data/taskcluster/test_taskgraph/transforms/foo.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/data/testmod/thing.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/mockedopen.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_actions_rebuild_cached_tasks.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_config.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_create.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_docker.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_generator.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_graph.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_morph.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_optimize.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_optimize_strategies.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_target_tasks.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_transform_chunking.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_transform_docker_image.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_transform_task_context.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_transforms_base.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_transforms_cached_tasks.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_transforms_fetch.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_transforms_from_deps.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_transforms_matrix.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_transforms_notify.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_transforms_run.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_transforms_run_run_task.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_transforms_run_toolchain.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_transforms_task.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_archive.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_attributes.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_cached_tasks.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_copy.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_dependencies.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_docker.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_json.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_keyed_by.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_parameterization.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_path.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_python_path.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_readonlydict.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_taskcluster.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_templates.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_time.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_treeherder.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_verify.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_workertypes.py +0 -0
- {taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_yaml.py +0 -0
|
@@ -13,13 +13,13 @@ repos:
|
|
|
13
13
|
exclude: template
|
|
14
14
|
- id: check-added-large-files
|
|
15
15
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
16
|
-
rev: v0.15.
|
|
16
|
+
rev: v0.15.12
|
|
17
17
|
hooks:
|
|
18
18
|
- id: ruff
|
|
19
19
|
args: [--fix, --exit-non-zero-on-fix]
|
|
20
20
|
- id: ruff-format
|
|
21
21
|
- repo: https://github.com/astral-sh/uv-pre-commit
|
|
22
|
-
rev: 0.11.
|
|
22
|
+
rev: 0.11.8
|
|
23
23
|
hooks:
|
|
24
24
|
- id: uv-lock
|
|
25
25
|
- repo: https://github.com/adrienverge/yamllint.git
|
|
@@ -48,6 +48,5 @@ exclude: |
|
|
|
48
48
|
(?x)^(
|
|
49
49
|
src/taskgraph/run-task/fetch-content |
|
|
50
50
|
src/taskgraph/run-task/robustcheckout.py |
|
|
51
|
-
src/taskgraph/run-task/run-task
|
|
52
|
-
taskcluster/scripts/external_tools
|
|
51
|
+
src/taskgraph/run-task/run-task
|
|
53
52
|
)
|
|
@@ -226,7 +226,6 @@ tasks:
|
|
|
226
226
|
- $if: 'isPullRequest'
|
|
227
227
|
then:
|
|
228
228
|
TASKGRAPH_PULL_REQUEST_NUMBER: '${event.pull_request.number}'
|
|
229
|
-
TASKGRAPH_EXTRA_REFS: {$json: ["refs/notes/decision-parameters"]}
|
|
230
229
|
- $if: 'tasks_for == "action" || tasks_for == "pr-action"'
|
|
231
230
|
then:
|
|
232
231
|
ACTION_TASK_GROUP_ID: '${action.taskGroupId}' # taskGroupId of the target task
|
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## [23.0.0] - 2026-05-04
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Support for defining schemas as dicts (in addition to the class-based approach)
|
|
8
|
+
- New `disabled_actions` graph configuration to prevent specific actions from being generated
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- BREAKING CHANGE: Converted parameter schema from voluptuous to msgspec
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- `taskgraph full -J --tasks <regex>` now displays full dependencies instead of a filtered subset
|
|
17
|
+
- `fetch-content` now percent-encodes artifact names, fixing downloads of artifacts containing spaces or other special characters
|
|
18
|
+
|
|
19
|
+
## [22.0.0] - 2026-04-16
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- Decision task now fetches `refs/notes/decision-parameters` itself
|
|
24
|
+
|
|
25
|
+
### Removed
|
|
26
|
+
|
|
27
|
+
- BREAKING CHANGE: Removed ability for `run-task` to fetch arbitrary extra refs
|
|
28
|
+
- BREAKING CHANGE: Removed docker-worker feature: relengapi-proxy
|
|
29
|
+
|
|
3
30
|
## [21.0.0] - 2026-04-13
|
|
4
31
|
|
|
5
32
|
### Added
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
Define Schemas
|
|
2
|
+
==============
|
|
3
|
+
|
|
4
|
+
:doc:`Transforms </concepts/transforms>` can define schemas to validate task data at each step of the
|
|
5
|
+
pipeline. Taskgraph uses `msgspec`_ under the hood, and provides a
|
|
6
|
+
:class:`~taskgraph.util.schema.Schema` base class that integrates with
|
|
7
|
+
:meth:`TransformSequence.add_validate() <taskgraph.transforms.base.TransformSequence.add_validate>`.
|
|
8
|
+
|
|
9
|
+
There are two ways to define a schema: the **class based** approach and the
|
|
10
|
+
**dict based** approach. Both produce equivalent results; which one you prefer
|
|
11
|
+
is a matter of style.
|
|
12
|
+
|
|
13
|
+
.. _msgspec: https://jcristharif.com/msgspec/
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
Class Based Schemas
|
|
17
|
+
-------------------
|
|
18
|
+
|
|
19
|
+
Subclass :class:`~taskgraph.util.schema.Schema` and declare fields as class
|
|
20
|
+
attributes with type annotations:
|
|
21
|
+
|
|
22
|
+
.. code-block:: python
|
|
23
|
+
|
|
24
|
+
from typing import Optional
|
|
25
|
+
from taskgraph.transforms.base import TransformSequence
|
|
26
|
+
from taskgraph.util.schema import Schema
|
|
27
|
+
|
|
28
|
+
class MySubConfig(Schema):
|
|
29
|
+
total_num: int
|
|
30
|
+
fields: list[str] = []
|
|
31
|
+
|
|
32
|
+
class MySchema(Schema, forbid_unknown_fields=False):
|
|
33
|
+
config: Optional[MySubConfig] = None
|
|
34
|
+
|
|
35
|
+
transforms = TransformSequence()
|
|
36
|
+
transforms.add_validate(MySchema)
|
|
37
|
+
|
|
38
|
+
A few things to note:
|
|
39
|
+
|
|
40
|
+
- Field names use ``snake_case`` in Python but are **automatically renamed to
|
|
41
|
+
``kebab-case``** in YAML. So ``total_num`` in Python matches
|
|
42
|
+
``total-num`` in YAML.
|
|
43
|
+
- ``Optional[T]`` fields default to ``None`` unless you supply an explicit
|
|
44
|
+
default.
|
|
45
|
+
- Fields without a default are **required**.
|
|
46
|
+
- ``forbid_unknown_fields=True`` (the default) causes validation to fail if the
|
|
47
|
+
task data contains keys that are not declared in the schema. Set it to
|
|
48
|
+
``False`` on outer schemas so that fields belonging to later transforms are
|
|
49
|
+
not rejected.
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
Dict Based Schemas
|
|
53
|
+
------------------
|
|
54
|
+
|
|
55
|
+
Call :meth:`Schema.from_dict() <taskgraph.util.schema.Schema.from_dict>` with a
|
|
56
|
+
dictionary mapping field names to ``type`` or ``(type, default)`` tuples:
|
|
57
|
+
|
|
58
|
+
.. code-block:: python
|
|
59
|
+
|
|
60
|
+
from typing import Optional, Union
|
|
61
|
+
from taskgraph.transforms.base import TransformSequence
|
|
62
|
+
from taskgraph.util.schema import Schema
|
|
63
|
+
|
|
64
|
+
MySchema = Schema.from_dict(
|
|
65
|
+
{
|
|
66
|
+
"config": Schema.from_dict(
|
|
67
|
+
{
|
|
68
|
+
"total-num": int,
|
|
69
|
+
"fields": list[str] = []
|
|
70
|
+
},
|
|
71
|
+
optional=True,
|
|
72
|
+
),
|
|
73
|
+
},
|
|
74
|
+
forbid_unknown_fields=False,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
transforms = TransformSequence()
|
|
78
|
+
transforms.add_validate(MySchema)
|
|
79
|
+
|
|
80
|
+
This example is equivalent to the first example. One advantage with the dict based approach
|
|
81
|
+
is that you can write keys in **kebab-case** directly.
|
|
82
|
+
|
|
83
|
+
Field specifications follow these rules:
|
|
84
|
+
|
|
85
|
+
- A bare type (e.g. ``str``) means the field is required.
|
|
86
|
+
- ``Optional[T]`` means the field is optional and defaults to ``None``.
|
|
87
|
+
- A ``(type, default)`` tuple supplies an explicit default, e.g.
|
|
88
|
+
``(list[str], [])``.
|
|
89
|
+
|
|
90
|
+
Keyword arguments to ``from_dict`` are forwarded to ``msgspec.defstruct``.
|
|
91
|
+
The most commonly used ones are ``name`` (for better error messages) and
|
|
92
|
+
``forbid_unknown_fields``.
|
|
93
|
+
|
|
94
|
+
.. note::
|
|
95
|
+
``Schema.from_dict`` does **not** apply ``rename="kebab"`` automatically,
|
|
96
|
+
because you can express the kebab-case names directly in the dict keys.
|
|
97
|
+
Underscores in dict keys stay as underscores and dashes become valid
|
|
98
|
+
kebab-case field names.
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
Nesting Schemas
|
|
102
|
+
---------------
|
|
103
|
+
|
|
104
|
+
Both approaches support nesting:
|
|
105
|
+
|
|
106
|
+
.. code-block:: python
|
|
107
|
+
|
|
108
|
+
# Class-based nesting
|
|
109
|
+
class Inner(Schema):
|
|
110
|
+
value: str
|
|
111
|
+
|
|
112
|
+
class Outer(Schema, forbid_unknown_fields=False, kw_only=True):
|
|
113
|
+
inner: Optional[Inner] = None
|
|
114
|
+
|
|
115
|
+
# Dict-based nesting
|
|
116
|
+
Outer = Schema.from_dict(
|
|
117
|
+
{
|
|
118
|
+
"inner": Schema.from_dict({"value": str}, optional=True),
|
|
119
|
+
},
|
|
120
|
+
forbid_unknown_fields=False,
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
Pass ``optional=True`` to ``from_dict`` to make the whole nested schema
|
|
124
|
+
optional. This is necessary as function calls are not allowed in type
|
|
125
|
+
annotations, so ``Optional[Schema.from_dict(...)]`` is not valid Python.
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
Mutually Exclusive Fields
|
|
129
|
+
-------------------------
|
|
130
|
+
|
|
131
|
+
Use the ``exclusive`` keyword to declare groups of fields where at most one
|
|
132
|
+
may be set at a time:
|
|
133
|
+
|
|
134
|
+
.. code-block:: python
|
|
135
|
+
|
|
136
|
+
# Class-based
|
|
137
|
+
class MySchema(Schema, exclusive=[["field_a", "field_b"]]):
|
|
138
|
+
field_a: Optional[str] = None
|
|
139
|
+
field_b: Optional[str] = None
|
|
140
|
+
|
|
141
|
+
# Dict-based
|
|
142
|
+
MySchema = Schema.from_dict(
|
|
143
|
+
{
|
|
144
|
+
"field-a": Optional[str],
|
|
145
|
+
"field-b": Optional[str],
|
|
146
|
+
},
|
|
147
|
+
exclusive=[["field_a", "field_b"]],
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
``exclusive`` takes a list of groups, where each group is a list of field
|
|
151
|
+
names (Python ``snake_case``). A validation error is raised if more than one
|
|
152
|
+
field in a group is set.
|
|
153
|
+
|
|
154
|
+
.. note::
|
|
155
|
+
When using ``exclusive`` with the dict-based approach, refer to fields by
|
|
156
|
+
their Python attribute names (``snake_case``), not their YAML keys.
|
|
@@ -3,6 +3,21 @@ Migration Guide
|
|
|
3
3
|
|
|
4
4
|
This page can help when migrating Taskgraph across major versions.
|
|
5
5
|
|
|
6
|
+
22.x -> 23.x
|
|
7
|
+
------------
|
|
8
|
+
|
|
9
|
+
* :func:`taskgraph.parameters.extend_parameters_schema` now requires a msgspec
|
|
10
|
+
``Schema`` subclass instead of a voluptuous schema dict. Convert any custom
|
|
11
|
+
parameter schemas to msgspec.
|
|
12
|
+
|
|
13
|
+
21.x -> 22.x
|
|
14
|
+
------------
|
|
15
|
+
|
|
16
|
+
* If you have tasks using `docker-worker`'s `relengapi-proxy` feature, it is no
|
|
17
|
+
longer supported. Remove all references to it in your task definitions.
|
|
18
|
+
* Remove references to `<REPO>_EXTRA_REFS` in all `run-task` based tasks. These
|
|
19
|
+
refs must now be fetched as part of the task payload.
|
|
20
|
+
|
|
6
21
|
20.x -> 21.x
|
|
7
22
|
------------
|
|
8
23
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
### Project
|
|
2
2
|
[project]
|
|
3
3
|
name = "taskcluster-taskgraph"
|
|
4
|
-
version = "
|
|
4
|
+
version = "23.0.0"
|
|
5
5
|
description = "Build taskcluster taskgraphs"
|
|
6
6
|
readme = "README.rst"
|
|
7
7
|
authors = [
|
|
@@ -94,7 +94,6 @@ source = ["src/taskgraph/", "src/taskgraph/run-task/", "packages", "test"]
|
|
|
94
94
|
### Lint and Format
|
|
95
95
|
[tool.ruff]
|
|
96
96
|
extend-exclude = [
|
|
97
|
-
"taskcluster/scripts/external_tools",
|
|
98
97
|
"src/taskgraph/run-task/robustcheckout.py"
|
|
99
98
|
]
|
|
100
99
|
line-length = 88
|
{taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/actions/registry.py
RENAMED
|
@@ -273,12 +273,27 @@ def render_actions_json(parameters, graph_config, decision_task_id):
|
|
|
273
273
|
artifact.
|
|
274
274
|
"""
|
|
275
275
|
assert isinstance(parameters, Parameters), "requires instance of Parameters"
|
|
276
|
+
|
|
277
|
+
all_actions = _get_actions(graph_config)
|
|
278
|
+
disabled = set(graph_config["taskgraph"].get("disabled-actions") or [])
|
|
279
|
+
known_cb_names = {action.cb_name for action in all_actions}
|
|
280
|
+
unknown = disabled - known_cb_names
|
|
281
|
+
if unknown:
|
|
282
|
+
raise ValueError(
|
|
283
|
+
"Unknown action(s) in `taskgraph.disabled-actions`: "
|
|
284
|
+
f"{sorted(unknown)}. Known actions: {sorted(known_cb_names)}"
|
|
285
|
+
)
|
|
286
|
+
|
|
276
287
|
actions = []
|
|
277
|
-
for action in sorted(
|
|
288
|
+
for action in sorted(all_actions, key=lambda action: action.order):
|
|
289
|
+
if action.cb_name in disabled:
|
|
290
|
+
continue
|
|
291
|
+
|
|
278
292
|
action = action.action_builder(parameters, graph_config, decision_task_id)
|
|
279
293
|
if action:
|
|
280
294
|
assert is_json(action), "action must be a JSON compatible object"
|
|
281
295
|
actions.append(action)
|
|
296
|
+
|
|
282
297
|
return {
|
|
283
298
|
"version": 1,
|
|
284
299
|
"variables": {},
|
|
@@ -57,6 +57,9 @@ class TaskgraphConfig(Schema):
|
|
|
57
57
|
index_path_regexes: Optional[list[str]] = None
|
|
58
58
|
# Configuration related to the 'run' transforms.
|
|
59
59
|
run: Optional[RunConfig] = None
|
|
60
|
+
# List of action `cb_name`s to omit from `actions.json`,
|
|
61
|
+
# e.g. `["retrigger", "retrigger-disabled", "rerun"]`.
|
|
62
|
+
disabled_actions: Optional[list[str]] = None
|
|
60
63
|
|
|
61
64
|
def __post_init__(self):
|
|
62
65
|
# Validate repositories has at least 1 entry (was All(..., Length(min=1)))
|
|
@@ -267,7 +267,7 @@ def get_decision_parameters(graph_config, options):
|
|
|
267
267
|
# load extra parameters from vcs note if able
|
|
268
268
|
note_ref = "refs/notes/decision-parameters"
|
|
269
269
|
if options.get("allow_parameter_override") and (
|
|
270
|
-
note_params := repo.get_note(note_ref)
|
|
270
|
+
note_params := repo.get_note(note_ref, parameters["head_repository"])
|
|
271
271
|
):
|
|
272
272
|
try:
|
|
273
273
|
note_params = json.loads(note_params)
|
|
@@ -10,16 +10,17 @@ from datetime import datetime
|
|
|
10
10
|
from io import BytesIO
|
|
11
11
|
from pprint import pformat
|
|
12
12
|
from subprocess import CalledProcessError
|
|
13
|
+
from typing import Optional, Union
|
|
13
14
|
from unittest.mock import Mock
|
|
14
15
|
from urllib.parse import urlparse
|
|
15
16
|
from urllib.request import urlopen
|
|
16
17
|
|
|
17
18
|
import mozilla_repo_urls
|
|
18
|
-
|
|
19
|
+
import msgspec
|
|
19
20
|
|
|
20
21
|
from taskgraph.util import json, yaml
|
|
21
22
|
from taskgraph.util.readonlydict import ReadOnlyDict
|
|
22
|
-
from taskgraph.util.schema import validate_schema
|
|
23
|
+
from taskgraph.util.schema import Schema, validate_schema
|
|
23
24
|
from taskgraph.util.taskcluster import find_task_id, get_artifact_url
|
|
24
25
|
from taskgraph.util.vcs import get_repository
|
|
25
26
|
|
|
@@ -30,43 +31,50 @@ class ParameterMismatch(Exception):
|
|
|
30
31
|
|
|
31
32
|
#: Schema for base parameters.
|
|
32
33
|
#: Please keep this list sorted and in sync with docs/reference/parameters.rst
|
|
33
|
-
base_schema = Schema(
|
|
34
|
+
base_schema = Schema.from_dict(
|
|
34
35
|
{
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
36
|
+
"base_repository": str,
|
|
37
|
+
"base_ref": Optional[str],
|
|
38
|
+
"base_rev": str,
|
|
39
|
+
"build_date": int,
|
|
40
|
+
"build_number": int,
|
|
41
|
+
"do_not_optimize": list[str],
|
|
42
|
+
"enable_always_target": Union[bool, list[str]],
|
|
43
|
+
"existing_tasks": dict[str, str],
|
|
44
|
+
"files_changed": list[str],
|
|
45
|
+
"filters": list[str],
|
|
46
|
+
"head_ref": str,
|
|
47
|
+
"head_repository": str,
|
|
48
|
+
"head_rev": str,
|
|
49
|
+
"head_tag": str,
|
|
50
|
+
"level": str,
|
|
51
|
+
"moz_build_date": str,
|
|
52
|
+
"next_version": Optional[str],
|
|
53
|
+
"optimize_strategies": Optional[str],
|
|
54
|
+
"optimize_target_tasks": bool,
|
|
55
|
+
"owner": str,
|
|
56
|
+
"project": str,
|
|
57
|
+
"pushdate": int,
|
|
58
|
+
"pushlog_id": str,
|
|
59
|
+
"repository_type": str,
|
|
59
60
|
# target-kinds is not included, since it should never be
|
|
60
61
|
# used at run-time
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
62
|
+
"target_tasks_method": str,
|
|
63
|
+
"tasks_for": str,
|
|
64
|
+
"version": Optional[str],
|
|
65
|
+
"code-review": Schema.from_dict(
|
|
66
|
+
{"phabricator-build-target": str},
|
|
67
|
+
name="CodeReviewConfig",
|
|
68
|
+
optional=True,
|
|
69
|
+
),
|
|
70
|
+
},
|
|
71
|
+
name="BaseParametersSchema",
|
|
72
|
+
forbid_unknown_fields=False,
|
|
73
|
+
kw_only=True,
|
|
68
74
|
)
|
|
69
75
|
|
|
76
|
+
_parameter_extensions: list = []
|
|
77
|
+
|
|
70
78
|
|
|
71
79
|
def get_contents(path):
|
|
72
80
|
with open(path) as fh:
|
|
@@ -83,11 +91,21 @@ def _get_defaults(repo_root=None):
|
|
|
83
91
|
repo_path = repo_root or os.getcwd()
|
|
84
92
|
try:
|
|
85
93
|
repo = get_repository(repo_path)
|
|
86
|
-
|
|
87
|
-
#
|
|
88
|
-
|
|
94
|
+
# Resolve git-backed attributes eagerly so any subprocess failures
|
|
95
|
+
# (e.g. Windows "dubious ownership" when safe.directory isn't honored)
|
|
96
|
+
# are caught by the except below instead of escaping later.
|
|
97
|
+
branch = repo.branch
|
|
98
|
+
head_rev = repo.head_rev
|
|
99
|
+
tool = repo.tool
|
|
100
|
+
files_changed = repo.get_changed_files("AM")
|
|
101
|
+
except (RuntimeError, CalledProcessError):
|
|
102
|
+
# Use fake values if no repo is detected or git refuses to operate.
|
|
103
|
+
repo = Mock()
|
|
89
104
|
repo.get_url.return_value = ""
|
|
90
|
-
|
|
105
|
+
branch = ""
|
|
106
|
+
head_rev = ""
|
|
107
|
+
tool = "git"
|
|
108
|
+
files_changed = []
|
|
91
109
|
|
|
92
110
|
try:
|
|
93
111
|
repo_url = repo.get_url()
|
|
@@ -110,11 +128,11 @@ def _get_defaults(repo_root=None):
|
|
|
110
128
|
"do_not_optimize": [],
|
|
111
129
|
"enable_always_target": True,
|
|
112
130
|
"existing_tasks": {},
|
|
113
|
-
"files_changed":
|
|
131
|
+
"files_changed": files_changed,
|
|
114
132
|
"filters": ["target_tasks_method"],
|
|
115
|
-
"head_ref":
|
|
133
|
+
"head_ref": branch or head_rev,
|
|
116
134
|
"head_repository": repo_url,
|
|
117
|
-
"head_rev":
|
|
135
|
+
"head_rev": head_rev,
|
|
118
136
|
"head_tag": "",
|
|
119
137
|
"level": "3",
|
|
120
138
|
"moz_build_date": datetime.now().strftime("%Y%m%d%H%M%S"),
|
|
@@ -125,7 +143,7 @@ def _get_defaults(repo_root=None):
|
|
|
125
143
|
"project": project,
|
|
126
144
|
"pushdate": int(time.time()),
|
|
127
145
|
"pushlog_id": "0",
|
|
128
|
-
"repository_type":
|
|
146
|
+
"repository_type": tool,
|
|
129
147
|
"target_tasks_method": "default",
|
|
130
148
|
"tasks_for": "",
|
|
131
149
|
"version": get_version(repo_path),
|
|
@@ -143,19 +161,27 @@ def extend_parameters_schema(schema, defaults_fn=None):
|
|
|
143
161
|
graph-configuration.
|
|
144
162
|
|
|
145
163
|
Args:
|
|
146
|
-
schema
|
|
147
|
-
parameters.
|
|
164
|
+
schema: A msgspec ``Schema`` subclass describing extended parameters.
|
|
148
165
|
defaults_fn (function): A function which takes no arguments and returns a
|
|
149
166
|
dict mapping parameter name to default value in the
|
|
150
167
|
event strict=False (optional).
|
|
151
168
|
"""
|
|
152
|
-
global base_schema
|
|
153
169
|
global defaults_functions
|
|
154
|
-
|
|
170
|
+
if not (isinstance(schema, type) and issubclass(schema, msgspec.Struct)):
|
|
171
|
+
raise TypeError(
|
|
172
|
+
"extend_parameters_schema requires a msgspec Schema subclass; "
|
|
173
|
+
f"got {type(schema).__name__}"
|
|
174
|
+
)
|
|
175
|
+
_parameter_extensions.append(schema)
|
|
155
176
|
if defaults_fn:
|
|
156
177
|
defaults_functions.append(defaults_fn)
|
|
157
178
|
|
|
158
179
|
|
|
180
|
+
def _schema_key_names(schema) -> set:
|
|
181
|
+
"""Return the data-level field names declared by a parameters schema."""
|
|
182
|
+
return {f.encode_name for f in msgspec.structs.fields(schema)}
|
|
183
|
+
|
|
184
|
+
|
|
159
185
|
class Parameters(ReadOnlyDict):
|
|
160
186
|
"""An immutable dictionary with nicer KeyError messages on failure"""
|
|
161
187
|
|
|
@@ -214,11 +240,30 @@ class Parameters(ReadOnlyDict):
|
|
|
214
240
|
return kwargs
|
|
215
241
|
|
|
216
242
|
def check(self):
|
|
217
|
-
|
|
218
|
-
base_schema if self.strict else base_schema.extend({}, extra=ALLOW_EXTRA)
|
|
219
|
-
)
|
|
243
|
+
data = dict(self.copy())
|
|
220
244
|
try:
|
|
221
|
-
|
|
245
|
+
# Validate core fields against just the subset of data owned by the
|
|
246
|
+
# base schema. Extension keys are validated separately below, and a
|
|
247
|
+
# strict-mode check rejects anything unknown to either.
|
|
248
|
+
base_keys = _schema_key_names(base_schema)
|
|
249
|
+
base_data = {k: v for k, v in data.items() if k in base_keys}
|
|
250
|
+
validate_schema(base_schema, base_data, "Invalid parameters:")
|
|
251
|
+
|
|
252
|
+
# Validate each registered extension against the keys it declares.
|
|
253
|
+
allowed = set(base_keys)
|
|
254
|
+
for ext in _parameter_extensions:
|
|
255
|
+
ext_keys = _schema_key_names(ext)
|
|
256
|
+
allowed |= ext_keys
|
|
257
|
+
ext_data = {k: data[k] for k in ext_keys if k in data}
|
|
258
|
+
validate_schema(ext, ext_data, "Invalid parameters:")
|
|
259
|
+
|
|
260
|
+
# Strict mode: reject any data key not covered by base or extensions.
|
|
261
|
+
if self.strict:
|
|
262
|
+
unknown = sorted(set(data) - allowed)
|
|
263
|
+
if unknown:
|
|
264
|
+
raise Exception(
|
|
265
|
+
"Invalid parameters:\nunknown keys: " + ", ".join(unknown)
|
|
266
|
+
)
|
|
222
267
|
except Exception as e:
|
|
223
268
|
raise ParameterMismatch(str(e))
|
|
224
269
|
|
{taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/run-task/fetch-content
RENAMED
|
@@ -626,7 +626,7 @@ def fetch_and_extract(url, dest_dir, extract=True, sha256=None, size=None):
|
|
|
626
626
|
the destination directory.
|
|
627
627
|
"""
|
|
628
628
|
|
|
629
|
-
basename = urllib.parse.urlparse(url).path.split("/")[-1]
|
|
629
|
+
basename = urllib.parse.unquote(urllib.parse.urlparse(url).path.split("/")[-1])
|
|
630
630
|
dest_path = dest_dir / basename
|
|
631
631
|
|
|
632
632
|
download_to_path(url, dest_path, sha256=sha256, size=size)
|
|
@@ -920,16 +920,17 @@ def command_task_artifacts(args):
|
|
|
920
920
|
sha256 = None
|
|
921
921
|
if fetch.get("verify-hash"):
|
|
922
922
|
sha256 = get_hash(fetch, root_url)
|
|
923
|
+
encoded_artifact = urllib.parse.quote(fetch["artifact"])
|
|
923
924
|
if fetch["artifact"].startswith("public/"):
|
|
924
925
|
path = "task/{task}/artifacts/{artifact}".format(
|
|
925
|
-
task=fetch["task"], artifact=
|
|
926
|
+
task=fetch["task"], artifact=encoded_artifact
|
|
926
927
|
)
|
|
927
928
|
url = api(root_url, "queue", "v1", path)
|
|
928
929
|
else:
|
|
929
930
|
url = ("{proxy_url}/api/queue/v1/task/{task}/artifacts/{artifact}").format(
|
|
930
931
|
proxy_url=os.environ["TASKCLUSTER_PROXY_URL"],
|
|
931
932
|
task=fetch["task"],
|
|
932
|
-
artifact=
|
|
933
|
+
artifact=encoded_artifact,
|
|
933
934
|
)
|
|
934
935
|
downloads.append((url, extdir, fetch["extract"], sha256))
|
|
935
936
|
|
{taskcluster_taskgraph-21.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/run-task/run-task
RENAMED
|
@@ -31,7 +31,7 @@ import time
|
|
|
31
31
|
import urllib.error
|
|
32
32
|
import urllib.request
|
|
33
33
|
from pathlib import Path
|
|
34
|
-
from typing import Dict,
|
|
34
|
+
from typing import Dict, Optional
|
|
35
35
|
|
|
36
36
|
SECRET_BASEURL_TPL = "{}/secrets/v1/secret/{{}}".format(
|
|
37
37
|
os.environ.get("TASKCLUSTER_PROXY_URL", "http://taskcluster").rstrip("/")
|
|
@@ -640,7 +640,6 @@ def git_checkout(
|
|
|
640
640
|
ssh_key_file: Optional[Path],
|
|
641
641
|
ssh_known_hosts_file: Optional[Path],
|
|
642
642
|
shallow: bool = False,
|
|
643
|
-
extra_refs: Optional[List[str]] = None,
|
|
644
643
|
):
|
|
645
644
|
assert head_ref or head_rev
|
|
646
645
|
|
|
@@ -735,14 +734,6 @@ def git_checkout(
|
|
|
735
734
|
env=env,
|
|
736
735
|
)
|
|
737
736
|
|
|
738
|
-
if extra_refs:
|
|
739
|
-
git_fetch(
|
|
740
|
-
destination_path,
|
|
741
|
-
*[f"{ref}:{ref}" for ref in extra_refs],
|
|
742
|
-
remote=head_repo,
|
|
743
|
-
env=env,
|
|
744
|
-
)
|
|
745
|
-
|
|
746
737
|
args = [
|
|
747
738
|
"git",
|
|
748
739
|
"checkout",
|
|
@@ -941,8 +932,6 @@ def collect_vcs_options(args, project, name):
|
|
|
941
932
|
head_rev = os.environ.get(f"{env_prefix}_HEAD_REV")
|
|
942
933
|
pip_requirements = os.environ.get(f"{env_prefix}_PIP_REQUIREMENTS")
|
|
943
934
|
private_key_secret = os.environ.get(f"{env_prefix}_SSH_SECRET_NAME")
|
|
944
|
-
if extra_refs := os.environ.get(f"{env_prefix}_EXTRA_REFS"):
|
|
945
|
-
extra_refs = json.loads(extra_refs)
|
|
946
935
|
|
|
947
936
|
store_path = os.environ.get("HG_STORE_PATH")
|
|
948
937
|
|
|
@@ -976,7 +965,6 @@ def collect_vcs_options(args, project, name):
|
|
|
976
965
|
"ssh-secret-name": private_key_secret,
|
|
977
966
|
"pip-requirements": pip_requirements,
|
|
978
967
|
"shallow-clone": shallow_clone,
|
|
979
|
-
"extra-refs": extra_refs,
|
|
980
968
|
}
|
|
981
969
|
|
|
982
970
|
|
|
@@ -1026,7 +1014,6 @@ def vcs_checkout_from_args(options):
|
|
|
1026
1014
|
ssh_key_file,
|
|
1027
1015
|
ssh_known_hosts_file,
|
|
1028
1016
|
shallow=options.get("shallow-clone", False),
|
|
1029
|
-
extra_refs=options.get("extra-refs"),
|
|
1030
1017
|
)
|
|
1031
1018
|
elif options["repo-type"] == "hg":
|
|
1032
1019
|
revision = hg_checkout(
|
|
@@ -44,13 +44,10 @@ class TaskGraph:
|
|
|
44
44
|
|
|
45
45
|
def to_json(self):
|
|
46
46
|
"Return a JSON-able object representing the task graph, as documented"
|
|
47
|
-
named_links_dict = self.graph.named_links_dict()
|
|
48
47
|
# this dictionary may be keyed by label or by taskid, so let's just call it 'key'
|
|
49
48
|
tasks = {}
|
|
50
49
|
for key in self.graph.visit_postorder():
|
|
51
50
|
tasks[key] = self.tasks[key].to_json()
|
|
52
|
-
# overwrite dependencies with the information in the taskgraph's edges.
|
|
53
|
-
tasks[key]["dependencies"] = named_links_dict.get(key, {})
|
|
54
51
|
return tasks
|
|
55
52
|
|
|
56
53
|
@classmethod
|