@@ -3,12 +3,15 @@ mod tests;
33
44use  std:: collections:: BTreeMap ; 
55
6+ use  anyhow:: Context  as  _; 
67use  serde_yaml:: Value ; 
78
89use  crate :: GitHubContext ; 
10+ use  crate :: utils:: load_env_var; 
911
1012/// Representation of a job loaded from the `src/ci/github-actions/jobs.yml` file. 
1113#[ derive( serde:: Deserialize ,  Debug ,  Clone ) ]  
14+ #[ serde( deny_unknown_fields) ]  
1215pub  struct  Job  { 
1316    /// Name of the job, e.g. mingw-check 
1417     pub  name :  String , 
@@ -26,6 +29,8 @@ pub struct Job {
2629    pub  free_disk :  Option < bool > , 
2730    /// Documentation link to a resource that could help people debug this CI job. 
2831     pub  doc_url :  Option < String > , 
32+     /// Whether the job is executed on AWS CodeBuild. 
33+      pub  codebuild :  Option < bool > , 
2934} 
3035
3136impl  Job  { 
@@ -80,7 +85,7 @@ impl JobDatabase {
8085} 
8186
8287pub  fn  load_job_db ( db :  & str )  -> anyhow:: Result < JobDatabase >  { 
83-     let  mut  db:  Value  = serde_yaml:: from_str ( & db) ?; 
88+     let  mut  db:  Value  = serde_yaml:: from_str ( db) ?; 
8489
8590    // We need to expand merge keys (<<), because serde_yaml can't deal with them 
8691    // `apply_merge` only applies the merge once, so do it a few times to unwrap nested merges. 
@@ -107,6 +112,29 @@ struct GithubActionsJob {
107112    free_disk :  Option < bool > , 
108113    #[ serde( skip_serializing_if = "Option::is_none" ) ]  
109114    doc_url :  Option < String > , 
115+     #[ serde( skip_serializing_if = "Option::is_none" ) ]  
116+     codebuild :  Option < bool > , 
117+ } 
118+ 
119+ /// Replace GitHub context variables with environment variables in job configs. 
120+ /// Used for codebuild jobs like 
121+ /// `codebuild-ubuntu-22-8c-$github.run_id-$github.run_attempt` 
122+ fn  substitute_github_vars ( jobs :  Vec < Job > )  -> anyhow:: Result < Vec < Job > >  { 
123+     let  run_id = load_env_var ( "GITHUB_RUN_ID" ) ?; 
124+     let  run_attempt = load_env_var ( "GITHUB_RUN_ATTEMPT" ) ?; 
125+ 
126+     let  jobs = jobs
127+         . into_iter ( ) 
128+         . map ( |mut  job| { 
129+             job. os  = job
130+                 . os 
131+                 . replace ( "$github.run_id" ,  & run_id) 
132+                 . replace ( "$github.run_attempt" ,  & run_attempt) ; 
133+             job
134+         } ) 
135+         . collect ( ) ; 
136+ 
137+     Ok ( jobs) 
110138} 
111139
112140/// Skip CI jobs that are not supposed to be executed on the given `channel`. 
@@ -177,6 +205,8 @@ fn calculate_jobs(
177205        } 
178206        RunType :: AutoJob  => ( db. auto_jobs . clone ( ) ,  "auto" ,  & db. envs . auto_env ) , 
179207    } ; 
208+     let  jobs = substitute_github_vars ( jobs. clone ( ) ) 
209+         . context ( "Failed to substitute GitHub context variables in jobs" ) ?; 
180210    let  jobs = skip_jobs ( jobs,  channel) ; 
181211    let  jobs = jobs
182212        . into_iter ( ) 
@@ -207,6 +237,7 @@ fn calculate_jobs(
207237                continue_on_error :  job. continue_on_error , 
208238                free_disk :  job. free_disk , 
209239                doc_url :  job. doc_url , 
240+                 codebuild :  job. codebuild , 
210241            } 
211242        } ) 
212243        . collect ( ) ; 
0 commit comments