@@ -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