xref: /aosp_15_r20/external/grpc-grpc/tools/run_tests/artifacts/package_targets.py (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1#!/usr/bin/env python3
2# Copyright 2016 gRPC authors.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#     http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15"""Definition of targets to build distribution packages."""
16
17import os.path
18import sys
19
20sys.path.insert(0, os.path.abspath(".."))
21import python_utils.jobset as jobset
22
23
24def create_docker_jobspec(
25    name,
26    dockerfile_dir,
27    shell_command,
28    environ={},
29    flake_retries=0,
30    timeout_retries=0,
31):
32    """Creates jobspec for a task running under docker."""
33    environ = environ.copy()
34
35    docker_args = []
36    for k, v in list(environ.items()):
37        docker_args += ["-e", "%s=%s" % (k, v)]
38    docker_env = {
39        "DOCKERFILE_DIR": dockerfile_dir,
40        "DOCKER_RUN_SCRIPT": "tools/run_tests/dockerize/docker_run.sh",
41        "DOCKER_RUN_SCRIPT_COMMAND": shell_command,
42        "OUTPUT_DIR": "artifacts",
43    }
44    jobspec = jobset.JobSpec(
45        cmdline=["tools/run_tests/dockerize/build_and_run_docker.sh"]
46        + docker_args,
47        environ=docker_env,
48        shortname="build_package.%s" % (name),
49        timeout_seconds=30 * 60,
50        flake_retries=flake_retries,
51        timeout_retries=timeout_retries,
52    )
53    return jobspec
54
55
56def create_jobspec(
57    name,
58    cmdline,
59    environ=None,
60    cwd=None,
61    shell=False,
62    flake_retries=0,
63    timeout_retries=0,
64    cpu_cost=1.0,
65):
66    """Creates jobspec."""
67    jobspec = jobset.JobSpec(
68        cmdline=cmdline,
69        environ=environ,
70        cwd=cwd,
71        shortname="build_package.%s" % (name),
72        timeout_seconds=10 * 60,
73        flake_retries=flake_retries,
74        timeout_retries=timeout_retries,
75        cpu_cost=cpu_cost,
76        shell=shell,
77    )
78    return jobspec
79
80
81class CSharpPackage:
82    """Builds C# packages."""
83
84    def __init__(self, platform):
85        self.platform = platform
86        self.labels = ["package", "csharp", self.platform]
87        self.name = "csharp_package_nuget_%s" % self.platform
88        self.labels += ["nuget"]
89
90    def pre_build_jobspecs(self):
91        return []
92
93    def build_jobspec(self, inner_jobs=None):
94        del inner_jobs  # arg unused as there is little opportunity for parallelizing
95        environ = {
96            "GRPC_CSHARP_BUILD_SINGLE_PLATFORM_NUGET": os.getenv(
97                "GRPC_CSHARP_BUILD_SINGLE_PLATFORM_NUGET", ""
98            )
99        }
100
101        build_script = "src/csharp/build_nuget.sh"
102
103        if self.platform == "linux":
104            return create_docker_jobspec(
105                self.name,
106                "tools/dockerfile/test/csharp_debian11_x64",
107                build_script,
108                environ=environ,
109            )
110        else:
111            repo_root = os.path.join(
112                os.path.dirname(os.path.abspath(__file__)), "..", "..", ".."
113            )
114            environ["EXTERNAL_GIT_ROOT"] = repo_root
115            return create_jobspec(
116                self.name, ["bash", build_script], environ=environ
117            )
118
119    def __str__(self):
120        return self.name
121
122
123class RubyPackage:
124    """Collects ruby gems created in the artifact phase"""
125
126    def __init__(self):
127        self.name = "ruby_package"
128        self.labels = ["package", "ruby", "linux"]
129
130    def pre_build_jobspecs(self):
131        return []
132
133    def build_jobspec(self, inner_jobs=None):
134        del inner_jobs  # arg unused as this step simply collects preexisting artifacts
135        return create_docker_jobspec(
136            self.name,
137            "tools/dockerfile/grpc_artifact_centos6_x64",
138            "tools/run_tests/artifacts/build_package_ruby.sh",
139        )
140
141
142class PythonPackage:
143    """Collects python eggs and wheels created in the artifact phase"""
144
145    def __init__(self):
146        self.name = "python_package"
147        self.labels = ["package", "python", "linux"]
148
149    def pre_build_jobspecs(self):
150        return []
151
152    def build_jobspec(self, inner_jobs=None):
153        del inner_jobs  # arg unused as this step simply collects preexisting artifacts
154        # since the python package build does very little, we can use virtually
155        # any image that has new-enough python, so reusing one of the images used
156        # for artifact building seems natural.
157        return create_docker_jobspec(
158            self.name,
159            "tools/dockerfile/grpc_artifact_python_manylinux2014_x64",
160            "tools/run_tests/artifacts/build_package_python.sh",
161            environ={"PYTHON": "/opt/python/cp39-cp39/bin/python"},
162        )
163
164
165class PHPPackage:
166    """Copy PHP PECL package artifact"""
167
168    def __init__(self):
169        self.name = "php_package"
170        self.labels = ["package", "php", "linux"]
171
172    def pre_build_jobspecs(self):
173        return []
174
175    def build_jobspec(self, inner_jobs=None):
176        del inner_jobs  # arg unused as this step simply collects preexisting artifacts
177        return create_docker_jobspec(
178            self.name,
179            "tools/dockerfile/grpc_artifact_centos6_x64",
180            "tools/run_tests/artifacts/build_package_php.sh",
181        )
182
183
184def targets():
185    """Gets list of supported targets"""
186    return [
187        CSharpPackage("linux"),
188        CSharpPackage("macos"),
189        CSharpPackage("windows"),
190        RubyPackage(),
191        PythonPackage(),
192        PHPPackage(),
193    ]
194