@@ -3,7 +3,7 @@ use std::{io::Read, time::Duration};
33use anyhow:: { Context as _, Result , bail} ;
44use flate2:: read:: GzDecoder ;
55
6- use crate :: utils :: git ;
6+ use super :: { VerifyOutcome , resolve_version } ;
77
88const DEFAULT_BASE_URL : & str = "https://apt.vector.dev" ;
99const 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.
1515const 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( ) ]
2320pub 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
4237impl 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
8787struct 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-
11792fn check_arch (
11893 client : & reqwest:: blocking:: Client ,
11994 base_url : & str ,
0 commit comments