ci: verify that codebuild jobs use ghcr.io

This commit is contained in:
MarcoIeni 2025-05-28 10:23:38 +02:00
parent 642e49bfed
commit bf52d1a803
No known key found for this signature in database
2 changed files with 67 additions and 1 deletions

View file

@ -1,4 +1,8 @@
use std::path::Path;
use super::Job;
use crate::jobs::{JobDatabase, load_job_db};
use crate::{DOCKER_DIRECTORY, JOBS_YML_PATH, utils};
#[test]
fn lookup_job_pattern() {
@ -62,3 +66,65 @@ fn check_pattern(db: &JobDatabase, pattern: &str, expected: &[&str]) {
assert_eq!(jobs, expected);
}
/// Validate that CodeBuild jobs use Docker images from ghcr.io registry.
/// This is needed because otherwise from CodeBuild we get rate limited by Docker Hub.
fn validate_codebuild_image(job: &Job) -> anyhow::Result<()> {
let is_job_on_codebuild = job.codebuild.unwrap_or(false);
if !is_job_on_codebuild {
// Jobs in GitHub Actions don't get rate limited by Docker Hub.
return Ok(());
}
let image_name = job.image();
// we hardcode host-x86_64 here, because in codebuild we only run jobs for this architecture.
let dockerfile_path =
Path::new(DOCKER_DIRECTORY).join("host-x86_64").join(&image_name).join("Dockerfile");
if !dockerfile_path.exists() {
return Err(anyhow::anyhow!(
"Dockerfile not found for CodeBuild job '{}' at path: {}",
job.name,
dockerfile_path.display()
));
}
let dockerfile_content = utils::read_to_string(&dockerfile_path)?;
// Check if all FROM statement uses ghcr.io registry
let has_ghcr_from = dockerfile_content
.lines()
.filter(|line| line.trim_start().to_lowercase().starts_with("from "))
.all(|line| line.contains("ghcr.io"));
if !has_ghcr_from {
return Err(anyhow::anyhow!(
"CodeBuild job '{}' must use ghcr.io registry in its Dockerfile FROM statement. \
Dockerfile path: {dockerfile_path:?}",
job.name,
));
}
Ok(())
}
#[test]
fn validate_jobs() {
let db = {
let default_jobs_file = Path::new(JOBS_YML_PATH);
let db_str = utils::read_to_string(default_jobs_file).unwrap();
load_job_db(&db_str).expect("Failed to load job database")
};
let all_jobs =
db.pr_jobs.iter().chain(db.try_jobs.iter()).chain(db.auto_jobs.iter()).collect::<Vec<_>>();
let errors: Vec<anyhow::Error> =
all_jobs.into_iter().filter_map(|job| validate_codebuild_image(job).err()).collect();
if !errors.is_empty() {
let error_messages =
errors.into_iter().map(|e| format!("- {e}")).collect::<Vec<_>>().join("\n");
panic!("Job validation failed:\n{error_messages}");
}
}

View file

@ -27,7 +27,7 @@ use crate::test_dashboard::generate_test_dashboard;
use crate::utils::{load_env_var, output_details};
const CI_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/..");
const DOCKER_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../docker");
pub const DOCKER_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../docker");
const JOBS_YML_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../github-actions/jobs.yml");
struct GitHubContext {