# yamllint disable rule:line-length # This file is rendered via JSON-e by # - github events - https://github.com/taskcluster/taskcluster/tree/main/services/github # - cron tasks - https://hg.mozilla.org/ci/ci-admin/file/default/build-decision/ # - action tasks - taskcluster/taskgraph/actions/registry.py --- version: 1 reporting: checks-v1 autoCancelPreviousChecks: true policy: pullRequests: public_restricted tasks: # NOTE: support for actions in ci-admin requires that the `tasks` property be an array *before* JSON-e rendering # takes place. - $let: trustDomain: taskgraph ownerEmail: $switch: 'tasks_for == "github-push"': '${event.pusher.email}' 'tasks_for == "github-release"': 'release+taskgraph-ci@mozilla.com' 'tasks_for[:19] == "github-pull-request"': '${event.pull_request.user.login}@users.noreply.github.com' 'tasks_for in ["cron", "action", "pr-action"]': '${tasks_for}@noreply.mozilla.org' baseRepoUrl: $switch: 'tasks_for[:19] == "github-pull-request"': '${event.pull_request.base.repo.html_url}' 'tasks_for in ["cron", "action"]': '${repository.url}' 'tasks_for == "pr-action"': '${repository.base_url}' $default: '${event.repository.html_url}' repoUrl: $switch: 'tasks_for[:19] == "github-pull-request"': '${event.pull_request.head.repo.html_url}' 'tasks_for in ["cron", "action", "pr-action"]': '${repository.url}' $default: '${event.repository.html_url}' project: $switch: 'tasks_for in ["github-push", "github-release"]': '${event.repository.name}' 'tasks_for[:19] == "github-pull-request"': '${event.pull_request.base.repo.name}' 'tasks_for in ["cron", "action", "pr-action"]': '${repository.project}' head_branch: $switch: 'tasks_for[:19] == "github-pull-request"': ${event.pull_request.head.ref} 'tasks_for == "github-push"': ${event.ref} 'tasks_for == "github-release"': '${event.release.target_commitish}' 'tasks_for in ["cron", "action", "pr-action"]': '${push.branch}' base_ref: $switch: 'tasks_for[:19] == "github-pull-request"': ${event.pull_request.base.ref} # event.base_ref is barely documented[1]. Testing showed it's only # defined when creating a new branch. It's null when pushing to an # existing branch # # [1] https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#push 'tasks_for == "github-push" && event.base_ref': ${event.base_ref} 'tasks_for == "github-push" && !(event.base_ref)': ${event.ref} 'tasks_for == "github-release"': '' 'tasks_for in ["cron", "action"]': '${push.branch}' 'tasks_for == "pr-action"': '${push.base_branch}' head_ref: $switch: 'tasks_for[:19] == "github-pull-request"': ${event.pull_request.head.ref} 'tasks_for == "github-push"': ${event.ref} 'tasks_for in ["cron", "action", "pr-action"]': '${push.branch}' 'tasks_for == "github-release"': ${event.release.tag_name} base_sha: $switch: 'tasks_for == "github-push"': '${event.before}' 'tasks_for == "github-release"': '${event.release.target_commitish}' 'tasks_for[:19] == "github-pull-request"': '${event.pull_request.base.sha}' 'tasks_for in ["cron", "action", "pr-action"]': '${push.revision}' head_sha: $switch: 'tasks_for == "github-push"': '${event.after}' 'tasks_for[:19] == "github-pull-request"': '${event.pull_request.head.sha}' 'tasks_for in ["cron", "action", "pr-action"]': '${push.revision}' 'tasks_for == "github-release"': '${event.release.tag_name}' ownTaskId: $switch: '"github" in tasks_for': {$eval: as_slugid("decision_task")} 'tasks_for in ["cron", "action", "pr-action"]': '${ownTaskId}' pullRequestAction: $switch: 'tasks_for[:19] == "github-pull-request"': ${event.action} $default: 'UNDEFINED' releaseAction: $if: 'tasks_for == "github-release"' then: ${event.action} else: 'UNDEFINED' isPullRequest: $eval: 'tasks_for[:19] == "github-pull-request"' in: $if: > tasks_for in ["action", "pr-action", "cron"] || (tasks_for == "github-release" && releaseAction == "published") || (tasks_for == "github-push" && head_branch == "refs/heads/main") || (isPullRequest && pullRequestAction in ["opened", "reopened", "synchronize"]) then: $let: level: $if: 'tasks_for in ["github-release", "github-push", "cron", "action"] && repoUrl == "https://github.com/taskcluster/taskgraph"' then: 3 else: 1 short_head_ref: $if: 'head_ref[:10] == "refs/tags/"' then: {$eval: 'head_ref[10:]'} else: $if: 'head_ref[:11] == "refs/heads/"' then: {$eval: 'head_ref[11:]'} else: ${head_ref} in: taskId: {$if: 'tasks_for != "action" && tasks_for != "pr-action"', then: '${ownTaskId}'} taskGroupId: $if: 'tasks_for == "action" || tasks_for == "pr-action"' then: '${action.taskGroupId}' else: '${ownTaskId}' # same as taskId; this is how automation identifies a decision task schedulerId: '${trustDomain}-level-${level}' created: {$fromNow: ''} deadline: {$fromNow: '1 day'} expires: {$fromNow: '1 year 1 second'} # 1 second so artifacts expire first metadata: $merge: - owner: "${ownerEmail}" source: "${repoUrl}/raw/${head_sha}/.taskcluster.yml" - $switch: 'tasks_for in ["github-push", "github-release"] || isPullRequest': name: "Decision Task" description: 'The task that creates all of the other tasks in the task graph' 'tasks_for == "action"': name: "Action: ${action.title}" description: | ${action.description} Action triggered by clientID `${clientId}` 'tasks_for == "pr-action"': name: "PR action: ${action.title}" description: | ${action.description} PR action triggered by clientID `${clientId}` $default: name: "Decision Task for cron job ${cron.job_name}" description: 'Created by a [cron task](https://firefox-ci-tc.services.mozilla.com/tasks/${cron.task_id})' provisionerId: "${trustDomain}-${level}" workerType: "decision" tags: $switch: 'tasks_for == "github-push" || isPullRequest': createdForUser: "${ownerEmail}" kind: decision-task 'tasks_for == "action" || tasks_for == "pr-action"': createdForUser: '${ownerEmail}' kind: 'action-callback' 'tasks_for == "cron"': kind: cron-task routes: $flatten: - checks - {$if: '!isPullRequest && tasks_for != "pr-action"', then: ["tc-treeherder.v2.${project}.${head_sha}"], else: []} - $switch: 'tasks_for == "github-push"': - "index.${trustDomain}.v2.${project}.latest.taskgraph.decision" - "index.${trustDomain}.v2.${project}.revision.${head_sha}.taskgraph.decision" 'tasks_for == "action"': - "index.${trustDomain}.v2.${project}.revision.${head_sha}.taskgraph.actions.${ownTaskId}" 'tasks_for == "cron"': - "index.${trustDomain}.v2.${project}.latest.taskgraph.decision-${cron.job_name}" - "index.${trustDomain}.v2.${project}.revision.${head_sha}.taskgraph.decision-${cron.job_name}" # list each cron task on this revision, so actions can find them - 'index.${trustDomain}.v2.${project}.revision.${head_sha}.cron.${ownTaskId}' $default: [] scopes: $switch: 'tasks_for == "github-push"': - 'assume:repo:${repoUrl[8:]}:branch:${short_head_ref}' 'tasks_for == "github-release"': - 'assume:repo:${repoUrl[8:]}:release:${releaseAction}' 'isPullRequest': - 'assume:repo:github.com/${event.pull_request.base.repo.full_name}:${tasks_for[7:]}' 'tasks_for == "action"': - 'assume:repo:${repoUrl[8:]}:action:${action.action_perm}' 'tasks_for == "pr-action"': - 'assume:repo:${baseRepoUrl[8:]}:pr-action:${action.action_perm}' $default: - 'assume:repo:${repoUrl[8:]}:cron:${cron.job_name}' dependencies: [] requires: all-completed priority: # Most times, there is plenty of worker capacity so everything runs # quickly, but sometimes a storm of action tasks lands. Then we # want, from highest to lowest: # - cron tasks (time-sensitive) (low) # - decision tasks (minimize user-visible delay) (very-low) # - action tasks (avoid interfering with the other two) (lowest) # SCM levels all use different workerTypes, so there is no need for priority # between levels; "low" is the highest priority available at all levels, and # nothing runs at any higher priority on these workerTypes. $if: "tasks_for == 'cron'" then: low else: $if: 'tasks_for == "github-push" || isPullRequest' then: very-low else: lowest # tasks_for == 'action' retries: 5 payload: env: # run-task uses these to check out the source; the inputs # to `mach taskgraph decision` are all on the command line. $merge: - TASKGRAPH_BASE_REPOSITORY: '${baseRepoUrl}' TASKGRAPH_BASE_REF: '${base_ref}' TASKGRAPH_BASE_REV: '${base_sha}' TASKGRAPH_HEAD_REPOSITORY: '${repoUrl}' TASKGRAPH_HEAD_REF: '${head_ref}' TASKGRAPH_HEAD_REV: '${head_sha}' TASKGRAPH_REPOSITORY_TYPE: git REPOSITORIES: {$json: {taskgraph: Taskgraph}} - $if: 'isPullRequest' then: TASKGRAPH_PULL_REQUEST_NUMBER: '${event.pull_request.number}' - $if: 'tasks_for == "action" || tasks_for == "pr-action"' then: ACTION_TASK_GROUP_ID: '${action.taskGroupId}' # taskGroupId of the target task ACTION_TASK_ID: {$json: {$eval: 'taskId'}} # taskId of the target task (JSON-encoded) ACTION_INPUT: {$json: {$eval: 'input'}} ACTION_CALLBACK: '${action.cb_name}' cache: "${trustDomain}-level-${level}-checkouts-sparse-v2": /builds/worker/checkouts features: taskclusterProxy: true chainOfTrust: true image: mozillareleases/taskgraph:decision-latest maxRunTime: 1800 command: - run-task - '--taskgraph-checkout=/builds/worker/checkouts/src' - '--' - bash - -cx - $let: extraArgs: $if: 'tasks_for == "cron"' then: '${cron.quoted_args}' else: $if: 'tasks_for == "github-pull-request"' then: '--allow-parameter-override' else: '' in: $if: 'tasks_for == "action" || tasks_for == "pr-action"' then: > cd /builds/worker/checkouts/src && ln -s /builds/worker/artifacts artifacts && pip3 install --user --break-system-packages . && taskgraph action-callback else: > cd /builds/worker/checkouts/src && ln -s /builds/worker/artifacts artifacts && pip3 install --user --break-system-packages . && taskgraph decision --verbose --pushlog-id='0' --pushdate='0' --project='${project}' --owner='${ownerEmail}' --level='${level}' --repository-type=git --tasks-for='${tasks_for}' --base-repository='${baseRepoUrl}' --base-ref='${base_ref}' --base-rev='${base_sha}' --head-repository='${repoUrl}' --head-ref='${head_ref}' --head-rev='${head_sha}' ${extraArgs} artifacts: 'public': type: 'directory' path: '/builds/worker/artifacts' expires: {$fromNow: '1 year'} 'public/docker-contexts': type: 'directory' path: '/builds/worker/checkouts/src/docker-contexts' # This needs to be at least the deadline of the # decision task + the docker-image task deadlines. # It is set to a week to allow for some time for # debugging, but they are not useful long-term. expires: {$fromNow: '7 day'} extra: $merge: - treeherder: $merge: - machine: platform: gecko-decision - $switch: 'tasks_for in ["github-push", "github-release"] || isPullRequest': symbol: D 'tasks_for == "action" || tasks_for == "pr-action"': groupName: 'action-callback' groupSymbol: AC symbol: "${action.symbol}" $default: groupSymbol: cron symbol: "${cron.job_symbol}" - $if: 'tasks_for == "action" || tasks_for == "pr-action"' then: parent: '${action.taskGroupId}' action: name: '${action.name}' context: taskGroupId: '${action.taskGroupId}' taskId: {$eval: 'taskId'} input: {$eval: 'input'} clientId: {$eval: 'clientId'} - $if: 'tasks_for == "cron"' then: cron: {$json: {$eval: 'cron'}} - tasks_for: '${tasks_for}'