Skip to content

Commit cdb27e8

Browse files
prontclaude
andauthored
chore(dev): kill Ruby and port release scripts to native vdev (#25379)
* chore(dev): replace Ruby release flow with internal vdev functions Ports the two remaining Ruby release scripts to native Rust and folds the resulting `vdev release` surface down to the bits that are actually called. - `scripts/generate-release-cue.rb` (467 lines) is replaced by a `pub(super) fn run` in `vdev/src/commands/release/generate_cue.rs`. The function walks `git log v<last>...HEAD` (three-dot symmetric difference, so `--cherry-pick --right-only` filters out commits already released on a patch branch — the Ruby form), parses the conventional-commit messages, processes `changelog.d/*.md` fragments into the release CUE schema, and runs `cue fmt`. It is called only from `vdev release prepare` (no standalone CLI subcommand). - `scripts/release-commit.rb`, `vdev release commit`, `vdev release push`, `vdev build release-cue`, and the corresponding Makefile targets (`make release`, `release-commit`, `release-push`) are removed: none of them were called by CI workflows, scripts, or issue templates, and the original `release-commit.rb` had been broken for some time (pointing at `docs/reference/releases`, a directory that no longer exists). Manual operator tagging happens via `git tag` directly per the release issue templates. - The `scripts/util/*.rb` library, `Gemfile`, `Gemfile.lock`, and the `Gemfile` COPY in `scripts/environment/Dockerfile` are deleted. `ruby` itself stays in the bootstrap scripts and `vdev/README.md` — `scripts/check-events` is the last remaining Ruby script and gets ported in a follow-up commit. - Docs, issue templates, the `changes.yml` workflow filter, and `website/README.md` are repointed at `cargo vdev release prepare`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(dev): port scripts/check-events to vdev via syn AST Replaces the last Ruby script in the repo (515 lines) with a native `vdev check events` that walks Rust source via `syn`'s AST instead of regex-scraping. The validation rules from `docs/specs/instrumentation.md` are preserved unchanged; behaviour against the current tree matches the Ruby script (`0 error(s)` on master, identical reports on a synthetic fixture exercising every rule branch). Implementation notes: - Structural scanning (struct fields, impl-block trait/event names) uses syn visitors. Macro argument parsing (`counter!(...)`, `trace!(...)`, etc.) uses small targeted regexes on the macro's already-tokenised input. Use-counting (`emit!(EventName)` / `register!(...)`) uses one regex pass over the raw source because syn does not descend into the bodies of opaque macros like `tokio::select!` where some emit sites live. - `## skip check-validity-events ##` is added to `lib/vector-common/src/internal_event/component_events_dropped.rs`. That impl block is the foundation type the `registered_event!` macro abstracts over, so it has to implement `RegisterInternalEvent` by hand. The Ruby script's regex never matched its multi-line `impl` header and so silently let it through; the AST scanner sees it correctly and the existing skip-marker mechanism makes the intent explicit. - `proc-macro2`, `quote`, and `syn` are declared as workspace deps with default-features off; vdev opts into the syn `full`, `visit`, `extra-traits`, `printing`, `parsing` features and proc-macro2's `span-locations` locally. These features are already pulled in transitively by Vector's existing dep graph (verified via `cargo tree -p vector`), so the additions do not change Vector's production binary. - 32 unit tests are added: 14 covering the macro/log/metric arg parsers (literal-first, named-field, variable, trailing-literal, `%`-capture, message format checks, comma-arg nesting, `CamelCase → snake_case`) and 18 driving every branch of `validate_event` with synthetic `Event` structs. - Differential test (run by hand against a worktree with a synthetic fixture file): `ruby scripts/check-events` and `cargo vdev check events` flagged the same eight events plus the same duplicate pair; outputs differed only in sort order and a Ruby string-escape artefact. The bootstrap scripts (`scripts/environment/bootstrap-{macos, ubuntu-24.04}.sh`), `vdev/README.md`, and `.ruby-version` lose their Ruby references — there is no Ruby left in the repo to install. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(dev): make check-events robust to CWD and trailing-literal messages Two bugs caught in code review of `vdev/src/commands/check/events.rs`: 1. The native check globbed `src/**/*.rs` and `lib/**/*.rs` relative to the caller's CWD. The Ruby script wrapper used to chdir to the repo root, so this silently regressed: running `vdev check events` from anywhere outside the repo root produced `0 error(s)` without scanning anything. Fix: chdir to `paths::find_repo_root()` at the top of `Cli::exec`, matching the previous wrapper's behaviour. Running from a subdir now scans correctly; running from outside the repo errors out with a useful message. 2. `parse_log_args` claimed the first bare positional expression as the log message before scanning the rest of the args for a string literal. For real Vector code that uses `warn!(%error, "Failed to flush.")`, the literal is the actual message but the function never reached it — so the message-format check (capital + trailing period) silently never fired on those sites. Fix: walk all args once, classify each as a literal candidate, `message =` named-field candidate, bare-positional candidate, or plain parameter, then pick the message in that priority order. Adds a regression test covering the bare-then-literal pattern. Both bugs were flagged by Codex code review on PR #25379. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(dev): cover nested log calls and dedup against released metadata Three review findings on the check-events / release-cue ports: - `vdev check events` only ran its log-message format check via the syn AST visitor, which does not descend into the bodies of opaque outer macros like `tokio::select!` / `cfg_if!`. Log calls nested inside those macros were silently exempt. Replaces the AST format check with a raw-text pass that finds every `(trace|debug|info| warn|error)!(...)` invocation regardless of nesting. Adds two unit tests against the new pass — including one that asserts a violation inside a synthetic `tokio::select!` block is still reported. - `generate_cue::run` no longer relies on `--cherry-pick --right-only` alone to dedupe commits against earlier releases — that flag only filters patch-id-equivalent commits, so a conflict-resolved cherry- pick (different SHA, same PR) could re-appear in the next release CUE. Adds a `collect_released_identifiers` pass that pulls the SHA and PR-number sets out of every existing `website/cue/reference/releases/*.cue`, then filters the fetched commit set against both. Two unit tests cover the extractor. - `Commit::validate` now bails when the conventional-commit parser could not classify the subject (`type: None`). Previously such commits passed validation and landed in the published release CUE with a null type — a malformed PR title would silently ship. Also factors `parse_log_args` so it shares one `&str` implementation with the new raw-text pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(dev): apply rustfmt over previous fix Pre-push hook reformatting on the format-check + dedup fixes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(dev): replace map().unwrap_or(false) in check-events test helper `cargo clippy -p vdev --all-targets` flagged two map_unwrap_or lints in the test-only `check()` helper. Identical pattern to fixes already applied in production code; just missed when test cases were added later. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(dev): clean up vdev check-events module Drop the pedantic clippy allows the file was carrying and refactor to satisfy them: rename Event fields whose `_event` suffix tripped struct_field_names, group the three skip flags into a SkipFlags substruct (struct_excessive_bools), and split validate_event and Cli::exec into smaller helpers (too_many_lines). Also remove a redundant `name_ends_with` wrapper that just called str::ends_with, and merge the parse_log_args TokenStream wrapper into its `&str` body. One callsite was already operating on stringified tokens, so it was doing a wasted parse-and-restringify round trip. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(deps): use convert_case for snake-casing in vdev check-events Replace the bespoke `camel_to_snake` regex helper in vdev's check-events with `convert_case::Casing::to_case`. Promote convert_case to a workspace dep so vdev and vector-config-common share the same version declaration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: drop outdated comment on workspace proc-macro2/quote/syn deps The comment claimed declaring these at the workspace level prevented vdev's extra `syn` features from unifying into Vector's production build. That's not what workspace declarations do — `cargo` unifies features across the resolved dep graph regardless. The reason vdev's features don't reach the `vector` package is simply that vdev isn't a dep of `vector`. The comment was also stale: these crates are now direct deps of vector-config-macros, vector-config-common, and vector-common-macros, not just vdev. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(dev): accept uppercase release scopes in conventional-commit parser The release-CUE generator rejected commit subjects with uppercase scope characters (e.g. `fix(ARC): ...`), even though `.github/workflows/semantic.yml` explicitly lists `ARC` as a valid scope. A PR title that passed semantic validation could therefore block `release prepare` later. Widen the scope character class to allow uppercase letters and add a regression test. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(dev): track angle brackets in macro-arg splitter split_comma_args only tracked `()[]{}` nesting, so a registered_event! handle field with a generic type containing a comma would be split mid-type. The existing src/internal_events/filter.rs field `Registered<ComponentEventsDropped<'static, INTENTIONAL>> = register!(...)` broke before the assignment, hiding the register! emission and causing spurious missing-log/counter errors for FilterEventsDropped. Track angle depth as a separate counter and only decrement `>` when there is a matching `<`, so the `>` in `key => value` tag pairs (used inside counter! args) stays unaffected. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent bbde98b commit cdb27e8

36 files changed

Lines changed: 2616 additions & 1806 deletions

‎.github/ISSUE_TEMPLATE/minor-release.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ Automated steps include:
4545
- Pin VRL to latest released version rather than `main`
4646
- Check if there is a newer version of [Alpine](https://alpinelinux.org/releases/) or [Debian](https://www.debian.org/releases/) available to update the release images in
4747
`distribution/docker/`. Update if so.
48-
- Run `cargo vdev build release-cue` to generate a new cue file for the release
48+
- Generate a new cue file for the release in `website/cue/reference/releases/`
4949
- Copy VRL changelogs from the VRL version in the last Vector release as a new changelog entry
5050
([example](https://github.com/vectordotdev/vector/blob/9c67bba358195f5018febca2f228dfcb2be794b5/website/cue/reference/releases/0.41.0.cue#L33-L64))
5151
- Update version number in `website/cue/reference/administration/interfaces/kubectl.cue`

‎.github/ISSUE_TEMPLATE/patch-release.md‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@ export PREP_BRANCH=prepare-v-0-"${CURRENT_MINOR_VERSION}"-"${NEW_PATCH_VERSION}"
2424
- [ ] Cherry-pick in all commits to be released from the associated release milestone
2525
- If any merge conflicts occur, attempt to solve them and if needed enlist the aid of those familiar with the conflicting commits.
2626
- [ ] Bump the release number in the `Cargo.toml` to the current version number
27-
- [ ] Run `cargo vdev build release-cue` to generate a new cue file for the release
28-
- [ ] Add description key to the generated cue file with a description of the release (see
27+
- [ ] Add a new cue file for the release at `website/cue/reference/releases/${NEW_VERSION}.cue`
28+
by copying the previous patch release file and editing the version, date, commits, and
29+
changelog entries to match this release.
30+
- [ ] Add a description key to the cue file with a description of the release (see
2931
previous releases for examples).
3032
- [ ] Update version number in `distribution/install.sh`
3133
- [ ] Add new version to `website/cue/reference/versions.cue`

‎.github/workflows/changes.yml‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,6 @@ jobs:
228228
- "vdev/**"
229229
- ".github/workflows/changes.yml"
230230
component_docs:
231-
- 'scripts/generate-component-docs.rb'
232231
- "vdev/**"
233232
- 'website/cue/**/*.cue'
234233
- 'docs/generated/**'

‎.ruby-version‎

Lines changed: 0 additions & 1 deletion
This file was deleted.

‎Cargo.lock‎

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Cargo.toml‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ clap = { version = "4.5.60", default-features = false, features = ["derive", "er
149149
clap_complete = "4.5.66"
150150
colored = { version = "3.1.1", default-features = false }
151151
const-str = { version = "1.1.0", default-features = false }
152+
convert_case = { version = "0.8", default-features = false }
152153
criterion = "0.8"
153154
crossbeam-utils = { version = "0.8.21", default-features = false }
154155
darling = { version = "0.20.11", default-features = false, features = ["suggestions"] }
@@ -198,6 +199,9 @@ tokio = { version = "1.49.0", default-features = false }
198199
tokio-stream = { version = "0.1.18", default-features = false }
199200
tokio-test = "0.4.5"
200201
tokio-tungstenite = { version = "0.20.1", default-features = false }
202+
proc-macro2 = { version = "1", default-features = false }
203+
quote = { version = "1", default-features = false }
204+
syn = { version = "2", default-features = false }
201205
toml = { version = "0.9.8", default-features = false, features = ["serde", "display", "parse"] }
202206
tonic = { version = "0.11", default-features = false, features = ["transport", "codegen", "prost", "tls", "tls-roots", "gzip"] }
203207
tonic-build = { version = "0.11", default-features = false, features = ["transport", "prost"] }

‎Makefile‎

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -595,13 +595,6 @@ package-%:
595595

596596
##@ Releasing
597597

598-
.PHONY: release
599-
release: release-prepare generate release-commit ## Release a new Vector version
600-
601-
.PHONY: release-commit
602-
release-commit: ## Commits release changes
603-
@$(VDEV) release commit
604-
605598
.PHONY: release-docker
606599
release-docker: ## Release to Docker Hub
607600
@$(VDEV) release docker
@@ -618,10 +611,6 @@ release-homebrew: ## Release to vectordotdev Homebrew tap
618611
release-prepare: ## Prepares the release with metadata and highlights
619612
@$(VDEV) release prepare
620613

621-
.PHONY: release-push
622-
release-push: ## Push new Vector version
623-
@$(VDEV) release push
624-
625614
.PHONY: release-s3
626615
release-s3: ## Release artifacts to S3
627616
@$(VDEV) release s3

‎docs/DOCUMENTING.md‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,12 @@ watchexec "make check-docs"
147147

148148
### Changelog
149149

150-
Contributors do not need to maintain a changelog. This is automatically generated
151-
via the `make release` command, made possible by the use of
152-
[conventional commit](https://www.conventionalcommits.org/en/v1.0.0/) titles.
150+
Contributors document user-facing changes by adding a fragment under
151+
[`changelog.d/`](../changelog.d/README.md); the release CUE file's user-facing
152+
changelog section is assembled from those fragments by `cargo vdev release
153+
prepare` during release prep. The CUE file's `commits:` array is populated
154+
from the git log via [conventional commit](https://www.conventionalcommits.org/en/v1.0.0/)
155+
titles, so PR titles must follow that spec.
153156

154157
### Release highlights
155158

‎lib/vector-common/src/internal_event/component_events_dropped.rs‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,12 @@ impl<'a, const INTENTIONAL: bool> From<&'a str> for ComponentEventsDropped<'a, I
2727
}
2828
}
2929

30+
// ComponentEventsDropped is the foundation type the `registered_event!` macro
31+
// abstracts over, so we have to implement RegisterInternalEvent by hand here.
3032
impl<'a, const INTENTIONAL: bool> RegisterInternalEvent
3133
for ComponentEventsDropped<'a, INTENTIONAL>
3234
{
35+
// ## skip check-validity-events ##
3336
type Handle = DroppedHandle<'a, INTENTIONAL>;
3437
fn register(self) -> Self::Handle {
3538
Self::Handle {

‎lib/vector-config-common/Cargo.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ edition = "2024"
55
license = "MPL-2.0"
66

77
[dependencies]
8-
convert_case = { version = "0.8", default-features = false }
8+
convert_case.workspace = true
99
darling.workspace = true
1010
proc-macro2 = { version = "1.0", default-features = false }
1111
serde.workspace = true

0 commit comments

Comments
 (0)