Skip to content

fix(cli): ship db/ in wheels-base-template by whitelisting db/.keep#3188

Closed
wheels-bot[bot] wants to merge 1 commit into
developfrom
fix/bot-3174-wheels-base-template-package-omits-the-db-director
Closed

fix(cli): ship db/ in wheels-base-template by whitelisting db/.keep#3188
wheels-bot[bot] wants to merge 1 commit into
developfrom
fix/bot-3174-wheels-base-template-package-omits-the-db-director

Conversation

@wheels-bot

@wheels-bot wheels-bot Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Summary

The published wheels-base-template zip shipped without the conventional db/ directory, so SQLite/H2 file paths under db/ failed without a manual mkdir. Root cause: tools/build/base/.gitignore (copied into the build dir as the package .gitignore by prepare-base.sh) carried a /db/** rule, and CommandBox package publish honors .gitignore — so db/.keep was silently stripped from the artifact even though prepare-base.sh:34 copies db/ in.

This whitelists !/db/.keep in that ignore file so the directory marker ships while end-user db files stay ignored. The drop-/db/**-entirely alternative would un-ignore users' SQLite files — the whitelist re-includes only the keep file, so no unwanted files re-enter the package. A new structural guard spec pins the ignore file against regression.

Related Issue

Refs #3174

Using Refs (not Fixes): the issue also asks for a publish-time presence assertion in the release workflow's "Validate Package Structure" step. That hardening touches .github/workflows/release.yml, which the wheels-bot GitHub App token cannot push without the workflows permission (the push was rejected). It is deferred to a human follow-up so the merge does not auto-close the tracking issue while that piece is still pending. The .gitignore whitelist here is the actual root-cause fix that makes db/ ship.

Type of Change

  • Bug fix
  • New feature
  • Enhancement to existing feature
  • Documentation update
  • Refactoring

Feature Completeness Checklist

  • DCO sign-off -- commit carries Signed-off-by:
  • Tests -- vendor/wheels/tests/specs/cli/BaseTemplateDbDirectoryShipsSpec.cfc (failing → passing)
  • Framework Docs -- handled separately by bot-update-docs.yml
  • AI Reference Docs -- handled separately by bot-update-docs.yml
  • CLAUDE.md -- handled separately by bot-update-docs.yml
  • Changelog fragment -- changelog.d/3174-base-template-db-directory.fixed.md
  • Test runner passes -- see Test Plan

Test Plan

The fix touches build/packaging source (.gitignore) and a pure-structural CFML guard spec (fileRead + regex, no DB/server). The spec asserts:

  1. db/.keep exists for prepare-base.sh to copy.
  2. tools/build/base/.gitignore does not strip db/.keep — if /db/** is present, !/db/.keep must follow.

Fail→pass verified by source analysis: pre-fix, assertion (2) failed (.gitignore was exactly /vendor/*/ + /db/**, no re-include); post-fix the !/db/.keep line is present and matches the spec's anchored regex.

Note on local execution: the server-backed bash tools/test-local.sh cli runner could not execute in the bot sandbox — the wheels binary is not installed (only the unbranded lucli runtime, which is permission-blocked per the bot rails). CI runs the full suite across every engine × DB on this PR for the authoritative signal. The spec is purely structural (no datasource/server dependency), so its logic was verified directly against source.

Screenshots / Output

n/a

The published wheels-base-template zip omitted the conventional db/ directory
because tools/build/base/.gitignore carried a /db/** rule and CommandBox
package publish honors .gitignore, silently stripping db/.keep. SQLite/H2
file paths under db/ then failed without a manual mkdir.

Whitelist !/db/.keep so the directory marker ships while end-user db files
stay ignored, and add a structural guard spec pinning the ignore file.

A paired presence assertion in release.yml's Validate Package Structure step
is deferred to a human follow-up: the wheels-bot GitHub App token cannot push
.github/workflows changes without the workflows permission.

Refs #3174

Signed-off-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
@wheels-bot

wheels-bot Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor Author

Wheels Bot — No doc updates

Reviewed this PR's diff and found no docs that need updating (purely internal build/packaging bug fix — restores the db/ directory to the published template; no new conventions, public API surface, or user-facing behavior changed that would warrant guide or reference-doc edits).

@wheels-bot wheels-bot Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Wheels Bot — Reviewer

TL;DR: This PR fixes the #3174 root cause — the published wheels-base-template zip lost its db/ directory because tools/build/base/.gitignore's /db/** rule stripped db/.keep at publish time — by whitelisting !/db/.keep, pinned by a new structural guard spec plus a changelog fragment. The fix is correct as far as it can be verified from source, the spec follows the suite's established structural-guard patterns, and the commit is clean. Verdict: comment — two minor, non-blocking test-robustness notes below; nothing blocks merge.

What was verified

  • gitignore semantics are right. Per the gitignore documentation, a trailing /** matches everything inside a directory but not the directory itself, so the re-include restriction ("it is not possible to re-include a file if a parent directory of that file is excluded") does not apply: /db/** + !/db/.keep is the canonical keep-an-empty-directory pattern. The PR also correctly rejected the drop-/db/** alternative, which would un-ignore end users' SQLite files.
  • Root-cause chain checks out. tools/build/scripts/prepare-base.sh:34 is indeed cp -r db "${BUILD_DIR}/", db/.keep is tracked at the repo root, and line 60 copies tools/build/base/.gitignore into the build dir as the package .gitignore — matching the issue's analysis.
  • Spec follows suite prior art. expandPath("/wheels/../..") + describe-body var + fileRead/regex mirrors buildArtifactLicenseSpec.cfc:22 and LinuxPackageStagingSpec.cfc:33. Cross-engine regex portability is established: (?m) is used in RateLimiterMemoryStoreSpec.cfc:95 and POSIX [[:space:]] in LinuxPackageStagingSpec.cfc:184-188 (which documents the BoxLang/Java translation) — both green across the CI matrix.
  • # escaping is correct. The failure message uses issue ##3174 inside the string literal (the unescaped-#-crashes-the-suite gotcha from CLAUDE.md § Test-specific gotchas); bare #3174 appears only in // comments, which is safe.
  • Changelog fragment changelog.d/3174-base-template-db-directory.fixed.md uses a valid type and avoids a direct CHANGELOG.md edit.

Tests

  1. Guard scope gap (minor): the spec only protects the exact /db/** form. vendor/wheels/tests/specs/cli/BaseTemplateDbDirectoryShipsSpec.cfc:47-51:

    var ignoresDb = reFindNoCase("(?m)^[[:space:]]*/db/\*\*[[:space:]]*$", src) > 0;
    ...
    expect(!ignoresDb || reIncludesKeep).toBeTrue(

    If a future edit rewrites the rule as /db/ (the directory form — exactly what the repo-root .gitignore:29 uses) or unanchored db/**, ignoresDb is false, the !ignoresDb || reIncludesKeep expression short-circuits true, and the spec passes — but !/db/.keep cannot re-include through a /db/ directory exclusion (gitignore: re-inclusion is impossible when a parent directory is excluded), so the artifact would silently lose db/ again. Suggested hardening: detect any db-ignore form, e.g. reFindNoCase("(?m)^[[:space:]]*/?db/", src), and fail outright when the directory form (/db/ with no **) is present, since no whitelist can rescue it. Non-blocking — the guard is correct for the file as it stands today.

  2. Effectiveness at publish time is unproven by this spec (acknowledged in the PR, non-blocking). The spec is structural — it pins the ignore file's contents, not the published artifact. Whether CommandBox's package publish ignore matcher honors ! negation can only be conclusively confirmed at the next publish. The PR's deferred follow-up (a db/ presence assertion in release.yml's "Validate Package Structure" step, blocked on the bot token's missing workflows permission) is the real end-to-end guard — recommend a maintainer pick that up before the next release cut so a silent negation no-op surfaces at publish time rather than via user reports.

Commits

No findings — single commit, valid conventional header (fix(cli): …, 68 chars), body explains the why, Signed-off-by matches the author identity, and Refs (not Fixes) is correctly used so the merge doesn't auto-close #3174 while the workflow hardening is pending.

@bpamiri

bpamiri commented Jun 13, 2026

Copy link
Copy Markdown
Collaborator

Superseded by #3196 (merged): a propose-fix draft that raced the ForgeBox path-repair campaign for the same issue; the campaign PR landed first and closed the underlying issue. Closing the duplicate.

@bpamiri bpamiri closed this Jun 13, 2026
@bpamiri bpamiri deleted the fix/bot-3174-wheels-base-template-package-omits-the-db-director branch June 13, 2026 04:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant