-
Notifications
You must be signed in to change notification settings - Fork 0
Add desktop nightly release info and some refactor #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
0d595f9
622218f
b210abd
aa49052
2cf5a50
7f47b36
e845528
0e23aec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| # Thunderbird Desktop's nightly releases | ||
|
|
||
| This process is fairly well documented in general, however this doc attempts to shed some light into some of the intricacies of it. | ||
|
|
||
| ## Overview | ||
|
|
||
| In summary, nightly build jobs are triggered based on the [.cron.yml](https://hg-edge.mozilla.org/comm-central/file/tip/.cron.yml) file (whose schema can be found [here](https://github.com/mozilla-releng/fxci-config/blob/main/build-decision/src/build_decision/cron/schema.yml)) defined in the root directory of the [comm-central](https://hg-edge.mozilla.org/comm-central/file) repository. As described at [taskcluster/cron.html](https://firefox-source-docs.mozilla.org/taskcluster/cron.html), the [TaskCluster Hooks Service](https://firefox-ci-tc.services.mozilla.com/hooks) has a hook for each repository that runs every 15 minutes which reads `.cron.yml`, consults the time the cron task was created, rounded down to the nearest 15 minutes, and creates the tasks for the specified cron jobs based on the template [cron-task-template.yml](https://github.com/mozilla-releng/fxci-config/blob/main/cron-task-template.yml). | ||
|
|
||
| ## Cron job definition | ||
|
|
||
| ``` | ||
| jobs: | ||
| - name: nightly-desktop | ||
| job: | ||
| type: decision-task | ||
| treeherder-symbol: Nd | ||
| target-tasks-method: nightly_desktop | ||
| run-on-projects: | ||
| - comm-central | ||
| when: [{hour: 11, minute: 0}] | ||
| ``` | ||
|
|
||
| ## Decision Task | ||
|
|
||
| As seen above, the cron job specifies a `job.type`, which corresponds to the function responsible for creating TaskCluster tasks when the job runs. | ||
| In this case, the job type is `decision-task`, which results in a task that runs the [build-decision](https://github.com/mozilla-releng/fxci-config/tree/main/build-decision) docker image (see [Dockerfile](https://github.com/mozilla-releng/fxci-config/blob/main/taskcluster/docker/build-decision/Dockerfile). Specifically, the entry point for this image is a binary called `build-decision` located at `/build/.venv/bin/build-decision` which gets generated by `uv` based on [pyproject.toml](https://github.com/mozilla-releng/fxci-config/blob/main/build-decision/pyproject.toml#L28) and ultimately runs [main()](https://github.com/mozilla-releng/fxci-config/blob/main/build-decision/src/build_decision/util/cli.py#L53-L63). This method, in turn, parses the incoming arguments (e.g `cron` for cron tasks) and invokes [cron(options)](https://github.com/mozilla-releng/fxci-config/blob/main/build-decision/src/build_decision/cli.py#L79-L92) method which gets the job created. An example execution of this binary and arguments passed by TaskCluster is as follows: | ||
|
|
||
| ``` | ||
| build-decision cron \ | ||
| --repo-url https://hg.mozilla.org/comm-central \ | ||
| --project comm-central \ | ||
| --level 3 \ | ||
| --repository-type hg \ | ||
| --trust-domain comm \ | ||
| --branch default | ||
| ``` | ||
|
|
||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be nice to also add some details about what tasks are selected and how for the nightly_build. It looks like we re-use https://searchfox.org/firefox-main/source/taskcluster/gecko_taskgraph/target_tasks.py#999 and comm_taskgraph/decision.py is involved. For task selection it looks like that happens around here: https://searchfox.org/firefox-main/source/taskcluster/gecko_taskgraph/target_tasks.py#899 Which in comm/taskcluster/kinds should match up with: One more thing that would be nice to document is the flow of mach taskgraph decision. This is from claude code, so would need verifying but something along these lines:
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've added a detailed flow on how the nightly decision task is handled, within the This is fairly detailed — happy to pare it down if you'd prefer a higher-level overview. Just let me know. |
||
| Jobs with type `decision-task` create tasks based on the [.taskcluster.yml](https://hg-edge.mozilla.org/comm-central/file/tip/.taskcluster.yml) file. This file has a route defined for cron tasks at [line 145](https://hg-edge.mozilla.org/comm-central/file/tip/.taskcluster.yml#l145) that points to where the resulting task in TaskCluster will be. After replacing all the variables we get the nightly desktop decision task [URL](https://firefox-ci-tc.services.mozilla.com/tasks/index/comm.v2.comm-central.latest.taskgraph/decision-nightly-desktop). | ||
|
|
||
| > [!NOTE] | ||
| > Click `View Task` -> `Full Task Definition` and you'll see a reference to the actual task created by `build-decision`: | ||
| > | ||
| > ``` | ||
| > description: >- | ||
| > Created by a [cron | ||
| > task](https://firefox-ci-tc.services.mozilla.com/tasks/V12RpoRORi6MsIC507wFbg) | ||
| > ([Treeherder | ||
| > job](https://treeherder.mozilla.org/#/jobs?repo=comm-central&revision=8746fe1c7efe0d0f92f6dcf73ea6d6b65d367c39&selectedTaskRun=WQc5nWWfSNGu1I48hN_vSg)) | ||
| > ``` | ||
| > | ||
| > Go into that task and you'll see the exact arguments that were passed on the `build-decision` binary. | ||
|
|
||
| We can also copy the `Task ID` from there and look up the task in TreeHerder: | ||
|
|
||
| ``` | ||
| https://treeherder.mozilla.org/#/jobs?repo=comm-central&selectedTaskRun=<taskID> | ||
| ``` | ||
|
|
||
| Alternatively, we can also filter by all `cron` tasks in TreeHerder, like [this](https://treeherder.mozilla.org/jobs?repo=comm-central&job_type_name=cron). | ||
|
|
||
| Look for tasks that show `Cron(Nd)`. You may need to expand cron tasks that have been grouped (example the ones showing `Cron(+X)`), where `X` is the number grouped cron tasks. | ||
|
|
||
| When viewing the artifacts of the nightly decision task, you will notice a set of `docker-contexts/<image_name>.tar.gz` files. These are Docker build contexts — tarballs containing the Dockerfile and supporting files for each Docker image used by tasks in the graph. They are produced by the decision task itself and consumed by docker-image build tasks, which fetch the appropriate tarball, build the image, and upload the result for downstream tasks to use. | ||
|
|
||
| ## mach taskgraph decision | ||
|
|
||
| By going into the TaskCluster nightly build decision task URL [here](https://firefox-ci-tc.services.mozilla.com/tasks/index/comm.v2.comm-central.latest.taskgraph/decision-nightly-desktop) and viewing the full task definition we see the task executes a `mach taskgraph decision` (see implementation [here](https://searchfox.org/firefox-main/source/taskcluster/mach_commands.py#260-328)) command with a bunch of parameters pertaining to Thunderbird's repository location in addition to `--target-tasks-method=nightly_desktop`, which specifies the registered method responsible for building and returning the full graph of tasks pertaining to nightly builds and releases (see definition [here](https://searchfox.org/firefox-main/source/taskcluster/gecko_taskgraph/target_tasks.py#999-1015)). | ||
|
|
||
| The [taskgraph_decision()](https://searchfox.org/firefox-main/source/taskcluster/mach_commands.py#266) method is the entry point for the `mach taskgraph decision` command and ultimately executes [taskgraph_commands["decision"].func(options)](https://searchfox.org/firefox-main/source/taskcluster/mach_commands.py#287) which is an alias for [gecko_taskgraph.main.decision()](https://searchfox.org/firefox-main/source/taskcluster/gecko_taskgraph/main.py#538-598), which in turn calls [taskgraph_decision()](https://searchfox.org/firefox-main/source/taskcluster/gecko_taskgraph/decision.py#171) in `decision.py`. The detailed flow is as follows: | ||
|
|
||
| 1. `taskgraph_decision()` creates a `TaskGraphGenerator` with `root_dir` set to `comm/taskcluster` (from the `--root` CLI arg). When `TaskGraphGenerator` gets instantiated it calls [self_run()](https://github.com/taskcluster/taskgraph/blob/main/src/taskgraph/generator.py#L164), which calls [load_graph_config(root_dir)](https://github.com/taskcluster/taskgraph/blob/main/src/taskgraph/config.py#L164-L173) that reads [comm/taskcluster/config.yml](https://searchfox.org/comm-central/source/taskcluster/config.yml) into a `GraphConfig` object and then calls `graph_config.register()`. This adds `comm/taskcluster` to the Python path (making `comm_taskgraph` importable - see [here](https://github.com/taskcluster/taskgraph/blob/main/src/taskgraph/config.py#L127)) and calls the `comm_taskgraph:register` hook. | ||
| 2. The `graph_config` object now holds the contents of `comm/taskcluster/config.yml`, including the `taskgraph.decision-parameters` entry pointing to `comm_taskgraph.decision:get_decision_parameters`. | ||
| 3. [gecko_taskgraph.decision.get_decision_parameters()](https://searchfox.org/firefox-main/source/taskcluster/gecko_taskgraph/decision.py#277) builds the initial parameters from the CLI options, including setting `target_tasks_method: nightly_desktop`. At the end, it [checks](https://searchfox.org/firefox-main/source/taskcluster/gecko_taskgraph/decision.py#440-443) whether `graph_config["taskgraph"]` has a `decision-parameters` key, finds it, and calls [comm_taskgraph.decision.get_decision_parameters()](https://searchfox.org/comm-central/source/taskcluster/comm_taskgraph/decision.py#134), which: | ||
| - Sets project defaults from [PER_PROJECT_PARAMETERS](https://searchfox.org/comm-central/source/taskcluster/comm_taskgraph/decision.py#38-70) — for `comm-central` this would default `target_tasks_method` to `comm_central_tasks`. | ||
| - Overrides `target_tasks_method` back to `nightly_desktop` from the CLI arg (since CLI args take precedence). | ||
| - `tasks_for` was set to `"cron"` by gecko's `get_decision_parameters()`, which reads it directly from the `--tasks-for=cron` CLI argument passed by `build-decision` when it created the decision task. Comm's function checks this value and, since it is `"cron"`, looks up `nightly_desktop` in [`CRON_OPTIONS`](https://searchfox.org/comm-central/source/taskcluster/comm_taskgraph/decision.py#72-81) to populate two additional parameters. `existing_tasks` is populated by finding the on-push decision task for the same revision and fetching its `full-task-graph.json` artifact, which contains a mapping of task labels (e.g. `build-linux64-shippable/opt`) to the TaskCluster task IDs that were scheduled during that push. `existing_tasks` is then consumed by the optimization phase — a step inside the base `taskgraph` library's `TaskGraphGenerator._run()` that runs after `nightly_desktop()` has determined the target task set. It calls [`optimize_task_graph()`](https://github.com/taskcluster/taskgraph/blob/main/src/taskgraph/optimize/base.py) which, for each task in the nightly graph, looks up its label in `existing_tasks`: if a match is found the task is not scheduled again and its existing task ID is recorded for downstream tasks to reference. Tasks that are nightly-specific (signing, beetmover uploads, Balrog submission) have no entry in `existing_tasks` since they were never part of the on-push graph, so they get scheduled fresh. `release_history` is populated synchronously during `comm_taskgraph.decision.get_decision_parameters()` via [`populate_release_history()`](https://searchfox.org/firefox-main/source/taskcluster/gecko_taskgraph/util/partials.py#178), which queries the Balrog API for the URLs of previous nightly complete MARs. Partial MAR generation tasks use these to produce binary diffs against the current nightly, giving users on a recent version a smaller incremental update to download. | ||
| 4. With the finalized parameters, when the [target_tasks_method](https://taskcluster-taskgraph.readthedocs.io/en/latest/reference/parameters.html#target-tasks-method) is resolved, it calls [nightly_desktop()](https://searchfox.org/firefox-main/source/taskcluster/gecko_taskgraph/target_tasks.py#999-1015) to determine the set of tasks to schedule. | ||
| 5. The resulting task graph is optimized, written out as artifacts, and tasks are created via the TaskCluster API. | ||
|
|
||
| ### Task selection | ||
|
|
||
| `nightly_desktop` uses [make_desktop_nightly_filter()](https://searchfox.org/firefox-main/source/taskcluster/gecko_taskgraph/target_tasks.py#892-905) to select tasks across all desktop platforms. The filter picks tasks that have the `shippable: true` attribute set, which in `comm/taskcluster/kinds/build/` corresponds to the shippable build variants: | ||
|
|
||
| - `linux64-shippable/opt` | ||
| - `linux64-aarch64-shippable/opt` | ||
| - `win32-shippable/opt` | ||
| - `win64-shippable/opt` | ||
| - `macosx64-shippable/opt` | ||
| - `macosx64-aarch64-shippable/opt` | ||
|
|
||
| The results for each platform are unioned together along with any platform-agnostic release tasks to produce the final task list. | ||
Uh oh!
There was an error while loading. Please reload this page.