33
44use crate :: commands:: release:: generate_cue;
55use crate :: utils:: { command:: run_command, git, paths} ;
6- use anyhow:: { Context , Result , anyhow, bail} ;
6+ use anyhow:: { Context , Result , anyhow} ;
7+ use reqwest:: blocking:: Client ;
78use semver:: Version ;
89use std:: {
910 env, fs,
@@ -12,6 +13,7 @@ use std::{
1213 path:: { Path , PathBuf } ,
1314 process:: Command ,
1415} ;
16+ use toml:: Value ;
1517use toml_edit:: DocumentMut ;
1618
1719const ALPINE_PREFIX : & str = "FROM docker.io/alpine:" ;
@@ -467,57 +469,53 @@ fn insert_block_after_changelog(original: &str, block: &str) -> String {
467469}
468470
469471fn get_latest_vrl_tag_and_changelog ( ) -> Result < String > {
470- // Step 1: get the latest tag
471- let tag_output = Command :: new ( "gh" )
472- . args ( [ "api" , "repos/vectordotdev/vrl/tags" , "--jq" , ".[0].name" ] )
473- . output ( )
474- . context ( "Failed to run `gh api` for VRL tags" ) ?;
475-
476- if !tag_output. status . success ( ) {
477- let stderr = String :: from_utf8_lossy ( & tag_output. stderr ) ;
478- bail ! ( "gh api tags failed: {stderr}" ) ;
479- }
480-
481- let tag = String :: from_utf8 ( tag_output. stdout )
482- . context ( "gh api output is not valid UTF-8" ) ?;
483- let tag = tag. trim ( ) . to_string ( ) ;
484-
485- // Step 2: fetch CHANGELOG.md for that tag
486- let changelog_output = Command :: new ( "gh" )
487- . args ( [
488- "api" ,
489- & format ! ( "repos/vectordotdev/vrl/contents/CHANGELOG.md?ref={tag}" ) ,
490- "-H" ,
491- "Accept: application/vnd.github.raw+json" ,
492- ] )
493- . output ( )
494- . context ( "Failed to run `gh api` for VRL CHANGELOG.md" ) ?;
495-
496- if !changelog_output. status . success ( ) {
497- let stderr = String :: from_utf8_lossy ( & changelog_output. stderr ) ;
498- bail ! ( "gh api CHANGELOG.md failed: {stderr}" ) ;
499- }
500-
501- let changelog = String :: from_utf8 ( changelog_output. stdout )
502- . context ( "CHANGELOG.md is not valid UTF-8" ) ?;
503-
504- // Extract the first release section (from the first ## to the next ##)
472+ let client = Client :: new ( ) ;
473+
474+ // Step 1: Get latest tag from GitHub API
475+ let tags_url = "https://api.github.com/repos/vectordotdev/vrl/tags" ;
476+ let tags_response = client
477+ . get ( tags_url)
478+ . header ( "User-Agent" , "rust-reqwest" ) // GitHub API requires User-Agent
479+ . send ( ) ?
480+ . text ( ) ?;
481+
482+ let tags: Vec < Value > = serde_json:: from_str ( & tags_response) ?;
483+ let latest_tag = tags
484+ . first ( )
485+ . and_then ( |tag| tag. get ( "name" ) )
486+ . and_then ( |name| name. as_str ( ) )
487+ . ok_or_else ( || anyhow ! ( "Failed to extract latest tag" ) ) ?
488+ . to_string ( ) ;
489+
490+ // Step 2: Download CHANGELOG.md for the specific tag
491+ let changelog_url =
492+ format ! ( "https://raw.githubusercontent.com/vectordotdev/vrl/{latest_tag}/CHANGELOG.md" , ) ;
493+ let changelog = client
494+ . get ( & changelog_url)
495+ . header ( "User-Agent" , "rust-reqwest" )
496+ . send ( ) ?
497+ . text ( ) ?;
498+
499+ // Step 3: Extract text from first ## to next ##
500+ let lines: Vec < & str > = changelog. lines ( ) . collect ( ) ;
505501 let mut section = Vec :: new ( ) ;
506502 let mut found_first = false ;
507- for line in changelog. lines ( ) {
503+
504+ for line in lines {
508505 if line. starts_with ( "## " ) {
509506 if found_first {
507+ section. push ( line. to_string ( ) ) ;
510508 break ;
511509 }
512510 found_first = true ;
513- }
514- if found_first {
515- section. push ( line) ;
511+ section . push ( line . to_string ( ) ) ;
512+ } else if found_first {
513+ section. push ( line. to_string ( ) ) ;
516514 }
517515 }
518516
519517 if !found_first {
520- bail ! ( "No ## headers found in VRL CHANGELOG.md" ) ;
518+ return Err ( anyhow ! ( "No ## headers found in CHANGELOG.md" ) ) ;
521519 }
522520
523521 Ok ( section. join ( "\n " ) )
0 commit comments