---
version: 1
reporting: checks-v1
policy:
    # XXX We restrict taskcluster to collaborators so priviledged tests (like UI tests) can run on PRs
    pullRequests: collaborators
tasks:
    - $let:
        trustDomain: mobile

        # Github events have this stuff in different places...
        ownerEmail:
            $if: 'tasks_for in ["cron", "action"]'
            then: '${tasks_for}@noreply.mozilla.org'
            else:
                $if: 'tasks_for == "github-push"'
                then: '${event.pusher.email}'
                else:
                    $if: 'tasks_for == "github-pull-request"'
                    then: '${event.pull_request.user.login}@users.noreply.github.com'
        baseRepoUrl:
            $if: 'tasks_for == "github-push"'
            then: '${event.repository.html_url}'
            else:
                $if: 'tasks_for == "github-pull-request"'
                then: '${event.pull_request.base.repo.html_url}'
                else:
                    $if: 'tasks_for in ["cron", "action"]'
                    then: '${repository.url}'
        repoUrl:
            $if: 'tasks_for == "github-push"'
            then: '${event.repository.html_url}'
            else:
                $if: 'tasks_for == "github-pull-request"'
                then: '${event.pull_request.head.repo.html_url}'
                else:
                    $if: 'tasks_for in ["cron", "action"]'
                    then: '${repository.url}'
        project:
            $if: 'tasks_for == "github-push"'
            then: '${event.repository.name}'
            else:
                $if: 'tasks_for == "github-pull-request"'
                then: '${event.pull_request.head.repo.name}'
                else:
                    $if: 'tasks_for in ["cron", "action"]'
                    then: '${repository.project}'
        head_branch:
            $if: 'tasks_for == "github-pull-request"'
            then: ${event.pull_request.head.ref}
            else:
                $if: 'tasks_for == "github-push"'
                then: ${event.ref}
                else:
                    $if: 'tasks_for in ["action", "cron"]'
                    then: '${push.branch}'
        head_sha:
            $if: 'tasks_for == "github-push"'
            then: '${event.after}'
            else:
                $if: 'tasks_for == "github-pull-request"'
                then: '${event.pull_request.head.sha}'
                else:
                    $if: 'tasks_for in ["action", "cron"]'
                    then: '${push.revision}'
        ownTaskId:
            $if: '"github" in tasks_for'
            then: {$eval: as_slugid("decision_task")}
            else:
                $if: 'tasks_for in ["cron", "action"]'
                then: '${ownTaskId}'
        pullRequestAction:
            $if: 'tasks_for == "github-pull-request"'
            then: ${event.action}
            else: 'UNDEFINED'
      in:
        $if: >
            tasks_for in ["action", "cron"]
            || (tasks_for == "github-pull-request" && pullRequestAction in ["opened", "reopened", "synchronize"])
            || (tasks_for == "github-push" && head_branch[:10] != "refs/tags/") && (head_branch != "staging.tmp") && (head_branch != "trying.tmp") && (head_branch[:8] != "mergify/")
        then:
            $let:
                level:
                    $if: 'tasks_for in ["github-push", "action", "cron"] && repoUrl == "https://github.com/mozilla-mobile/fenix"'
                    then: '3'
                    else: '1'
                short_head_branch:
                    $if: 'head_branch[:11] == "refs/heads/"'
                    then: {$eval: 'head_branch[11:]'}
            in:
                taskId:
                    $if: 'tasks_for != "action"'
                    then: '${ownTaskId}'
                taskGroupId:
                    $if: 'tasks_for == "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, despite rounding errors
                metadata:
                    $merge:
                        - owner: "${ownerEmail}"
                          source: '${repoUrl}/raw/${head_sha}/.taskcluster.yml'
                        - $if: 'tasks_for in ["github-push", "github-pull-request"]'
                          then:
                            name: "Decision Task"
                            description: 'The task that creates all of the other tasks in the task graph'
                          else:
                            $if: 'tasks_for == "action"'
                            then:
                                name: "Action: ${action.title}"
                                description: |
                                    ${action.description}

                                    Action triggered by clientID `${clientId}`
                            else:
                                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:
                    $if: 'tasks_for in ["github-push", "github-pull-request"]'
                    then:
                        kind: decision-task
                    else:
                        $if: 'tasks_for == "action"'
                        then:
                            kind: 'action-callback'
                        else:
                            $if: 'tasks_for == "cron"'
                            then:
                                kind: cron-task
                routes:
                    $flattenDeep:
                        - checks
                        - $if: 'level == "3" || repoUrl == "https://github.com/mozilla-releng/staging-fenix"'
                          then:
                            - tc-treeherder.v2.${project}.${head_sha}
                            # TODO Bug 1601928: Make this scope fork-friendly once ${project} is better defined. This will enable
                            # staging release promotion on forks.
                        - $if: 'tasks_for == "github-push"'
                          then:
                            - index.${trustDomain}.v2.${project}.branch.${short_head_branch}.latest.taskgraph.decision
                            - index.${trustDomain}.v2.${project}.branch.${short_head_branch}.revision.${head_sha}.taskgraph.decision
                            - index.${trustDomain}.v2.${project}.revision.${head_sha}.taskgraph.decision
                        - $if: 'tasks_for == "cron"'
                          then:
                            # cron context provides ${head_branch} as a short one
                            - index.${trustDomain}.v2.${project}.branch.${head_branch}.latest.taskgraph.decision-${cron.job_name}
                            - index.${trustDomain}.v2.${project}.branch.${head_branch}.revision.${head_sha}.taskgraph.decision-${cron.job_name}
                            - index.${trustDomain}.v2.${project}.branch.${head_branch}.revision.${head_sha}.taskgraph.cron.${ownTaskId}
                scopes:
                    $if: 'tasks_for == "github-push"'
                    then:
                        # `https://` is 8 characters so, ${repoUrl[8:]} is the repository without the protocol.
                        - 'assume:repo:${repoUrl[8:]}:branch:${short_head_branch}'
                    else:
                        $if: 'tasks_for == "github-pull-request"'
                        then:
                            - 'assume:repo:github.com/${event.pull_request.base.repo.full_name}:pull-request'
                        else:
                            $if: 'tasks_for == "action"'
                            then:
                                # when all actions are hooks, we can calculate this directly rather than using a variable
                                - '${action.repo_scope}'
                            else:
                                - 'assume:repo:${repoUrl[8:]}:cron:${cron.job_name}'

                requires: all-completed
                priority: lowest
                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:
                            - MOBILE_BASE_REPOSITORY: '${baseRepoUrl}'
                              MOBILE_HEAD_REPOSITORY: '${repoUrl}'
                              MOBILE_HEAD_REF: '${head_branch}'
                              MOBILE_HEAD_REV: '${head_sha}'
                              MOBILE_REPOSITORY_TYPE: git
                              MOBILE_PIP_REQUIREMENTS: taskcluster/requirements.txt
                              MOZ_AUTOMATION: "1"
                              REPOSITORIES: {$json: {mobile: "Fenix"}}
                              HG_STORE_PATH: /builds/worker/checkouts/hg-store
                              ANDROID_SDK_ROOT: /builds/worker/android-sdk
                            - $if: 'tasks_for in ["github-pull-request"]'
                              then:
                                MOBILE_PULL_REQUEST_NUMBER: '${event.pull_request.number}'
                            - $if: 'tasks_for == "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}'
                    features:
                        taskclusterProxy: true
                        chainOfTrust: true
                        # Note: This task is built server side without the context or tooling that
                        # exist in tree so we must hard code the hash
                    image: mozillareleases/taskgraph:decision-mobile-625975b642c148be4c6f1d8ee5cedf7399f5d0dd33d275ff69d5934e3082d4a9@sha256:bfb26700182486e1c6c52701baea6f386fa39e5e25417423c27845933605ad43

                    maxRunTime: 1800

                    command:
                        - /usr/local/bin/run-task
                        - '--mobile-checkout=/builds/worker/checkouts/src'
                        - '--task-cwd=/builds/worker/checkouts/src'
                        - '--'
                        - bash
                        - -cx
                        - $let:
                            extraArgs:
                                $if: 'tasks_for == "cron"'
                                then: '${cron.quoted_args}'
                                else: ''
                          in:
                            $if: 'tasks_for == "action"'
                            then: >
                                taskcluster/scripts/decision-install-sdk.sh &&
                                ln -s /builds/worker/artifacts artifacts &&
                                ~/.local/bin/taskgraph action-callback
                            else: >
                                taskcluster/scripts/decision-install-sdk.sh &&
                                ln -s /builds/worker/artifacts artifacts &&
                                ~/.local/bin/taskgraph decision
                                --pushlog-id='0'
                                --pushdate='0'
                                --project='${project}'
                                --message=""
                                --owner='${ownerEmail}'
                                --level='${level}'
                                --base-repository="$MOBILE_BASE_REPOSITORY"
                                --head-repository="$MOBILE_HEAD_REPOSITORY"
                                --head-ref="$MOBILE_HEAD_REF"
                                --head-rev="$MOBILE_HEAD_REV"
                                --repository-type="$MOBILE_REPOSITORY_TYPE"
                                --tasks-for='${tasks_for}'
                                ${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
                                - $if: 'tasks_for in ["github-push", "github-pull-request"]'
                                  then:
                                    symbol: D
                                  else:
                                    $if: 'tasks_for == "action"'
                                    then:
                                        groupName: 'action-callback'
                                        groupSymbol: AC
                                        symbol: "${action.symbol}"
                                    else:
                                        groupSymbol: cron
                                        symbol: "${cron.job_symbol}"
                        - $if: 'tasks_for == "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}'
