Skip to content

Commit 4c487f8

Browse files
feat(vdev): expand release verify with apt/docker/github/homebrew/rpm/timber-io/website probes
1 parent 7e0677c commit 4c487f8

9 files changed

Lines changed: 1869 additions & 71 deletions

File tree

vdev/src/commands/release/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
mod channel;
2-
mod check;
32
mod github;
43
mod homebrew;
54
mod prepare;
65
mod push;
6+
mod verify;
77

88
crate::cli_subcommands! {
99
"Manage the release process..."
1010
generate_cue,
1111
channel,
12-
check,
1312
commit,
1413
docker,
1514
github,
1615
homebrew,
1716
prepare,
1817
push,
1918
s3,
19+
verify,
2020
}
2121

2222
crate::script_wrapper! {
Lines changed: 44 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::{io::Read, time::Duration};
33
use anyhow::{Context as _, Result, bail};
44
use flate2::read::GzDecoder;
55

6-
use crate::utils::git;
6+
use super::{VerifyOutcome, resolve_version};
77

88
const DEFAULT_BASE_URL: &str = "https://apt.vector.dev";
99
const DEFAULT_COMPONENT: &str = "vector-0";
@@ -14,16 +14,11 @@ const DEFAULT_SUITE: &str = "stable";
1414
// `x86_64` is a legacy Datadog alias that points at the same amd64 deb.
1515
const ARCHES: &[&str] = &["amd64", "arm64", "armhf", "x86_64"];
1616

17-
/// Check that a Vector release is fully published to the Datadog APT repo.
18-
///
19-
/// For each expected architecture, fetches `Packages.gz`, confirms the version is
20-
/// indexed, and verifies the referenced `.deb` is reachable.
17+
/// Verify the Datadog APT repo serves a Vector release across every expected architecture.
2118
#[derive(clap::Args, Debug)]
2219
#[command()]
2320
pub struct Cli {
24-
/// Version to check (e.g. `0.55.0`). Defaults to the most recent `v*` git tag,
25-
/// since `Cargo.toml`'s version is bumped to the next development version
26-
/// immediately after a release.
21+
/// Version to verify (e.g. `0.55.0`). Defaults to the most recent `v*` git tag.
2722
version: Option<String>,
2823

2924
/// Base URL of the APT repo.
@@ -41,79 +36,59 @@ pub struct Cli {
4136

4237
impl Cli {
4338
pub fn exec(self) -> Result<()> {
44-
let version = if let Some(v) = self.version {
45-
v
46-
} else {
47-
latest_release_tag()?
48-
};
49-
let debian_version = format!("{version}-1");
50-
51-
let client = reqwest::blocking::Client::builder()
52-
.timeout(Duration::from_secs(30))
53-
.build()?;
54-
55-
info!(
56-
"Checking Vector {version} in {}/dists/{}/{}",
57-
self.url, self.suite, self.component
58-
);
59-
60-
let mut failures = 0usize;
61-
for arch in ARCHES {
62-
match check_arch(
63-
&client,
64-
&self.url,
65-
&self.suite,
66-
&self.component,
67-
arch,
68-
&debian_version,
69-
) {
70-
Ok(ArchResult { filename, deb_size }) => {
71-
println!(" {arch:<8} OK {filename} ({deb_size} bytes)");
72-
}
73-
Err(e) => {
74-
failures += 1;
75-
println!(" {arch:<8} FAIL {e:#}");
76-
}
39+
let version = resolve_version(self.version)?;
40+
match verify_inner(&version, &self.url, &self.suite, &self.component) {
41+
Ok(summary) => {
42+
println!("OK: {summary}");
43+
Ok(())
7744
}
45+
Err(e) => Err(e),
7846
}
47+
}
48+
}
49+
50+
pub fn verify(version: &str) -> VerifyOutcome {
51+
match verify_inner(version, DEFAULT_BASE_URL, DEFAULT_SUITE, DEFAULT_COMPONENT) {
52+
Ok(summary) => VerifyOutcome::Ok(summary),
53+
Err(e) => VerifyOutcome::Failed(e),
54+
}
55+
}
56+
57+
fn verify_inner(version: &str, base_url: &str, suite: &str, component: &str) -> Result<String> {
58+
let debian_version = format!("{version}-1");
59+
let client = reqwest::blocking::Client::builder()
60+
.timeout(Duration::from_secs(30))
61+
.build()?;
62+
63+
info!("Checking Vector {version} in {base_url}/dists/{suite}/{component}");
7964

80-
if failures > 0 {
81-
bail!("{failures}/{} architectures missing {version}", ARCHES.len());
65+
let mut failures = 0usize;
66+
for arch in ARCHES {
67+
match check_arch(&client, base_url, suite, component, arch, &debian_version) {
68+
Ok(ArchResult { filename, deb_size }) => {
69+
println!(" {arch:<8} OK {filename} ({deb_size} bytes)");
70+
}
71+
Err(e) => {
72+
failures += 1;
73+
println!(" {arch:<8} FAIL {e:#}");
74+
}
8275
}
83-
Ok(())
8476
}
77+
78+
if failures > 0 {
79+
bail!(
80+
"{failures}/{} architectures missing {version}",
81+
ARCHES.len()
82+
);
83+
}
84+
Ok(format!("{}/{} arches OK", ARCHES.len(), ARCHES.len()))
8585
}
8686

8787
struct ArchResult {
8888
filename: String,
8989
deb_size: u64,
9090
}
9191

92-
// Return the most recent Vector release tag (e.g. `0.55.0`) with the leading `v` stripped.
93-
//
94-
// We use `for-each-ref` sorted by creation date rather than `git describe`, because Vector
95-
// tags releases on release branches (not master), so HEAD-reachability is the wrong signal.
96-
// The glob `v[0-9]*` matches tags like `v0.55.0` while excluding `vdev-v*` (second char is
97-
// `d`, not a digit).
98-
fn latest_release_tag() -> Result<String> {
99-
let tag = git::run_and_check_output(&[
100-
"for-each-ref",
101-
"--sort=-creatordate",
102-
"--count=1",
103-
"--format=%(refname:short)",
104-
"refs/tags/v[0-9]*",
105-
])
106-
.context("finding latest Vector release tag via `git for-each-ref`")?;
107-
let tag = tag.trim();
108-
if tag.is_empty() {
109-
bail!("no matching release tags found (pattern: `v[0-9]*`)");
110-
}
111-
let version = tag
112-
.strip_prefix('v')
113-
.ok_or_else(|| anyhow::anyhow!("expected tag {tag:?} to start with 'v'"))?;
114-
Ok(version.to_string())
115-
}
116-
11792
fn check_arch(
11893
client: &reqwest::blocking::Client,
11994
base_url: &str,

0 commit comments

Comments
 (0)