feat/v2.1-polish-dsl-errors: sharpen v2 config-error UX + pin v2.1.0 release via .release-version#35
Merged
vedanthvdev merged 1 commit intomasterfrom Apr 23, 2026
Conversation
…release via `.release-version` Three small-but-sharp fixes that surfaced during the v2.0.0-local pilot against security-service, bundled into one PR because they all share the same goal: close the gap between "something in my build.gradle is wrong" and "the plugin told me what to change". Two are DSL-error polish, the third teaches the release workflow a new version-override mechanism so this exact release can ship as v2.1.0 on a merge-to-master push without needing workflow_dispatch coordination. 1. Targeted v2 migration hint on the three removed legacy knobs. Adds `setRunAllIfNoMatches` / `setRunAllOnNonJavaChange` / `setExcludePaths` shims on `AffectedTestsExtension` that intercept the Groovy DSL assignment and throw a `GradleException` naming both the removed v1 knob and its v2 replacement(s) — pointing at the exact onXxx action, the mode shortcut where one exists, and the CHANGELOG section for the full table. Kotlin DSL callers already get a compile error naming the removed property so the shims only fire in Groovy, which is where the unhelpful default error lived. 2. `gradlewTimeoutSeconds` range check at configuration time. The v1.9.22 check (value >= 0, 0 disables) lived on the core builder and only ran at task-execution, which meant IDE sync / `./gradlew help` / `./gradlew tasks` all stayed green against a misconfigured build and the operator only saw the rejection when they tried to run affectedTest. Adds a mirror check in the plugin's `project.afterEvaluate` so the same message fires at configuration end. Builder-side check stays as belt-and-braces for programmatic callers that bypass the DSL extension. 3. `.release-version` override file in `.github/workflows/release.yml`. Until now, shipping a non-patch bump on a merge-to-master release required running the release workflow via `workflow_dispatch` with an explicit `version` input. That meant every minor release had a coordination window where the auto-release on the merge push could mint an unwanted patch tag before the manual dispatch took over. The workflow now reads a `.release-version` SemVer file at repo root (validated via regex before use) when no dispatch input is present, passes it to axion-release, and deletes the file in a `[skip ci]` follow-up commit after the tag/publish/release triad succeeds. This PR commits `.release-version = 2.1.0` so its own merge ships as v2.1.0 on the portal; the file self-cleans afterwards so subsequent patch releases resume auto-incrementing. Regression coverage for the DSL fixes is pinned in `AffectedTestsPluginTest`: - `legacyKnobAssignmentThrowsWithV2MigrationHint_runAllIfNoMatches` - `legacyKnobAssignmentThrowsWithV2MigrationHint_runAllOnNonJavaChange` - `legacyKnobAssignmentThrowsWithV2MigrationHint_excludePaths` - `negativeGradlewTimeoutFailsAtConfigurationTime` Each assertion pins both the user-facing knob name AND the v2 replacement / valid-range bound, so a well-intentioned "tidy up the error message" refactor that drops either half is caught by the test suite rather than rediscovered by the next migrating adopter. The release-workflow logic was simulated end-to-end against nine input cases (input-wins, file-used, trailing-newline trimmed, empty file rejected, bad SemVer rejected, pre-release allowed, etc.) to verify branching before relying on it to ship v2.1.0 itself. CHANGELOG calls v2.1.0 out as the first publicly tagged v2 release, bundling the v2.0 legacy-knob removal (already in master under the v1.9.23 tag the auto-patch-incrementer minted) with these polish fixes.
a1f5744 to
7864101
Compare
Owner
Author
|
Triggering CI - workflow didn't dispatch on initial push. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Three small-but-sharp fixes uncovered by the v2.0.0-local pilot against
security-service, bundled into one PR because they all close the same gap: "something in mybuild.gradleis wrong → the plugin told me exactly what to change".Two fixes are DSL-error polish; the third teaches the release workflow a version-override mechanism so this PR's own merge can ship as
v2.1.0on a normal push-to-master without needingworkflow_dispatchcoordination. The mechanism is reusable for future minor/major bumps.What
1. Targeted v2 migration hint on the three removed legacy knobs
Before (Gradle's generic error):
After (v2.1, via
setRunAllIfNoMatches/setRunAllOnNonJavaChange/setExcludePathsshims on the extension):Kotlin DSL already gets a compile error naming the removed property so shims only fire for Groovy — which is where the unhelpful default lived.
2.
gradlewTimeoutSecondsrange check at configuration timeThe v1.9.22
value >= 0check lived on the core builder and only ran at task-execution. IDE sync,./gradlew help,./gradlew tasksall stayed green against a misconfigured build; operators only saw the rejection when they ranaffectedTest.v2.1 mirrors the check in
AffectedTestsPlugin#applyviaproject.afterEvaluate, so the same message fires at configuration completion — IDE sync surfaces it immediately. Builder-side check stays as belt-and-braces for programmatic callers that bypass the DSL.3.
.release-versionoverride file for merge-to-master minor/major releasesUntil v2.1, the only way to ship a non-patch bump on a merge-to-master release was
workflow_dispatchwith an explicitversioninput. That meant every minor release had a coordination window where the auto-release on the merge push could mint an unwanted patch tag before the manual dispatch took over.The workflow now reads a
.release-versionSemVer file at repo root (regex-validated before use) when no dispatch input is present, passes it to axion-release, and deletes the file in a[skip ci]follow-up commit after the tag → publish → GitHub-Release triad succeeds.This PR commits
.release-version = 2.1.0so its own merge ships asv2.1.0on the Gradle Plugin Portal. The file self-cleans afterwards so subsequent patch releases resume auto-incrementing.Priority order in release.yml:
workflow_dispatchinput (unchanged).release-versionfile (new)Regression coverage
Pinned in
AffectedTestsPluginTest:legacyKnobAssignmentThrowsWithV2MigrationHint_runAllIfNoMatcheslegacyKnobAssignmentThrowsWithV2MigrationHint_runAllOnNonJavaChangelegacyKnobAssignmentThrowsWithV2MigrationHint_excludePathsnegativeGradlewTimeoutFailsAtConfigurationTimeEach message assertion pins both the user-facing knob name AND the v2 replacement / valid-range bound, so a well-intentioned "tidy up the error message" refactor that drops either half is caught.
Revert-verified: reverting
AffectedTestsPlugin.javain isolation (keeping the rest) makesnegativeGradlewTimeoutFailsAtConfigurationTimefail at the assertion, not at compile. Reverting the extension shims makes the other three tests fail to compile — which is also a guard against silent regression.The release-workflow logic was simulated locally against 9 input cases (input-wins, file-used, trailing-newline trimmed, empty file rejected, bad SemVer rejected, pre-release allowed, ...) before relying on it to ship v2.1.0.
Test plan
./gradlew checkgreen on branch HEADruby -e 'require "yaml"; YAML.load_file(...)').release-versionpicked up → tagv2.1.0→ publish to Plugin Portal → GitHub Release → self-cleanup commit[skip ci]security-servicescenarios againstio.github.vedanthvdev.affectedtests:2.1.0pulled directly from the portal (not mavenLocal)Notes for reviewers
v1.9.23tag that auto-patch-increment minted on the PR feat/v2.0-remove-legacy-knobs: Phase 3 — delete the v1 DSL surface for v2.0.0 #34 merge — so the Plugin Portal has v2-content under a patch version already. v2.1.0 is the first publicly tagged v2 release and supersedes v1.9.23 in name.