Update LiquibaseCommandLineTest expectedHelpOutput for the three new ALLOW_* audit flags#7760
Conversation
…ree new ALLOW_* flags Three upstream PRs from the May-2026 audit batch each added a new GlobalConfiguration.builder.define() entry that picocli auto-renders into the CLI --help output as a global option, but none of the three PRs updated the byte-exact snapshot fixture in LiquibaseCommandLineTest.expectedHelpOutput. Surfaces in liquibase-pro subtree-sync CI (LiquibaseCommandLineTest.'help output':854) once the sibling MSSQL regression (DAT-23093 / #7756) cleared and the Maven reactor advanced past liquibase-standard into liquibase-cli. Missed PRs (all merged into upstream main, all by the same author): #7747 CWE-78 allowExecuteCommand — declared at GlobalConfiguration:57 #7748 CWE-470 allowCustomChange — declared at GlobalConfiguration:56 #7750 CWE-22 allowParentDirectoryReferences — declared at GlobalConfiguration:58 Add three picocli-rendered stanzas to expectedHelpOutput at the alphabetical insertion points the renderer actually emits (captured verbatim from a local 'mvn test -Dtest=LiquibaseCommandLineTest#help output' run after the missing flags were declared): - --allow-custom-change=PARAM inserted BEFORE --allow-duplicated-changeset-identifiers (alphabetical: 'c' < 'd' within 'allow-*') - --allow-execute-command=PARAM inserted BETWEEN --allow-duplicated-changeset-identifiers and --allow-inherit-logical-file-path (alphabetical: 'd' < 'e' < 'i') - --allow-parent-directory-references=PARAM inserted BETWEEN --allow-inherit-logical-file-path and --always-drop-instead-of-replace (alphabetical: 'i' < 'p' within 'allow-*'; 'allow-*' < 'always-*' since 'l' < 'w' at position 2 of the suffix) Each stanza copies the description text VERBATIM from picocli's .usage() renderer — including picocli's specific line-wrap points, which depend on description length, terminal width assumptions, and where word boundaries fall. Hand-editing the stanzas would risk drifting from picocli's rendering on the next build; capturing them as picocli emits is the only way to keep the snapshot stable. Test: full liquibase-cli reactor passes (115 / 115 specs across ParameterUtilTest, CommandLineArgumentValueProviderTest, LiquibaseCommandLineProCommandTest, LiquibaseCommandLineTest (40 incl. 'help output'), LiquibaseCommandLineThreadingTest, LiquibaseLauncherTest, ProCommandErrorMessageTest). Once this merges and a follow-up subtree-sync pulls it into liquibase-pro, the 'help output' assertion at line 854 of the synced fixture file flips green. Note for the audit-batch follow-up: a similar fixture-drift gap will appear when the remaining open PRs in this batch (#7749 customPrecondition, #7753 sqlCheck, #7754 includeAll filter/comparator classes, #7755 external changelog paths) merge into main, because each declares a new GlobalConfiguration entry. Each of those PRs should ideally include its own LiquibaseCommandLineTest fixture update before merging; if any merge without one, a follow-up of this PR's shape will be needed for it.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe pull request updates ChangesCLI help text for security-related options
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~3 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…w allowExternalChangelogPaths flag This PR introduces ALLOW_EXTERNAL_CHANGELOG_PATHS in GlobalConfiguration (allowExternalChangelogPaths=true by default). The help-output snapshot reflects over all registered config definitions, so the new flag appears in --help and the fixture needs the matching block. Block captured byte-exact from picocli's actual --help output. Mirrors the #7760 pattern for the three already-merged ALLOW_* audit flags (this branch's merge from origin/main brought those in; this commit adds the fourth). Note on the UNC double-backslash: the description references the leading '\\' UNC path prefix. In Groovy triple-quoted source the inserted text is escaped as '\\\\' (four source backslashes → two runtime backslashes) so the runtime fixture matches picocli's literal output. The other 35 block lines apply verbatim. LiquibaseCommandLineTest 40/40 green locally.
…put for the new allowIncludeAllClasses flag This PR introduces ALLOW_INCLUDE_ALL_CLASSES in GlobalConfiguration (allowIncludeAllClasses=true by default), governing the includeAll resourceFilter/resourceComparator class-name attributes. The help-output snapshot reflects over all registered config definitions, so the new flag appears in --help and the fixture needs the matching block. Block captured byte-exact from picocli's actual --help output, inserted alphabetically between --allow-execute-command and --allow-inherit-logical- file-path. Mirrors the #7760 pattern for the three already-merged ALLOW_* audit flags (the merge from origin/main brought those in; this commit adds the fourth). LiquibaseCommandLineTest 40/40 green locally.
…w allowSqlPrecondition flag This PR introduces ALLOW_SQL_PRECONDITION in GlobalConfiguration (allowSqlPrecondition=true by default), governing the <sqlCheck> changelog precondition. The help-output snapshot reflects over all registered config definitions, so the new flag appears in --help and the fixture needs the matching block. Block captured byte-exact from picocli's actual --help output, inserted alphabetically after --allow-parent-directory-references and before --always-drop-instead-of-replace. Mirrors the #7760 pattern for the three already-merged ALLOW_* audit flags (merge from origin/main brought those in; this commit adds the fourth). LiquibaseCommandLineTest 40/40 green locally.
…7761) (#7764) * CWE-316: make CommandScope.clearCredentialArguments() opt-in — fixes #7761 The original CWE-316 fix (PR #7741, commit 4850342) added a `finally { clearCredentialArguments(); }` block at the end of CommandScope.execute() to overwrite credential-bearing argument values with "*****" so the original Strings would become GC-eligible after the command ran. That broke every caller that calls execute() more than once on the same CommandScope: the second call reads "*****" from argumentValues, passes it to the JDBC driver, and the driver rejects the connection with "FATAL: password authentication failed for user '<lbuser>'". Surfaced by liquibase.dbtest.pgsql.PostgreSQLIntegrationTest .testStatusRunDuringUpdate, which executes the same CommandScope three times (before / during / after a concurrent liquibase.update()). The first execution succeeded, the second failed with the password auth error. Upstream main has been red on this test since PR #7741 landed (2026-05-21 12:15 UTC); the regression became visible after the May-22+ subtree-sync attempts into liquibase-pro PR #3860 and again on upstream main after PR #7760 landed and freed the reactor to advance past liquibase-standard. Why the regression sat in main for four days ============================================ PR #7741 was authored from a fork. Upstream's run-tests.yml workflow gates its `authorize` job on `environment: external` whenever the PR's head repo differs from github.repository. That gate requires a maintainer to click "Review deployments → Approve and run" before the workflow can proceed. The gate was never approved on #7741's pre-merge build; the workflow sat in `status: waiting`; no Run Test for (Java N <OS>) or Integration Test (<db>) job ever materialised; the PR's 9 green checks were all from non-gated workflows (CodeQL / label / claude-review). The merge button did not block on a workflow that never produced any check at all. After merge, the post-merge `push` to main triggered the workflow with the `internal` environment (no manual approval needed). By that point the merge was already in. Same shape for PR #7760 (the DAT-23096 fixture fix that finally let the reactor advance past liquibase-cli to liquibase-integration-tests on the subtree-sync). Option A — opt-in clearing ========================== Three options were discussed in the upstream issue: A. Make the clearing opt-in: add clearCredentialArguments() as a public method on CommandScope; remove the finally block; call it explicitly at single-use call sites (e.g. Main's CLI runners). Preserves CWE-316 intent for CLI sessions without breaking long- lived / re-used scopes elsewhere. Recommended. B. Gate the clearing on a markSingleUse() flag (backwards-compatible default). Possible, but adds API surface and a state machine that's easy to forget. C. Clear on scope close rather than per-execute. Requires CommandScope to be AutoCloseable; bigger refactor; same forget- to-close risk as B. This PR implements Option A. The other two are not pursued. Changes ======= 1) CommandScope.java - Removed the outer `finally { clearCredentialArguments(); }` block from execute() (between the second-to-last catch and the closing brace at the method's bottom). - Changed clearCredentialArguments() from package-private to public so external callers can invoke it explicitly. - Updated both the CREDENTIAL_KEY_TOKENS doc comment and the clearCredentialArguments() method doc to document the new caller-invoked contract, including the specific re-use scenario that the auto-finally broke and the recommended try-finally pattern for single-use callers. 2) Main.java - Added a private static helper executeAndClearCredentials(CommandScope) that wraps execute() in try-finally + clearCredentialArguments() and returns CommandResults. Used in place of bare execute() at every CLI command-runner site (15 sites: snapshotCommand, dropAllCommand, calculateChecksumCommand, historyCommand, diffCommand, diffChangelogCommand, updateCommand, rollbackOneChangeSet (x2), rollbackOneUpdate (x2), executeSql, three bare commandScope.execute() sites). - Net effect: CLI users get the same CWE-316 protection they had before #7741's regression-causing fix landed, but the protection now lives at the call site (where the single-use assumption is true) rather than inside execute() (where the assumption was false for the integration tests and any library / programmatic caller that re-uses a scope). 3) CommandScopeTest.groovy - Updated the two existing specs that asserted auto-clearing in execute()'s finally to assert the new opt-in semantics (execute() alone does NOT touch credential values; explicit clearCredentialArguments() does). - Added a new regression spec "execute called twice on the same scope reads original credentials both times — regression for PostgreSQLIntegrationTest .testStatusRunDuringUpdate" that calls execute() three times on the same scope and uses a MockCommandStep that captures argumentValues["password"] each time the pipeline runs. All three captured values must equal the original credential. This is the unit-level regression coverage for the integration-test scenario that surfaced the bug — running it at unit speed means future re-introductions are caught at PR-author time without needing a live postgres in the loop. - Added a new spec "caller-invoked try-finally pattern around execute clears credentials post-execution (CWE-316 wiring documented for CLI integrators)" that demonstrates and pins the recommended usage pattern: the pipeline sees the original credential during execute(), and the credential is wiped immediately after the call returns. This is what Main.executeAndClearCredentials() does internally; the spec documents the contract so external callers have a reference. Tests ===== All passing locally on this branch: CommandScopeTest 22 / 22 (3 new specs) LiquibaseCommandLineTest 40 / 40 (incl. 'help output') liquibase-cli full reactor 115 / 115 liquibase-standard Command*-related 204 / 204 MainTest 32 / 32 (Total 413 specs across the directly-impacted set. Did not run the live- postgres integration tests locally — Docker not available; see the "Validation" section in the PR description.) Validation ========== Per the validation checklist filed alongside this fix (Pro internal DAT-23097 last comment, mirrored into the upstream issue), this PR needs explicit confirmation that the run-tests.yml workflow actually ran pre-merge. If reviewers see the workflow stuck in `status: waiting` on the `authorize` job, please click "Review deployments → Approve and run" before merging — that's the gate that previously hid both PR #7741 and PR #7760 regressions for days. Closes #7761. * CWE-316: empty commit to re-trigger gated CI workflows after maintainer review approval (#7763) * CWE-316: fix pre-existing no-op in runGenerateChangelogCommandStep `Main.runGenerateChangelogCommandStep()` built the CommandScope for the legacy CLI `generateChangelog` command but never called .execute() on it, making the command a silent no-op via the Main.java entry point. The bug predates this PR (also present on upstream main at 8ed8669) but CodeRabbit flagged it while reviewing the executeAndClearCredentials helper this PR introduces, so applying the fix here with that helper is the natural landing place.
…put for the new allowIncludeAllClasses flag This PR introduces ALLOW_INCLUDE_ALL_CLASSES in GlobalConfiguration (allowIncludeAllClasses=true by default), governing the includeAll resourceFilter/resourceComparator class-name attributes. The help-output snapshot reflects over all registered config definitions, so the new flag appears in --help and the fixture needs the matching block. Block captured byte-exact from picocli's actual --help output, inserted alphabetically between --allow-execute-command and --allow-inherit-logical- file-path. Mirrors the #7760 pattern for the three already-merged ALLOW_* audit flags (the merge from origin/main brought those in; this commit adds the fourth). LiquibaseCommandLineTest 40/40 green locally.
…w allowSqlPrecondition flag This PR introduces ALLOW_SQL_PRECONDITION in GlobalConfiguration (allowSqlPrecondition=true by default), governing the <sqlCheck> changelog precondition. The help-output snapshot reflects over all registered config definitions, so the new flag appears in --help and the fixture needs the matching block. Block captured byte-exact from picocli's actual --help output, inserted alphabetically after --allow-parent-directory-references and before --always-drop-instead-of-replace. Mirrors the #7760 pattern for the three already-merged ALLOW_* audit flags (merge from origin/main brought those in; this commit adds the fourth). LiquibaseCommandLineTest 40/40 green locally.
TL;DR
Three audit-batch PRs that landed in
mainrecently — #7747 (CWE-78allowExecuteCommand), #7748 (CWE-470allowCustomChange), #7750 (CWE-22allowParentDirectoryReferences) — each added a newGlobalConfiguration.builder.define()entry that picocli auto-renders into--helpoutput. None of those PRs updated the byte-exactexpectedHelpOutputsnapshot inLiquibaseCommandLineTest.groovy. This PR adds the three missing stanzas at the alphabetical positions picocli actually emits.Captured the stanzas verbatim from a local
mvn test -Dtest='LiquibaseCommandLineTest#help output'run; not hand-written, so the wrap points exactly match what picocli renders.Why this regression wasn't caught at PR-author time
picocli reflects over
LiquibaseConfiguration.getRegisteredDefinitions()at CLI startup (seeLiquibaseCommandLine.addGlobalArgumentsline 1203) and adds anOptionSpecper registered definition automatically. Authors of new flags get the--helprendering "for free" without touching CLI code, which is exactly when it's easy to forget there's a downstream snapshot test pinning every byte of that output.The snapshot is a single ~691-line inline string literal in
LiquibaseCommandLineTest, which doesn't show up in IDE call-graphs ofGlobalConfiguration.ALLOW_CUSTOM_CHANGE(it's literally just a string). Each of the three authors (same author, three different PRs) missed the linkage three times in a row.Why it surfaced in CI now, not before
Maven's reactor stops at the first module-level test failure. On the liquibase-pro subtree-sync runs,
liquibase-standard'sMSSQLDatabaseTest.getTargetUniquenessAttributes_allAuthMethods_produceSameUrlwas failing first (the regression fixed in #7756). The reactor never advanced toliquibase-cli, so this fixture gap stayed invisible. After #7756 merged and the subtree-sync was retried, the reactor advanced pastliquibase-standard, andLiquibaseCommandLineTest.'help output':854immediately tripped.The fix
Three new stanzas inserted at the alphabetical positions picocli emits:
--allow-duplicated-changeset-identifiers--allow-custom-change=PARAM(#7748 / CWE-470)--allow-duplicated-…and--allow-inherit-logical-file-path--allow-execute-command=PARAM(#7747 / CWE-78)--allow-inherit-logical-file-pathand--always-drop-instead-of-replace--allow-parent-directory-references=PARAM(#7750 / CWE-22)Alphabetical ordering rationale:
allow-*:c<d<e<i<p— socustom-changecomes first,parent-directory-referencescomes last.allow-*(a-l-l-o-w) <always-*(a-l-w-a-y-s) becausel<wat position 2 of the suffix.Each stanza is the verbatim output of picocli's
.usage()renderer for that flag, including picocli's specific line-wrap points. The stanzas are NOT hand-written. Hand-editing risks drifting from picocli's rendering on the next build — capturing them as picocli emits them is the only way to keep this snapshot stable.Captured-output methodology (for future fixture updates)
For anyone adding a new
GlobalConfigurationflag and needing to update this fixture:new File("target/help-output-actual.txt").text = bytes.toString()to the'help output'test'swhen:block.mvn test -Dtest='LiquibaseCommandLineTest#help output'— it'll fail, buttarget/help-output-actual.txtwill contain the full picocli output.expectedHelpOutput.This is the procedure I used to generate this PR.
Test plan
Full
liquibase-clireactor passes (115/115 specs acrossParameterUtilTest,CommandLineArgumentValueProviderTest,LiquibaseCommandLineProCommandTest,LiquibaseCommandLineTest40 incl.'help output',LiquibaseCommandLineThreadingTest,LiquibaseLauncherTest,ProCommandErrorMessageTest).Things to be aware of
Fixture-only change. No production behaviour change. The three flags themselves (their actual gating logic) were merged via CWE-78: opt-in restricted mode for executeCommand changelog change #7747/CWE-470: opt-in restricted mode for customChange changelog change #7748/CWE-22 deprecation flag: opt-in path containment via liquibase.allowParentDirectoryReferences #7750.
No new tests. This PR adds 71 lines to the existing snapshot literal; it doesn't add new specs. The existing 'help output' spec is the only consumer of
expectedHelpOutput.Forward-looking risk: the same fixture-drift gap will reappear when the remaining audit-batch PRs land in main, because each introduces a new
GlobalConfigurationentry:customPrecondition) — updates description of existingALLOW_CUSTOM_CHANGE, will drift the stanza I added in this PRsqlCheck→ALLOW_SQL_PRECONDITION)includeAllfilter/comparator →ALLOW_INCLUDE_ALL_CLASSES)ALLOW_EXTERNAL_CHANGELOG_PATHS)Each should ideally include its own fixture update before merging. If any merge without one, a follow-up of this PR's shape will be needed for it. Adding a release-process note / PR-template checkbox to enforce this is filed as a separate TECHOPS follow-up.
Coordination
LiquibaseCommandLineTest.'help output'after this PR merges and a follow-up subtree-sync pulls it in.PostgreSQLIntegrationTest.testStatusRunDuringUpdateNPE inAlternateConnectionExecutor.<init>) is a pre-existing test-fixture wiring issue, unrelated to this PR.Related
allowExecuteCommand(the original PR that should have updated the fixture)allowCustomChange(same)allowParentDirectoryReferences(same)Part of the May-2026 OSS credential-handling-and-changelog-injection audit slice (
sdoulabel).