Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 6 additions & 8 deletions .github/ISSUE_TEMPLATE/minor-release.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@ title: "VRL [version] release"
labels: "domain: releasing"
---

- [ ] Create release preparation PR
- [ ] Bump [Cargo.toml](https://github.com/vectordotdev/vrl/blob/main/Cargo.toml#L3) version and commit the change.
- [ ] Run `cargo check` to update `Cargo.lock`.
- [ ] Run the [./scripts/generate_release_changelog.sh](https://github.com/vectordotdev/vrl/blob/main/scripts/generate_release_changelog.sh) script
and commit the changes.
- [ ] After the above PR is merged, run the [./scripts/publish.py](https://github.com/vectordotdev/vrl/blob/main/scripts/publish.py) script.
- [ ] Confirm that the new tag was created: https://github.com/vectordotdev/vrl/tags
- [ ] Confirm that the new VRL release was published: https://crates.io/crates/vrl
- [ ] Run `cargo run -p release` (use `--dry-run` to preview, `--issue <url>` to link this issue)
- [ ] Review/edit `CHANGELOG.md` when prompted, then press Enter to push and create the prep PR
- [ ] Get the prep PR reviewed and merged (the script will poll and continue automatically)
- The script will publish to crates.io, tag, and push the tag
- [ ] Confirm the new VRL release was published: https://crates.io/crates/vrl
- [ ] Confirm that the new tag was created: https://github.com/vectordotdev/vrl/tags
7 changes: 4 additions & 3 deletions release/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ The release flow:
3. Bumps version in `Cargo.toml`
4. Generates changelog from `changelog.d/` fragments
5. Pauses for you to review/edit `CHANGELOG.md`
6. Publishes to crates.io
7. Tags and pushes
8. Creates a PR to merge the release into main
6. Pushes the branch and creates a PR
7. Waits for the PR to be merged to main
8. Switches to main, tags the release commit
9. Checks out the tag, publishes to crates.io, pushes the tag

### Check Changelog Fragments

Expand Down
57 changes: 40 additions & 17 deletions release/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,33 +123,18 @@ fn release(version_arg: Option<&str>, dry_run: bool, issue: Option<&str>) -> Res
&root,
)?;

println!("Publishing to crates.io...");
run("cargo", &["publish"], &root)?;
println!("Published vrl v{new_version} to crates.io.");

let tag = format!("v{new_version}");
run(
"git",
&["tag", "-a", &tag, "-m", &format!("Release {new_version}")],
&root,
)?;

println!("Pushing...");
run("git", &["push", "-u", "origin", &branch], &root)?;
run("git", &["push", "origin", &tag], &root)?;

println!("Creating pull request...");
let title = format!("chore(releasing): Prepare {new_version} release");
let mut body = formatdoc! {"
Release {new_version}

Published to crates.io: https://crates.io/crates/vrl/{new_version}
Tag: `{tag}`"
Release {new_version}"
};
if let Some(link) = issue {
body.push_str(&format!("\n\nRelated issue: {link}"));
}
run(
let pr_url = run(
"gh",
&[
"pr",
Expand All @@ -167,8 +152,46 @@ fn release(version_arg: Option<&str>, dry_run: bool, issue: Option<&str>) -> Res
],
&root,
)?;
let pr_url = pr_url.trim().to_string();
println!("PR: {pr_url}");

println!("Waiting for the PR to be merged to main...");
loop {
let state = run(
"gh",
&["pr", "view", &pr_url, "--json", "state", "--jq", ".state"],
&root,
)?;
if state.trim() == "MERGED" {
println!("PR merged.");
break;
}
println!(" state: {}. Checking again in 15s...", state.trim());
std::thread::sleep(std::time::Duration::from_secs(15));
Comment on lines +165 to +170

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Abort when the prep PR is closed

In the release flow where the prep PR is closed instead of merged (for example reviewers reject it or a maintainer recreates the PR), this loop never exits because it treats every non-MERGED gh pr view --json state result as still pending; the GitHub CLI exposes closed PRs through this same state field. That leaves the release command polling forever rather than failing before tagging/publishing can be retried or corrected.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💭 Can we avoid polling? I am thinking if we can use the tag as a trigger for a publish workflow.

}

println!("Switching to main...");
run("git", &["checkout", "main"], &root)?;
run("git", &["pull", "origin", "main"], &root)?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Pin the tag to the merged release PR

When another PR lands on main after the release prep PR is merged but before this command runs, git pull origin main advances to that newer head, so the following tag and cargo publish operate on commits that were not part of the reviewed release PR. This can publish unintended code/changelog content under the release version; the script should tag/publish the prep PR's merge commit rather than whatever origin/main happens to be when polling notices the merge.

Useful? React with 👍 / 👎.


let tag = format!("v{new_version}");
run(
"git",
&["tag", "-a", &tag, "-m", &format!("Release {new_version}")],
&root,
)?;
Comment on lines +178 to +182

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Create the release tag only after publish succeeds

If cargo publish fails after this tag is created (for example because of a crates.io/auth/network error or because the merged package still needs a fix), the command exits with an unpublished local v{new_version} tag pointing at the failed commit. A retry of the release flow then fails at tag creation or requires manual tag cleanup, and if the fix is made in a follow-up commit the stale tag no longer matches the releasable commit; keep the tag creation after a successful publish or clean it up on failure.

Useful? React with 👍 / 👎.


run("git", &["checkout", &tag], &root)?;

println!("Publishing to crates.io...");
run("cargo", &["publish"], &root)?;
println!("Published vrl v{new_version} to crates.io.");

run("git", &["push", "origin", &tag], &root)?;

println!("\nRelease {new_version} complete!");
println!("Tag: {tag}");
println!("crates.io: https://crates.io/crates/vrl/{new_version}");
Ok(())
}

Expand Down
Loading