Aode (lion)
8f37beb0b1
All checks were successful
continuous-integration/drone/push Build is passing
96 lines
2.6 KiB
Rust
96 lines
2.6 KiB
Rust
use crate::{
|
|
revision::Revision,
|
|
version::{LatestOrSemver, Version},
|
|
BuildDirective,
|
|
};
|
|
|
|
#[derive(Debug)]
|
|
enum DockerError {
|
|
NoTag,
|
|
}
|
|
|
|
#[derive(Debug, serde::Deserialize)]
|
|
struct TagResult {
|
|
name: String,
|
|
}
|
|
|
|
#[derive(Debug, serde::Deserialize)]
|
|
struct TagsResponse {
|
|
count: usize,
|
|
next: String,
|
|
results: Vec<TagResult>,
|
|
}
|
|
|
|
impl std::fmt::Display for DockerError {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
match self {
|
|
Self::NoTag => write!(f, "No tag found for query"),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl std::error::Error for DockerError {}
|
|
|
|
const CHECK_MAX: usize = 100;
|
|
|
|
#[tracing::instrument]
|
|
pub(crate) async fn check_dockerhub_image(
|
|
namespace: String,
|
|
repository: String,
|
|
regex: String,
|
|
prefix: Option<String>,
|
|
previous_revision: &Revision,
|
|
) -> color_eyre::eyre::Result<BuildDirective> {
|
|
let regex = regex::Regex::new(®ex)?;
|
|
|
|
let client = reqwest::Client::builder()
|
|
.user_agent("release-checker (+https://git.asonix.dog/asonix/release-checker)")
|
|
.build()?;
|
|
|
|
let images_url = format!("https://registry.hub.docker.com/v2/repositories/{}/{}/tags?currently_tagged=true,ordering=last_updated,status=active", namespace, repository);
|
|
let mut next_url = Some(images_url);
|
|
let mut checked = 0;
|
|
|
|
while let Some(next) = next_url {
|
|
let tags: TagsResponse = client.get(&next).send().await?.json().await?;
|
|
checked += tags.results.len();
|
|
|
|
next_url = if checked < tags.count.min(CHECK_MAX) {
|
|
Some(tags.next)
|
|
} else {
|
|
None
|
|
};
|
|
|
|
let opt = tags
|
|
.results
|
|
.into_iter()
|
|
.filter_map(|result| {
|
|
if let Some(matched) = regex.find(&result.name) {
|
|
if matched.as_str() == result.name {
|
|
let trimmed = if let Some(prefix) = prefix.as_deref() {
|
|
result.name.trim_start_matches(prefix)
|
|
} else {
|
|
&result.name
|
|
};
|
|
|
|
return Some(Version::parse_from(trimmed));
|
|
}
|
|
}
|
|
|
|
None
|
|
})
|
|
.latest_or_semver(None);
|
|
|
|
if let Some(version) = opt {
|
|
// Bail if newest published version is the same as our most recent build
|
|
if version <= previous_revision.version {
|
|
return Ok(BuildDirective::ShouldIgnore);
|
|
}
|
|
|
|
return Ok(BuildDirective::ShouldBuild(Some(version)));
|
|
}
|
|
}
|
|
|
|
Err(DockerError::NoTag.into())
|
|
}
|