1- use std:: collections:: HashMap ;
2- use std:: path:: Path ;
1+ use std:: collections:: BTreeMap ;
2+ use std:: path:: { Path , PathBuf } ;
33use std:: process:: Command ;
44
55use anyhow:: Context ;
@@ -17,13 +17,13 @@ struct Job {
1717 name : String ,
1818 /// GitHub runner on which the job should be executed
1919 os : String ,
20- env : HashMap < String , Value > ,
20+ env : BTreeMap < String , Value > ,
2121 /// Should the job be only executed on a specific channel?
2222 #[ serde( default ) ]
2323 only_on_channel : Option < String > ,
2424 /// Rest of attributes that will be passed through to GitHub actions
2525 #[ serde( flatten) ]
26- extra_keys : HashMap < String , Value > ,
26+ extra_keys : BTreeMap < String , Value > ,
2727}
2828
2929impl Job {
@@ -44,11 +44,11 @@ impl Job {
4444#[ derive( serde:: Deserialize , Debug ) ]
4545struct JobEnvironments {
4646 #[ serde( rename = "pr" ) ]
47- pr_env : HashMap < String , Value > ,
47+ pr_env : BTreeMap < String , Value > ,
4848 #[ serde( rename = "try" ) ]
49- try_env : HashMap < String , Value > ,
49+ try_env : BTreeMap < String , Value > ,
5050 #[ serde( rename = "auto" ) ]
51- auto_env : HashMap < String , Value > ,
51+ auto_env : BTreeMap < String , Value > ,
5252}
5353
5454#[ derive( serde:: Deserialize , Debug ) ]
@@ -71,7 +71,7 @@ impl JobDatabase {
7171}
7272
7373fn load_job_db ( path : & Path ) -> anyhow:: Result < JobDatabase > {
74- let db = std :: fs :: read_to_string ( path) ?;
74+ let db = read_to_string ( path) ?;
7575 let mut db: Value = serde_yaml:: from_str ( & db) ?;
7676
7777 // We need to expand merge keys (<<), because serde_yaml can't deal with them
@@ -92,9 +92,9 @@ struct GithubActionsJob {
9292 /// prefix (PR/try/auto).
9393 full_name : String ,
9494 os : String ,
95- env : HashMap < String , String > ,
95+ env : BTreeMap < String , String > ,
9696 #[ serde( flatten) ]
97- extra_keys : HashMap < String , serde_json:: Value > ,
97+ extra_keys : BTreeMap < String , serde_json:: Value > ,
9898}
9999
100100/// Type of workflow that is being executed on CI
@@ -116,27 +116,17 @@ struct GitHubContext {
116116
117117impl GitHubContext {
118118 fn get_run_type ( & self ) -> Option < RunType > {
119- if self . event_name == "pull_request" {
120- return Some ( RunType :: PullRequest ) ;
121- } else if self . event_name == "push" {
122- let is_try_build =
123- [ "refs/heads/try" , "refs/heads/try-perf" , "refs/heads/automation/bors/try" ]
124- . iter ( )
125- . any ( |r| * * r == self . branch_ref ) ;
126- // Unrolled branch from a rollup for testing perf
127- // This should **not** allow custom try jobs
128- let is_unrolled_perf_build = self . branch_ref == "refs/heads/try-perf" ;
129- if is_try_build {
130- let custom_jobs =
131- if !is_unrolled_perf_build { Some ( self . get_custom_jobs ( ) ) } else { None } ;
132- return Some ( RunType :: TryJob { custom_jobs } ) ;
133- }
134-
135- if self . branch_ref == "refs/heads/auto" {
136- return Some ( RunType :: AutoJob ) ;
119+ match ( self . event_name . as_str ( ) , self . branch_ref . as_str ( ) ) {
120+ ( "pull_request" , _) => Some ( RunType :: PullRequest ) ,
121+ ( "push" , "refs/heads/try-perf" ) => Some ( RunType :: TryJob { custom_jobs : None } ) ,
122+ ( "push" , "refs/heads/try" | "refs/heads/automation/bors/try" ) => {
123+ let custom_jobs = self . get_custom_jobs ( ) ;
124+ let custom_jobs = if !custom_jobs. is_empty ( ) { Some ( custom_jobs) } else { None } ;
125+ Some ( RunType :: TryJob { custom_jobs } )
137126 }
127+ ( "push" , "refs/heads/auto" ) => Some ( RunType :: AutoJob ) ,
128+ _ => None ,
138129 }
139- None
140130 }
141131
142132 /// Tries to parse names of specific CI jobs that should be executed in the form of
@@ -175,7 +165,7 @@ fn skip_jobs(jobs: Vec<Job>, channel: &str) -> Vec<Job> {
175165 . collect ( )
176166}
177167
178- fn to_string_map ( map : & HashMap < String , Value > ) -> HashMap < String , String > {
168+ fn to_string_map ( map : & BTreeMap < String , Value > ) -> BTreeMap < String , String > {
179169 map. iter ( )
180170 . map ( |( key, value) | {
181171 (
@@ -232,7 +222,7 @@ fn calculate_jobs(
232222 let jobs = jobs
233223 . into_iter ( )
234224 . map ( |job| {
235- let mut env: HashMap < String , String > = to_string_map ( base_env) ;
225+ let mut env: BTreeMap < String , String > = to_string_map ( base_env) ;
236226 env. extend ( to_string_map ( & job. env ) ) ;
237227 let full_name = format ! ( "{prefix} - {}" , job. name) ;
238228
@@ -312,9 +302,9 @@ fn run_workflow_locally(db: JobDatabase, job_type: JobType, name: String) -> any
312302 JobType :: Auto => & db. auto_jobs ,
313303 JobType :: PR => & db. pr_jobs ,
314304 } ;
315- let job = find_linux_job ( & jobs, & name) . with_context ( || format ! ( "Cannot find job {name}" ) ) ?;
305+ let job = find_linux_job ( jobs, & name) . with_context ( || format ! ( "Cannot find job {name}" ) ) ?;
316306
317- let mut custom_env: HashMap < String , String > = HashMap :: new ( ) ;
307+ let mut custom_env: BTreeMap < String , String > = BTreeMap :: new ( ) ;
318308 // Replicate src/ci/scripts/setup-environment.sh
319309 // Adds custom environment variables to the job
320310 if name. starts_with ( "dist-" ) {
@@ -340,7 +330,10 @@ fn run_workflow_locally(db: JobDatabase, job_type: JobType, name: String) -> any
340330enum Args {
341331 /// Calculate a list of jobs that should be executed on CI.
342332 /// Should only be used on CI inside GitHub actions.
343- CalculateJobMatrix ,
333+ CalculateJobMatrix {
334+ #[ clap( long) ]
335+ jobs_file : Option < PathBuf > ,
336+ } ,
344337 /// Execute a given CI job locally.
345338 #[ clap( name = "run-local" ) ]
346339 RunJobLocally {
@@ -362,19 +355,29 @@ enum JobType {
362355
363356fn main ( ) -> anyhow:: Result < ( ) > {
364357 let args = Args :: parse ( ) ;
365- let db = load_job_db ( Path :: new ( JOBS_YML_PATH ) ) . context ( "Cannot load jobs.yml" ) ?;
358+ let default_jobs_file = Path :: new ( JOBS_YML_PATH ) ;
359+ let load_db = |jobs_path| load_job_db ( jobs_path) . context ( "Cannot load jobs.yml" ) ;
366360
367361 match args {
368- Args :: CalculateJobMatrix => {
362+ Args :: CalculateJobMatrix { jobs_file } => {
363+ let jobs_path = jobs_file. as_deref ( ) . unwrap_or ( default_jobs_file) ;
369364 let gh_ctx = load_github_ctx ( )
370365 . context ( "Cannot load environment variables from GitHub Actions" ) ?;
371- let channel = std :: fs :: read_to_string ( Path :: new ( CI_DIRECTORY ) . join ( "channel" ) )
366+ let channel = read_to_string ( Path :: new ( CI_DIRECTORY ) . join ( "channel" ) )
372367 . context ( "Cannot read channel file" ) ?;
373368
374- calculate_job_matrix ( db, gh_ctx, & channel) . context ( "Failed to calculate job matrix" ) ?;
369+ calculate_job_matrix ( load_db ( jobs_path) ?, gh_ctx, & channel)
370+ . context ( "Failed to calculate job matrix" ) ?;
371+ }
372+ Args :: RunJobLocally { job_type, name } => {
373+ run_workflow_locally ( load_db ( default_jobs_file) ?, job_type, name) ?
375374 }
376- Args :: RunJobLocally { job_type, name } => run_workflow_locally ( db, job_type, name) ?,
377375 }
378376
379377 Ok ( ( ) )
380378}
379+
380+ fn read_to_string < P : AsRef < Path > > ( path : P ) -> anyhow:: Result < String > {
381+ let error = format ! ( "Cannot read file {:?}" , path. as_ref( ) ) ;
382+ std:: fs:: read_to_string ( path) . context ( error)
383+ }
0 commit comments