diff --git a/Cargo.lock b/Cargo.lock
index 5f31832d545a9..bdc14fe074433 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -12182,6 +12182,7 @@ dependencies = [
"sha2",
"tempfile",
"toml 0.9.8",
+ "toml_edit 0.22.27",
]
[[package]]
diff --git a/vdev/Cargo.toml b/vdev/Cargo.toml
index 5a671f3c03b66..1683ace876a67 100644
--- a/vdev/Cargo.toml
+++ b/vdev/Cargo.toml
@@ -43,6 +43,7 @@ serde_yaml.workspace = true
sha2 = "0.10.9"
tempfile.workspace = true
toml.workspace = true
+toml_edit = { version = "0.22", default-features = false }
semver.workspace = true
indoc.workspace = true
git2 = { version = "0.20.2" }
diff --git a/vdev/src/commands/release/prepare.rs b/vdev/src/commands/release/prepare.rs
index 640f19f377386..f5b38de9fb073 100644
--- a/vdev/src/commands/release/prepare.rs
+++ b/vdev/src/commands/release/prepare.rs
@@ -3,7 +3,7 @@
use crate::utils::command::run_command;
use crate::utils::{git, paths};
-use anyhow::{Result, anyhow};
+use anyhow::{Context, Result, anyhow};
use reqwest::blocking::Client;
use semver::Version;
use std::fs::File;
@@ -14,7 +14,7 @@ use std::path::{Path, PathBuf};
use std::process::Command;
use std::{env, fs};
use toml::Value;
-use toml::map::Map;
+use toml_edit::DocumentMut;
const ALPINE_PREFIX: &str = "FROM docker.io/alpine:";
const ALPINE_DOCKERFILE: &str = "distribution/docker/alpine/Dockerfile";
@@ -42,6 +42,10 @@ pub struct Cli {
/// You can find the latest version here: .
#[arg(long)]
debian_version: Option,
+
+ /// Dry run. Enabling this will make it so no PRs will be created and no branches will be pushed upstream.
+ #[arg(long, default_value_t = false)]
+ dry_run: bool,
}
struct Prepare {
@@ -53,6 +57,7 @@ struct Prepare {
latest_vector_version: Version,
release_branch: String,
release_preparation_branch: String,
+ dry_run: bool,
}
impl Cli {
@@ -74,6 +79,7 @@ impl Cli {
"prepare-v-{}-{}-{}-website",
self.version.major, self.version.minor, self.version.patch
),
+ dry_run: self.dry_run,
};
prepare.run()
}
@@ -106,7 +112,11 @@ impl Prepare {
self.create_new_release_md()?;
- self.open_release_pr()
+ if !self.dry_run {
+ self.open_release_pr()?;
+ }
+
+ Ok(())
}
/// Steps 1 & 2
@@ -117,12 +127,16 @@ impl Prepare {
git::checkout_main_branch()?;
git::checkout_or_create_branch(self.release_branch.as_str())?;
- git::push_and_set_upstream(self.release_branch.as_str())?;
+ if !self.dry_run {
+ git::push_and_set_upstream(self.release_branch.as_str())?;
+ }
// Step 2: Create a new release preparation branch
// The branch website contains 'website' to generate vector.dev preview.
git::checkout_or_create_branch(self.release_preparation_branch.as_str())?;
- git::push_and_set_upstream(self.release_preparation_branch.as_str())?;
+ if !self.dry_run {
+ git::push_and_set_upstream(self.release_preparation_branch.as_str())?;
+ }
Ok(())
}
@@ -130,35 +144,11 @@ impl Prepare {
fn pin_vrl_version(&self) -> Result<()> {
debug!("pin_vrl_version");
let cargo_toml_path = &self.repo_root.join("Cargo.toml");
- let contents = fs::read_to_string(cargo_toml_path).expect("Failed to read Cargo.toml");
-
- // Needs this hybrid approach to preserve ordering.
- let mut lines: Vec = contents.lines().map(String::from).collect();
-
+ let contents = fs::read_to_string(cargo_toml_path).context("Failed to read Cargo.toml")?;
let vrl_version = self.vrl_version.to_string();
- for line in &mut lines {
- if line.trim().starts_with("vrl = { git = ") {
- if let Ok(mut vrl_toml) = line.parse::() {
- let vrl_dependency: &mut Value = vrl_toml
- .get_mut("vrl")
- .expect("line should start with 'vrl'");
-
- let mut new_dependency_value = Map::new();
- new_dependency_value
- .insert("version".to_string(), Value::String(vrl_version.clone()));
- let features = vrl_dependency
- .get("features")
- .expect("missing 'features' key");
- new_dependency_value.insert("features".to_string(), features.clone());
-
- *line = format!("vrl = {}", Value::from(new_dependency_value));
- }
- break;
- }
- }
+ let updated_contents = update_vrl_to_version(&contents, &vrl_version)?;
- lines.push(String::new()); // File should end with a newline.
- fs::write(cargo_toml_path, lines.join("\n")).expect("Failed to write Cargo.toml");
+ fs::write(cargo_toml_path, updated_contents).context("Failed to write Cargo.toml")?;
run_command("cargo update -p vrl");
git::commit(&format!(
"chore(releasing): Pinned VRL version to {vrl_version}"
@@ -420,6 +410,26 @@ impl Prepare {
// FREE FUNCTIONS AFTER THIS LINE
+/// Transforms a Cargo.toml string by replacing vrl's git dependency with a version dependency.
+/// Updates the vrl entry in [workspace.dependencies] from git + branch to a version.
+fn update_vrl_to_version(cargo_toml_contents: &str, vrl_version: &str) -> Result {
+ let mut doc = cargo_toml_contents
+ .parse::()
+ .context("Failed to parse Cargo.toml")?;
+
+ // Navigate to workspace.dependencies.vrl
+ let vrl_table = doc["workspace"]["dependencies"]["vrl"]
+ .as_inline_table_mut()
+ .context("vrl in workspace.dependencies should be an inline table")?;
+
+ // Remove git and branch, add version
+ vrl_table.remove("git");
+ vrl_table.remove("branch");
+ vrl_table.insert("version", vrl_version.into());
+
+ Ok(doc.to_string())
+}
+
fn get_latest_version_from_vector_tags() -> Result {
let tags = run_command("git tag --list --sort=-v:refname");
let latest_tag = tags
@@ -527,10 +537,31 @@ fn get_latest_vrl_tag_and_changelog() -> Result {
#[cfg(test)]
mod tests {
use crate::commands::release::prepare::{
- format_vrl_changelog_block, insert_block_after_changelog,
+ format_vrl_changelog_block, insert_block_after_changelog, update_vrl_to_version,
};
use indoc::indoc;
+ #[test]
+ fn test_update_vrl_to_version() {
+ let input = indoc! {r#"
+ [workspace.dependencies]
+ some-other-dep = "1.0.0"
+ vrl = { git = "https://github.com/vectordotdev/vrl.git", branch = "main", features = ["arbitrary", "cli", "test", "test_framework"] }
+ another-dep = "2.0.0"
+ "#};
+
+ let result = update_vrl_to_version(input, "0.28.0").expect("should succeed");
+
+ let expected = indoc! {r#"
+ [workspace.dependencies]
+ some-other-dep = "1.0.0"
+ vrl = { features = ["arbitrary", "cli", "test", "test_framework"] , version = "0.28.0" }
+ another-dep = "2.0.0"
+ "#};
+
+ assert_eq!(result, expected);
+ }
+
#[test]
fn test_insert_block_after_changelog() {
let vrl_changelog = "### [0.2.0]\n- Feature\n- Fix";