summaryrefslogtreecommitdiff
path: root/buildscripts/evergreen_activate_gen_tasks.py
blob: 5c20b285e6b1dc247a10a7a574026fe280b81321 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#!/usr/bin/env python3
"""Activate an evergreen task in the existing build."""
import os
import sys
from typing import List, Optional

import click
import structlog
from pydantic.main import BaseModel

from evergreen.api import EvergreenApi, RetryingEvergreenApi

# Get relative imports to work when the package is not installed on the PYTHONPATH.
if __name__ == "__main__" and __package__ is None:
    sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

# pylint: disable=wrong-import-position
from buildscripts.util.cmdutils import enable_logging
from buildscripts.util.fileops import read_yaml_file
from buildscripts.util.taskname import remove_gen_suffix

# pylint: enable=wrong-import-position

LOGGER = structlog.getLogger(__name__)

EVG_CONFIG_FILE = "./.evergreen.yml"
BURN_IN_TAGS = "burn_in_tags"
BURN_IN_TESTS = "burn_in_tests"


class EvgExpansions(BaseModel):
    """
    Evergreen expansions file contents.

    build_id: ID of build being run.
    version_id: ID of version being run.
    task_name: Name of task creating the generated configuration.
    burn_in_tag_buildvariants: Buildvariants to run burn_in_tags on.
    """

    build_id: str
    version_id: str
    task_name: str
    burn_in_tag_buildvariants: Optional[str] = None

    @classmethod
    def from_yaml_file(cls, path: str) -> "EvgExpansions":
        """Read the generation configuration from the given file."""
        return cls(**read_yaml_file(path))

    @property
    def task(self) -> str:
        """Get the task being generated."""
        return remove_gen_suffix(self.task_name)

    @property
    def burn_in_tag_buildvariants_list(self) -> List[str]:
        """Get the list of burn_in_tags buildvariants."""
        if self.burn_in_tag_buildvariants is None:
            return []
        return self.burn_in_tag_buildvariants.split()


def activate_task(expansions: EvgExpansions, evg_api: EvergreenApi) -> None:
    """
    Activate the given task in the specified build.

    :param expansions: Evergreen expansions file contents.
    :param evg_api: Evergreen API client.
    """
    if expansions.task == BURN_IN_TAGS:
        version = evg_api.version_by_id(expansions.version_id)
        for base_build_variant in expansions.burn_in_tag_buildvariants_list:
            build_variant = f"{base_build_variant}-required"
            try:
                build_id = version.build_variants_map[build_variant]
            except KeyError:
                LOGGER.warning(
                    "It is likely nothing to burn_in, so burn_in_tags build variant"
                    " was not generated. Skipping...", build_variant=build_variant)
                continue

            task_list = evg_api.tasks_by_build(build_id)

            for task in task_list:
                if task.display_name == BURN_IN_TESTS:
                    LOGGER.info("Activating task", task_id=task.task_id,
                                task_name=task.display_name)
                    evg_api.configure_task(task.task_id, activated=True)

    else:
        task_list = evg_api.tasks_by_build(expansions.build_id)
        for task in task_list:
            if task.display_name == expansions.task:
                LOGGER.info("Activating task", task_id=task.task_id, task_name=task.display_name)
                evg_api.configure_task(task.task_id, activated=True)


@click.command()
@click.option("--expansion-file", type=str, required=True,
              help="Location of expansions file generated by evergreen.")
@click.option("--evergreen-config", type=str, default=EVG_CONFIG_FILE,
              help="Location of evergreen configuration file.")
@click.option("--verbose", is_flag=True, default=False, help="Enable verbose logging.")
def main(expansion_file: str, evergreen_config: str, verbose: bool) -> None:
    """
    Activate the associated generated executions based in the running build.

    The `--expansion-file` should contain all the configuration needed to generate the tasks.
    \f
    :param expansion_file: Configuration file.
    :param evergreen_config: Evergreen configuration file.
    :param verbose: Use verbose logging.
    """
    enable_logging(verbose)
    expansions = EvgExpansions.from_yaml_file(expansion_file)
    evg_api = RetryingEvergreenApi.get_api(config_file=evergreen_config)

    activate_task(expansions, evg_api)


if __name__ == "__main__":
    main()  # pylint: disable=no-value-for-parameter