Add dockerhub pagination up to 100 tags
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Aode (lion) 2022-01-28 09:55:51 -06:00
parent 78f0011f73
commit 8f37beb0b1

View file

@ -9,13 +9,15 @@ enum DockerError {
NoTag,
}
#[derive(serde::Deserialize)]
#[derive(Debug, serde::Deserialize)]
struct TagResult {
name: String,
}
#[derive(serde::Deserialize)]
#[derive(Debug, serde::Deserialize)]
struct TagsResponse {
count: usize,
next: String,
results: Vec<TagResult>,
}
@ -29,6 +31,8 @@ impl std::fmt::Display for DockerError {
impl std::error::Error for DockerError {}
const CHECK_MAX: usize = 100;
#[tracing::instrument]
pub(crate) async fn check_dockerhub_image(
namespace: String,
@ -43,36 +47,48 @@ pub(crate) async fn check_dockerhub_image(
.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,page_size=30,status=active", namespace, repository);
let tags: TagsResponse = client.get(images_url).send().await?.json().await?;
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;
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
};
while let Some(next) = next_url {
let tags: TagsResponse = client.get(&next).send().await?.json().await?;
checked += tags.results.len();
return Some(Version::parse_from(trimmed));
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);
}
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)));
}
return Ok(BuildDirective::ShouldBuild(Some(version)));
}
Err(DockerError::NoTag.into())