8
8
and filters them based on the event that happened on CI.
9
9
"""
10
10
import dataclasses
11
- import enum
12
11
import json
13
12
import logging
14
13
import os
14
+ import re
15
+ import typing
15
16
from pathlib import Path
16
17
from typing import List , Dict , Any , Optional
17
18
@@ -44,22 +45,51 @@ def add_base_env(jobs: List[Job], environment: Dict[str, str]) -> List[Job]:
44
45
return jobs
45
46
46
47
47
- class WorkflowRunType (enum .Enum ):
48
- PR = enum .auto ()
49
- Try = enum .auto ()
50
- Auto = enum .auto ()
48
+ @dataclasses .dataclass
49
+ class PRRunType :
50
+ pass
51
+
52
+
53
+ @dataclasses .dataclass
54
+ class TryRunType :
55
+ custom_jobs : List [str ]
56
+
57
+
58
+ @dataclasses .dataclass
59
+ class AutoRunType :
60
+ pass
61
+
62
+
63
+ WorkflowRunType = typing .Union [PRRunType , TryRunType , AutoRunType ]
51
64
52
65
53
66
@dataclasses .dataclass
54
67
class GitHubCtx :
55
68
event_name : str
56
69
ref : str
57
70
repository : str
71
+ commit_message : Optional [str ]
72
+
73
+
74
+ def get_custom_jobs (ctx : GitHubCtx ) -> List [str ]:
75
+ """
76
+ Tries to parse names of specific CI jobs that should be executed in the form of
77
+ ci-job: <job-name>
78
+ from the commit message of the passed GitHub context.
79
+ """
80
+ if ctx .commit_message is None :
81
+ return []
82
+
83
+ regex = re .compile (r"ci-job: (.*)" )
84
+ jobs = []
85
+ for match in regex .finditer (ctx .commit_message ):
86
+ jobs .append (match .group (1 ))
87
+ return jobs
58
88
59
89
60
90
def find_run_type (ctx : GitHubCtx ) -> Optional [WorkflowRunType ]:
61
91
if ctx .event_name == "pull_request" :
62
- return WorkflowRunType . PR
92
+ return PRRunType ()
63
93
elif ctx .event_name == "push" :
64
94
old_bors_try_build = (
65
95
ctx .ref in ("refs/heads/try" , "refs/heads/try-perf" ) and
@@ -72,20 +102,37 @@ def find_run_type(ctx: GitHubCtx) -> Optional[WorkflowRunType]:
72
102
try_build = old_bors_try_build or new_bors_try_build
73
103
74
104
if try_build :
75
- return WorkflowRunType .Try
105
+ jobs = get_custom_jobs (ctx )
106
+ return TryRunType (custom_jobs = jobs )
76
107
77
108
if ctx .ref == "refs/heads/auto" and ctx .repository == "rust-lang-ci/rust" :
78
- return WorkflowRunType . Auto
109
+ return AutoRunType ()
79
110
80
111
return None
81
112
82
113
83
114
def calculate_jobs (run_type : WorkflowRunType , job_data : Dict [str , Any ]) -> List [Job ]:
84
- if run_type == WorkflowRunType . PR :
115
+ if isinstance ( run_type , PRRunType ) :
85
116
return add_base_env (name_jobs (job_data ["pr" ], "PR" ), job_data ["envs" ]["pr" ])
86
- elif run_type == WorkflowRunType .Try :
87
- return add_base_env (name_jobs (job_data ["try" ], "try" ), job_data ["envs" ]["try" ])
88
- elif run_type == WorkflowRunType .Auto :
117
+ elif isinstance (run_type , TryRunType ):
118
+ jobs = job_data ["try" ]
119
+ custom_jobs = run_type .custom_jobs
120
+ if custom_jobs :
121
+ if len (custom_jobs ) > 10 :
122
+ raise Exception (
123
+ f"It is only possible to schedule up to 10 custom jobs,"
124
+ f"received { len (custom_jobs )} jobs"
125
+ )
126
+
127
+ jobs = []
128
+ for custom_job in custom_jobs :
129
+ job = [j for j in job_data ["auto" ] if j ["image" ] == custom_job ]
130
+ if not job :
131
+ raise Exception (f"Custom job `{ custom_job } ` not found in auto jobs" )
132
+ jobs .append (job [0 ])
133
+
134
+ return add_base_env (name_jobs (jobs , "try" ), job_data ["envs" ]["try" ])
135
+ elif run_type is AutoRunType :
89
136
return add_base_env (name_jobs (job_data ["auto" ], "auto" ), job_data ["envs" ]["auto" ])
90
137
91
138
return []
@@ -99,19 +146,25 @@ def skip_jobs(jobs: List[Dict[str, Any]], channel: str) -> List[Job]:
99
146
100
147
101
148
def get_github_ctx () -> GitHubCtx :
149
+ event_name = os .environ ["GITHUB_EVENT_NAME" ]
150
+
151
+ commit_message = None
152
+ if event_name == "push" :
153
+ commit_message = os .environ ["COMMIT_MESSAGE" ]
102
154
return GitHubCtx (
103
- event_name = os . environ [ "GITHUB_EVENT_NAME" ] ,
155
+ event_name = event_name ,
104
156
ref = os .environ ["GITHUB_REF" ],
105
- repository = os .environ ["GITHUB_REPOSITORY" ]
157
+ repository = os .environ ["GITHUB_REPOSITORY" ],
158
+ commit_message = commit_message
106
159
)
107
160
108
161
109
162
def format_run_type (run_type : WorkflowRunType ) -> str :
110
- if run_type == WorkflowRunType . PR :
163
+ if isinstance ( run_type , PRRunType ) :
111
164
return "pr"
112
- elif run_type == WorkflowRunType . Auto :
165
+ elif isinstance ( run_type , AutoRunType ) :
113
166
return "auto"
114
- elif run_type == WorkflowRunType . Try :
167
+ elif isinstance ( run_type , TryRunType ) :
115
168
return "try"
116
169
else :
117
170
raise AssertionError ()
0 commit comments