Skip to content

Commit 21a5e27

Browse files
committed
ci: verify that codebuild jobs use ghcr.io
1 parent d76fe15 commit 21a5e27

File tree

2 files changed

+49
-3
lines changed

2 files changed

+49
-3
lines changed

src/ci/citool/src/jobs.rs

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
mod tests;
33

44
use std::collections::BTreeMap;
5+
use std::path::Path;
56

67
use anyhow::Context as _;
78
use serde_yaml::Value;
89

9-
use crate::GitHubContext;
10-
use crate::utils::load_env_var;
10+
use crate::utils::{self, load_env_var};
11+
use crate::{DOCKER_DIRECTORY, GitHubContext};
1112

1213
/// Representation of a job loaded from the `src/ci/github-actions/jobs.yml` file.
1314
#[derive(serde::Deserialize, Debug, Clone)]
@@ -46,6 +47,47 @@ impl Job {
4647
fn is_linux(&self) -> bool {
4748
self.os.contains("ubuntu")
4849
}
50+
51+
/// Validate that CodeBuild jobs use Docker images from ghcr.io registry.
52+
/// This is needed because otherwise from CodeBuild we get rate limited by Docker Hub.
53+
fn validate_codebuild_image(&self) -> anyhow::Result<()> {
54+
let is_job_on_codebuild = self.codebuild.unwrap_or(false);
55+
if !is_job_on_codebuild {
56+
// Jobs in GitHub Actions don't get rate limited by Docker Hub.
57+
return Ok(());
58+
}
59+
60+
let image_name = self.image();
61+
// we hardcode host-x86_64 here, because in codebuild we only run jobs for this architecture.
62+
let dockerfile_path =
63+
Path::new(DOCKER_DIRECTORY).join("host-x86_64").join(&image_name).join("Dockerfile");
64+
65+
if !dockerfile_path.exists() {
66+
return Err(anyhow::anyhow!(
67+
"Dockerfile not found for CodeBuild job '{}' at path: {}",
68+
self.name,
69+
dockerfile_path.display()
70+
));
71+
}
72+
73+
let dockerfile_content = utils::read_to_string(&dockerfile_path)?;
74+
75+
// Check if all FROM statement uses ghcr.io registry
76+
let has_ghcr_from = dockerfile_content
77+
.lines()
78+
.filter(|line| line.trim_start().to_lowercase().starts_with("from "))
79+
.all(|line| line.contains("ghcr.io"));
80+
81+
if !has_ghcr_from {
82+
return Err(anyhow::anyhow!(
83+
"CodeBuild job '{}' must use ghcr.io registry in its Dockerfile FROM statement. \
84+
Dockerfile path: {dockerfile_path:?}",
85+
self.name,
86+
));
87+
}
88+
89+
Ok(())
90+
}
4991
}
5092

5193
#[derive(serde::Deserialize, Debug)]
@@ -214,6 +256,10 @@ fn calculate_jobs(
214256
let jobs = substitute_github_vars(jobs.clone())
215257
.context("Failed to substitute GitHub context variables in jobs")?;
216258
let jobs = skip_jobs(jobs, channel);
259+
for j in &jobs {
260+
j.validate_codebuild_image()
261+
.context(format!("Failed to validate CodeBuild job '{}'", j.name))?;
262+
}
217263
let jobs = jobs
218264
.into_iter()
219265
.map(|job| {

src/ci/citool/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use crate::test_dashboard::generate_test_dashboard;
2727
use crate::utils::{load_env_var, output_details};
2828

2929
const CI_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/..");
30-
const DOCKER_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../docker");
30+
pub const DOCKER_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../docker");
3131
const JOBS_YML_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../github-actions/jobs.yml");
3232

3333
struct GitHubContext {

0 commit comments

Comments
 (0)