2 from dataclasses
import dataclass
3 from typing
import List, Dict, Any
4 from pathlib
import Path
13 from gidgethub.aiohttp
import GitHubAPI
19 def wrapper(*args, **kwargs):
20 return asyncio.run(fn(*args, **kwargs))
46 @run_experiment.command()
47 @click.option(
"--revert-sha",
"-r", multiple=
True)
50 async
def atlas(ctx: Context, revert_sha: List[str]):
51 gitlab_trigger_token = os.environ[
"GITLAB_TRIGGER_TOKEN"]
52 gitlab_trigger_url = os.environ[
"GITLAB_TRIGGER_URL"]
53 async with aiohttp.ClientSession()
as session:
54 gh = GitHubAPI(session,
"acts-commands", oauth_token=ctx.github_token)
58 head_clone_url = pr[
"head"][
"repo"][
"clone_url"]
59 head_branch = pr[
"head"][
"ref"]
60 head_sha = pr[
"head"][
"sha"]
62 variable_summary = f
"""
65 | `ACTS_GIT_REPO` | {head_clone_url} |
66 | `ACTS_REF` | `{head_branch}` |
67 | `SOURCE_SHA` | {head_sha} |
68 | `REVERT_SHAS` | {",".join(revert_sha)} |
73 🟡 I'm going to trigger an ATLAS experiment pipeline for you:
77 comment = await gh.post(pr[
"comments_url"], data={
"body": body})
80 "ACTS_GIT_REPO": head_clone_url,
81 "ACTS_REF": head_branch,
82 "SOURCE_SHA": head_sha,
84 "REVERT_SHAS":
",".
join(revert_sha),
85 "REPORT_COMMENT_URL": comment[
"url"],
88 "token": gitlab_trigger_token,
90 **{f
"variables[{k}]": v
for k, v
in variables.items()},
92 print(gitlab_trigger_url)
94 async with session.post(
95 url=gitlab_trigger_url,
98 if resp.status != 201:
101 🔴 I'm sorry, I couldn't run your command because of an error:
107 await gh.post(comment[
"url"], data={
"body": body})
111 data = await resp.json()
112 pipeline_url = data[
"web_url"]
116 🟡 I triggered an ATLAS experiment [pipeline]({pipeline_url}) for you
120 await gh.post(comment[
"url"], data={
"body": body})
124 allow_org, allow_team = allow_team.split(
"/", 1)
127 membership = await gh.getitem(
128 f
"/orgs/{allow_org}/teams/{allow_team}/memberships/{author}"
131 except gidgethub.BadRequest
as e:
132 if e.status_code != 404:
139 token: str, pr_url: str, sender: str, repository: str, allow_team: str
141 async with aiohttp.ClientSession()
as session:
142 gh = GitHubAPI(session,
"acts-commands", oauth_token=token)
145 raise RuntimeError(f
"{sender} is not in {allow_team}")
147 return await gh.getitem(pr_url)
150 async
def report_error(token: str, pr: Dict[str, Any], sender: str, error: Exception):
151 async with aiohttp.ClientSession()
as session:
152 gh = GitHubAPI(session,
"acts-commands", oauth_token=token)
156 🔴 I'm sorry, I couldn't run your command because of an error:
161 await gh.post(pr[
"comments_url"], data={
"body": body})
165 pr: str = typer.Option(),
166 body: str = typer.Option(),
167 sender: str = typer.Option(),
168 repository: str = typer.Option(),
169 allow_team: str = typer.Option(
"acts-project/ci-perms", envvar=
"ALLOW_TEAM"),
172 body = Path(body).read_text().strip()
174 if len(body.split(
"\n")) > 1:
175 raise typer.BadParameter(
"Body must be a single line")
177 if not body.startswith(
"/"):
178 raise typer.BadParameter(
"Body must start with a slash")
181 args = shlex.split(body)
183 token = os.environ[
"GITHUB_TOKEN"]
184 pr = asyncio.run(
preflight(token, pr, sender, repository, allow_team))
189 obj=
Context(pr=pr, github_token=token, sender=sender),
190 standalone_mode=
False,
192 except (CommandError, click.exceptions.ClickException)
as e: