taskcluster-taskgraph 22.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-22.0.0 → taskcluster_taskgraph-23.0.0}/.pre-commit-config.yaml +2 -2
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/CHANGELOG.md +16 -0
- {taskcluster_taskgraph-22.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-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/howto/index.rst +1 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/migrations.rst +7 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/pyproject.toml +1 -1
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/actions/registry.py +16 -1
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/config.py +3 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/parameters.py +95 -50
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/run-task/fetch-content +4 -3
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/taskgraph.py +0 -3
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/from_deps.py +40 -40
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/schema.py +81 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/self_taskgraph/custom_parameters.py +9 -6
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_actions_registry.py +73 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_main.py +27 -1
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_parameters.py +8 -13
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_scripts_fetch_content.py +80 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_taskgraph.py +2 -3
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_schema.py +51 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/uv.lock +1 -1
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/.codespell-ignore-words.txt +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/.github/CODEOWNERS +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/.github/dependabot.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/.github/workflows/codeql-analysis.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/.github/workflows/pre-commit-autoupdate.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/.github/workflows/pre-commit.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/.github/workflows/pypi-publish.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/.gitignore +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/.readthedocs.yaml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/.taskcluster.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/.yamllint +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/CODE_OF_CONDUCT.md +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/CONTRIBUTING.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/LICENSE +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/Makefile +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/README.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/concepts/index.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/concepts/kind.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/concepts/loading.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/concepts/optimization.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/concepts/overview.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/concepts/scopes.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/concepts/task-graphs.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/concepts/transforms.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/conf.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/contributing.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/glossary.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/howto/bootstrap-taskgraph.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/howto/create-actions.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/howto/create-tasks.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/howto/debugging.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/howto/docker.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/howto/load-task-locally.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/howto/resolve-keyed-by.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/howto/run-locally.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/howto/send-notifications.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/howto/use-fetches.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/index.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/cli.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/index.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/optimization-strategies.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/parameters.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/source/modules.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/source/taskgraph.actions.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/source/taskgraph.loader.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/source/taskgraph.optimize.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/source/taskgraph.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/source/taskgraph.transforms.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/source/taskgraph.transforms.run.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/source/taskgraph.util.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/transforms/chunking.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/transforms/from_deps.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/transforms/index.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/transforms/matrix.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/reference/transforms/task_context.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/tutorials/connecting-taskcluster.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/tutorials/creating-a-task-graph.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/tutorials/example-taskcluster.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/tutorials/getting-started.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/docs/tutorials/index.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/make.bat +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/packages/pytest-taskgraph/README.md +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/packages/pytest-taskgraph/pyproject.toml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/packages/pytest-taskgraph/src/pytest_taskgraph/__init__.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/packages/pytest-taskgraph/src/pytest_taskgraph/fixtures/gen.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/packages/pytest-taskgraph/src/pytest_taskgraph/fixtures/vcs.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/packages/sphinx-taskgraph/README.md +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/packages/sphinx-taskgraph/pyproject.toml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/packages/sphinx-taskgraph/src/sphinx_taskgraph/__init__.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/packages/sphinx-taskgraph/src/sphinx_taskgraph/autoschema.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/__init__.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/actions/__init__.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/actions/add_new_jobs.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/actions/cancel.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/actions/cancel_all.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/actions/rebuild_cached_tasks.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/actions/retrigger.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/actions/util.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/create.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/decision.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/docker.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/filter_tasks.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/generator.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/graph.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/loader/__init__.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/loader/default.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/loader/transform.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/main.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/morph.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/optimize/__init__.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/optimize/base.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/optimize/strategies.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/run-task/hgrc +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/run-task/robustcheckout.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/run-task/run-task +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/target_tasks.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/task.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/__init__.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/base.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/cached_tasks.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/chunking.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/code_review.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/docker_image.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/fetch.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/matrix.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/notify.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/run/__init__.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/run/common.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/run/index_search.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/run/run_task.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/run/toolchain.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/task.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/task_context.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/__init__.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/archive.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/attributes.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/cached_tasks.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/caches.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/copy.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/dependencies.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/docker.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/hash.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/json.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/keyed_by.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/parameterization.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/path.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/python_path.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/readonlydict.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/set_name.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/shell.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/taskcluster.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/taskgraph.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/templates.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/time.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/treeherder.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/vcs.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/verify.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/workertypes.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/util/yaml.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/config.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/REGISTRY +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/decision/Dockerfile +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/decision/HASH +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/decision/README.md +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/decision/VERSION +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/decision/system-setup.sh +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/fetch/Dockerfile +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/image_builder/README.rst +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/index-task/Dockerfile +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/index-task/README +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/index-task/insert-indexes.js +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/index-task/package.json +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/index-task/yarn.lock +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/python/Dockerfile +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/run-task/Dockerfile +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/run-task/system-setup.sh +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/skopeo/Dockerfile +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/skopeo/policy.json +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/docker/skopeo/push_image.sh +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/kinds/check/kind.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/kinds/codecov/kind.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/kinds/complete/kind.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/kinds/doc/kind.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/kinds/docker-image/kind.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/kinds/fetch/kind.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/kinds/push-image/kind.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/kinds/test/kind.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/kinds/test/linux.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/kinds/test/windows.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/scripts/codecov-upload.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/self_taskgraph/__init__.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/self_taskgraph/custom_target_tasks.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/self_taskgraph/transforms/add_pr_route.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/self_taskgraph/transforms/push_image.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/test/params/main-repo-pull-request-untrusted.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/test/params/main-repo-pull-request.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/test/params/main-repo-push.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/test/params/main-repo-release-pytest-taskgraph.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/taskcluster/test/params/main-repo-release-taskcluster-taskgraph.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/template/cookiecutter.json +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/template/hooks/post_gen_project.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/template/{{cookiecutter.project_name}}/taskcluster/config.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/template/{{cookiecutter.project_name}}/taskcluster/docker/linux/Dockerfile +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/template/{{cookiecutter.project_name}}/taskcluster/kinds/docker-image/kind.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/template/{{cookiecutter.project_name}}/taskcluster/kinds/hello/kind.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/template/{{cookiecutter.project_name}}/taskcluster/{{cookiecutter.project_slug}}_taskgraph/transforms/hello.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/template/{{cookiecutter.project_name}}/taskcluster.github.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/__init__.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/automationrelevance.json +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/conftest.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/data/task_context.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/data/taskcluster/config.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/data/taskcluster/docker/hello-world/Dockerfile +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/data/taskcluster/docker/hello-world-tag/Dockerfile +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/data/taskcluster/docker/hello-world-tag/REGISTRY +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/data/taskcluster/docker/hello-world-tag/VERSION +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/data/taskcluster/kinds/docker-image/kind.yml +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/data/taskcluster/scripts/toolchain/run.ps1 +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/data/taskcluster/scripts/toolchain/run.sh +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/data/taskcluster/test_taskgraph/transforms/foo.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/data/testmod/thing.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/mockedopen.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_actions_rebuild_cached_tasks.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_config.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_create.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_decision.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_docker.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_generator.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_graph.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_morph.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_optimize.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_optimize_strategies.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_scripts_run_task.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_target_tasks.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_transform_chunking.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_transform_docker_image.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_transform_task_context.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_transforms_base.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_transforms_cached_tasks.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_transforms_fetch.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_transforms_from_deps.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_transforms_matrix.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_transforms_notify.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_transforms_run.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_transforms_run_run_task.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_transforms_run_toolchain.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_transforms_task.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_archive.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_attributes.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_cached_tasks.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_copy.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_dependencies.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_docker.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_json.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_keyed_by.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_parameterization.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_path.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_python_path.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_readonlydict.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_taskcluster.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_templates.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_time.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_treeherder.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_vcs.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_verify.py +0 -0
- {taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/test/test_util_workertypes.py +0 -0
- {taskcluster_taskgraph-22.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
|
|
@@ -1,5 +1,21 @@
|
|
|
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
|
+
|
|
3
19
|
## [22.0.0] - 2026-04-16
|
|
4
20
|
|
|
5
21
|
### Fixed
|
|
@@ -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,13 @@ 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
|
+
|
|
6
13
|
21.x -> 22.x
|
|
7
14
|
------------
|
|
8
15
|
|
{taskcluster_taskgraph-22.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)))
|
|
@@ -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-22.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
|
|
|
@@ -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
|
{taskcluster_taskgraph-22.0.0 → taskcluster_taskgraph-23.0.0}/src/taskgraph/transforms/from_deps.py
RENAMED
|
@@ -22,46 +22,46 @@ from taskgraph.util.dependencies import GROUP_BY_MAP, get_dependencies
|
|
|
22
22
|
from taskgraph.util.schema import Schema, validate_schema
|
|
23
23
|
from taskgraph.util.set_name import SET_NAME_MAP
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
25
|
+
FROM_DEPS_SCHEMA = Schema.from_dict(
|
|
26
|
+
{
|
|
27
|
+
"from-deps": Schema.from_dict(
|
|
28
|
+
{
|
|
29
|
+
# Limit dependencies to specified kinds (defaults to all kinds in
|
|
30
|
+
# `kind-dependencies`).
|
|
31
|
+
#
|
|
32
|
+
# The first kind in the list is the "primary" kind. The
|
|
33
|
+
# dependency of this kind will be used to derive the label
|
|
34
|
+
# and copy attributes (if `copy-attributes` is True).
|
|
35
|
+
"kinds": Optional[list[str]],
|
|
36
|
+
# Set-name function (dynamic: validated at runtime against SET_NAME_MAP).
|
|
37
|
+
"set-name": Optional[Union[bool, str, dict[str, object]]],
|
|
38
|
+
# Limit dependencies to tasks whose attributes match
|
|
39
|
+
# using :func:`~taskgraph.util.attributes.attrmatch`.
|
|
40
|
+
"with-attributes": Optional[dict[str, Union[list, str]]],
|
|
41
|
+
# Group cross-kind dependencies using the given group-by
|
|
42
|
+
# function. One task will be created for each group. If not
|
|
43
|
+
# specified, the 'single' function will be used which creates
|
|
44
|
+
# a new task for each individual dependency.
|
|
45
|
+
"group-by": Optional[Union[str, dict[str, object]]],
|
|
46
|
+
# If True, copy attributes from the dependency matching the
|
|
47
|
+
# first kind in the `kinds` list (whether specified explicitly
|
|
48
|
+
# or taken from `kind-dependencies`).
|
|
49
|
+
"copy-attributes": Optional[bool],
|
|
50
|
+
# If true (the default), there must be only a single unique task
|
|
51
|
+
# for each kind in a dependency group. Setting this to false
|
|
52
|
+
# disables that requirement.
|
|
53
|
+
"unique-kinds": Optional[bool],
|
|
54
|
+
# If present, a `fetches` entry will be added for each task
|
|
55
|
+
# dependency. Attributes of the upstream task may be used as
|
|
56
|
+
# substitution values in the `artifact` or `dest` values of the
|
|
57
|
+
# `fetches` entry.
|
|
58
|
+
"fetches": Optional[dict[str, list[FetchesEntrySchema]]],
|
|
59
|
+
},
|
|
60
|
+
),
|
|
61
|
+
},
|
|
62
|
+
name="FromDepsSchema",
|
|
63
|
+
forbid_unknown_fields=False,
|
|
64
|
+
)
|
|
65
65
|
|
|
66
66
|
transforms = TransformSequence()
|
|
67
67
|
transforms.add_validate(FROM_DEPS_SCHEMA)
|