Blame taskcluster/docs/how-tos.rst

Packit f0b94e
How Tos
Packit f0b94e
=======
Packit f0b94e
Packit f0b94e
All of this equipment is here to help you get your work done more efficiently.
Packit f0b94e
However, learning how task-graphs are generated is probably not the work you
Packit f0b94e
are interested in doing.  This section should help you accomplish some of the
Packit f0b94e
more common changes to the task graph with minimal fuss.
Packit f0b94e
Packit f0b94e
.. important::
Packit f0b94e
Packit f0b94e
    If you cannot accomplish what you need with the information provided here,
Packit f0b94e
    please consider whether you can achieve your goal in a different way.
Packit f0b94e
    Perhaps something simpler would cost a bit more in compute time, but save
Packit f0b94e
    the much more expensive resource of developers' mental bandwidth.
Packit f0b94e
    Task-graph generation is already complex enough!
Packit f0b94e
Packit f0b94e
    If you want to proceed, you may need to delve into the implementation of
Packit f0b94e
    task-graph generation.  The documentation and code are designed to help, as
Packit f0b94e
    are the authors - ``hg blame`` may help track down helpful people.
Packit f0b94e
Packit f0b94e
    As you write your new transform or add a new kind, please consider the next
Packit f0b94e
    developer.  Where possible, make your change data-driven and general, so
Packit f0b94e
    that others can make a much smaller change.  Document the semantics of what
Packit f0b94e
    you are changing clearly, especially if it involves modifying a transform
Packit f0b94e
    schema.  And if you are adding complexity temporarily while making a
Packit f0b94e
    gradual transition, please open a new bug to remind yourself to remove the
Packit f0b94e
    complexity when the transition is complete.
Packit f0b94e
Packit f0b94e
Hacking Task Graphs
Packit f0b94e
-------------------
Packit f0b94e
Packit f0b94e
The recommended process for changing task graphs is this:
Packit f0b94e
Packit f0b94e
1. Run one of the ``mach taskgraph`` subcommands (see :doc:`mach`) to
Packit f0b94e
   generate a baseline against which to measure your changes.
Packit f0b94e
Packit f0b94e
   .. code-block:: none
Packit f0b94e
Packit f0b94e
       ./mach taskgraph tasks --json > old-tasks.json
Packit f0b94e
Packit f0b94e
2. Make your modifications under ``taskcluster/``.
Packit f0b94e
Packit f0b94e
3. Run the same ``mach taskgraph`` command, sending the output to a new file,
Packit f0b94e
   and use ``diff`` to compare the old and new files.  Make sure your changes
Packit f0b94e
   have the desired effect and no undesirable side-effects.  A plain unified
Packit f0b94e
   diff should be useful for most changes, but in some cases it may be helpful
Packit f0b94e
   to post-process the JSON to strip distracting changes.
Packit f0b94e
Packit f0b94e
4. When you are satisfied with the changes, push them to try to ensure that the
Packit f0b94e
   modified tasks work as expected.
Packit f0b94e
Packit f0b94e
Hacking Actions
Packit f0b94e
...............
Packit f0b94e
Packit f0b94e
If you are working on an action task and wish to test it out locally, use the
Packit f0b94e
``./mach taskgraph test-action-callback`` command:
Packit f0b94e
Packit f0b94e
   .. code-block:: none
Packit f0b94e
Packit f0b94e
        ./mach taskgraph test-action-callback \
Packit f0b94e
            --task-id I4gu9KDmSZWu3KHx6ba6tw --task-group-id sMO4ybV9Qb2tmcI1sDHClQ \
Packit f0b94e
            --input input.yml hello_world_action
Packit f0b94e
Packit f0b94e
This invocation will run the hello world callback with the given inputs and
Packit f0b94e
print any created tasks to stdout, rather than actually creating them.
Packit f0b94e
Packit f0b94e
Common Changes
Packit f0b94e
--------------
Packit f0b94e
Packit f0b94e
Changing Test Characteristics
Packit f0b94e
.............................
Packit f0b94e
Packit f0b94e
First, find the test description.  This will be in
Packit f0b94e
``taskcluster/ci/*/tests.yml``, for the appropriate kind (consult
Packit f0b94e
:doc:`kinds`).  You will find a YAML stanza for each test suite, and each
Packit f0b94e
stanza defines the test's characteristics.  For example, the ``chunks``
Packit f0b94e
property gives the number of chunks to run.  This can be specified as a simple
Packit f0b94e
integer if all platforms have the same chunk count, or it can be keyed by test
Packit f0b94e
platform.  For example:
Packit f0b94e
Packit f0b94e
.. code-block:: yaml
Packit f0b94e
Packit f0b94e
    chunks:
Packit f0b94e
        by-test-platform:
Packit f0b94e
            linux64/debug: 10
Packit f0b94e
            default: 8
Packit f0b94e
Packit f0b94e
The full set of available properties is in
Packit f0b94e
``taskcluster/taskgraph/transform/tests/test_description.py``.  Some other
Packit f0b94e
commonly-modified properties are ``max-run-time`` (useful if tests are being
Packit f0b94e
killed for exceeding maxRunTime) and ``treeherder-symbol``.
Packit f0b94e
Packit f0b94e
.. note::
Packit f0b94e
Packit f0b94e
    Android tests are also chunked at the mozharness level, so you will need to
Packit f0b94e
    modify the relevant mozharness config, as well.
Packit f0b94e
Packit f0b94e
Adding a Test Suite
Packit f0b94e
...................
Packit f0b94e
Packit f0b94e
To add a new test suite, you will need to know the proper mozharness invocation
Packit f0b94e
for that suite, and which kind it fits into (consult :doc:`kinds`).
Packit f0b94e
Packit f0b94e
Add a new stanza to ``taskcluster/ci/<kind>/tests.yml``, copying from the other
Packit f0b94e
stanzas in that file.  The meanings should be clear, but authoritative
Packit f0b94e
documentation is in
Packit f0b94e
``taskcluster/taskgraph/transform/tests/test_description.py`` should you need
Packit f0b94e
it.  The stanza name is the name by which the test will be referenced in try
Packit f0b94e
syntax.
Packit f0b94e
Packit f0b94e
Add your new test to a test set in ``test-sets.yml`` in the same directory.  If
Packit f0b94e
the test should only run on a limited set of platforms, you may need to define
Packit f0b94e
a new test set and reference that from the appropriate platforms in
Packit f0b94e
``test-platforms.yml``.  If you do so, include some helpful comments in
Packit f0b94e
``test-sets.yml`` for the next person.
Packit f0b94e
Packit f0b94e
Greening Up a New Test
Packit f0b94e
......................
Packit f0b94e
Packit f0b94e
When a test is not yet reliably green, configuration for that test should not
Packit f0b94e
be landed on integration branches.  Of course, you can control where the
Packit f0b94e
configuration is landed!  For many cases, it is easiest to green up a test in
Packit f0b94e
try: push the configuration to run the test to try along with your work to fix
Packit f0b94e
the remaining test failures.
Packit f0b94e
Packit f0b94e
When working with a group, check out a "twig" repository to share among your
Packit f0b94e
group, and land the test configuration in that repository.  Once the test is
Packit f0b94e
green, merge to an integration branch and the test will begin running there as
Packit f0b94e
well.
Packit f0b94e
Packit f0b94e
Adding a New Task
Packit f0b94e
.................
Packit f0b94e
Packit f0b94e
If you are adding a new task that is not a test suite, there are a number of
Packit f0b94e
options.  A few questions to consider:
Packit f0b94e
Packit f0b94e
 * Is this a new build platform or variant that will produce an artifact to
Packit f0b94e
   be run through the usual test suites?
Packit f0b94e
Packit f0b94e
 * Does this task depend on other tasks?  Do other tasks depend on it?
Packit f0b94e
Packit f0b94e
 * Is this one of a few related tasks, or will you need to generate a large
Packit f0b94e
   set of tasks using some programmatic means (for example, chunking)?
Packit f0b94e
Packit f0b94e
 * How is the task actually excuted?  Mozharness?  Mach?
Packit f0b94e
Packit f0b94e
 * What kind of environment does the task require?
Packit f0b94e
Packit f0b94e
Armed with that information, you can choose among a few options for
Packit f0b94e
implementing this new task.  Try to choose the simplest solution that will
Packit f0b94e
satisfy your near-term needs.  Since this is all implemented in-tree, it
Packit f0b94e
is not difficult to refactor later when you need more generality.
Packit f0b94e
Packit f0b94e
Existing Kind
Packit f0b94e
`````````````
Packit f0b94e
Packit f0b94e
The simplest option is to add your task to an existing kind.  This is most
Packit f0b94e
practical when the task "makes sense" as part of that kind -- for example, if
Packit f0b94e
your task is building an installer for a new platform using mozharness scripts
Packit f0b94e
similar to the existing build tasks, it makes most sense to add your task to
Packit f0b94e
the ``build`` kind.  If you need some additional functionality in the kind,
Packit f0b94e
it's OK to modify the implementation as necessary, as long as the modification
Packit f0b94e
is complete and useful to the next developer to come along.
Packit f0b94e
Packit f0b94e
Tasks in the ``build`` kind generate Firefox installers, and the ``test`` kind
Packit f0b94e
will add a full set of Firefox tests for each ``build`` task.
Packit f0b94e
Packit f0b94e
New Kind
Packit f0b94e
````````
Packit f0b94e
Packit f0b94e
The next option to consider is adding a new kind.  A distinct kind gives you
Packit f0b94e
some isolation from other task types, which can be nice if you are adding an
Packit f0b94e
experimental kind of task.
Packit f0b94e
Packit f0b94e
Kinds can range in complexity.  The simplest sort of kind uses the transform
Packit f0b94e
loader to read a list of jobs from the ``jobs`` key, and applies the standard
Packit f0b94e
``job`` and ``task`` transforms:
Packit f0b94e
Packit f0b94e
.. code-block:: yaml
Packit f0b94e
Packit f0b94e
    implementation: taskgraph.task.transform:TransformTask
Packit f0b94e
    transforms:
Packit f0b94e
       - taskgraph.transforms.job:transforms
Packit f0b94e
       - taskgraph.transforms.task:transforms
Packit f0b94e
    jobs:
Packit f0b94e
       - ..your job description here..
Packit f0b94e
Packit f0b94e
Job descriptions are defined and documented in
Packit f0b94e
``taskcluster/taskgraph/transforms/job/__init__.py``.
Packit f0b94e
Packit f0b94e
Custom Kind Loader
Packit f0b94e
``````````````````
Packit f0b94e
Packit f0b94e
If your task depends on other tasks, then the decision of which tasks to create
Packit f0b94e
may require some code.  For example, the ``test`` kind iterates over
Packit f0b94e
the builds in the graph, generating a full set of test tasks for each one.  This specific
Packit f0b94e
post-build behavior is implemented as a loader defined in ``taskcluster/taskgraph/loader/test.py``.
Packit f0b94e
Packit f0b94e
A custom loader is useful when the set of tasks you want to create is not
Packit f0b94e
static but based on something else (such as the available builds) or when the
Packit f0b94e
dependency relationships for your tasks are complex.
Packit f0b94e
Packit f0b94e
Custom Transforms
Packit f0b94e
`````````````````
Packit f0b94e
Packit f0b94e
Most loaders apply a series of ":doc:`transforms <transforms>`" that start with
Packit f0b94e
an initial human-friendly description of a task and end with a task definition
Packit f0b94e
suitable for insertion into a Taskcluster queue.
Packit f0b94e
Packit f0b94e
Custom transforms can be useful to apply defaults, simplifying the YAML files
Packit f0b94e
in your kind. They can also apply business logic that is more easily expressed
Packit f0b94e
in code than in YAML.
Packit f0b94e
Packit f0b94e
Transforms need not be one-to-one: a transform can produce zero or more outputs
Packit f0b94e
for each input. For example, the test transforms perform chunking by producing
Packit f0b94e
an output for each chunk of a given input.
Packit f0b94e
Packit f0b94e
Ideally those transforms will produce job descriptions, so you can use the
Packit f0b94e
existing ``job`` and ``task`` transforms:
Packit f0b94e
Packit f0b94e
.. code-block:: yaml
Packit f0b94e
Packit f0b94e
    transforms:
Packit f0b94e
       - taskgraph.transforms.my_stuff:transforms
Packit f0b94e
       - taskgraph.transforms.job:transforms
Packit f0b94e
       - taskgraph.transforms.task:transforms
Packit f0b94e
Packit f0b94e
Try to keep transforms simple, single-purpose and well-documented!
Packit f0b94e
Packit f0b94e
Custom Run-Using
Packit f0b94e
````````````````
Packit f0b94e
Packit f0b94e
If the way your task is executed is unique (so, not a mach command or
Packit f0b94e
mozharness invocation), you can add a new implementation of the job
Packit f0b94e
description's "run" section.  Before you do this, consider that it might be a
Packit f0b94e
better investment to modify your task to support invocation via mozharness or
Packit f0b94e
mach, instead.  If this is not possible, then adding a new file in
Packit f0b94e
``taskcluster/taskgraph/transforms/jobs`` with a structure similar to its peers
Packit f0b94e
will make the new run-using option available for job descriptions.
Packit f0b94e
Packit f0b94e
Something Else?
Packit f0b94e
...............
Packit f0b94e
Packit f0b94e
If you make another change not described here that turns out to be simple or
Packit f0b94e
common, please include an update to this file in your patch.
Packit f0b94e
Packit f0b94e