Skip to content

fix(installer): gitignore default _bmad/config.user.toml#2464

Open
bdsoha wants to merge 6 commits into
bmad-code-org:mainfrom
bdsoha:fix/gitignore-default-user-config
Open

fix(installer): gitignore default _bmad/config.user.toml#2464
bdsoha wants to merge 6 commits into
bmad-code-org:mainfrom
bdsoha:fix/gitignore-default-user-config

Conversation

@bdsoha

@bdsoha bdsoha commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

What

Seed _bmad/.gitignore with config.user.toml during install so the default user config is gitignored, matching the existing _bmad/custom/.gitignore rule for custom/*.user.toml.

Why

_bmad/config.user.toml holds personal, machine-specific install answers — the same kind of content already ignored under custom/. It was being left tracked, so personal config could be committed by accident.

Fixes #2456

How

  • Extend _installSharedScripts to call a new _ensureUserConfigGitignored helper after seeding the custom .gitignore.
  • The helper creates _bmad/.gitignore when missing, or appends the entry to an existing file that doesn't list it — so the rule reaches both fresh installs and updates of older projects without duplicating the line.

Testing

Added Test Suite 46 to test/test-installation-components.js covering the fresh-seed, idempotent re-install, and append-to-existing cases. Full npm test suite passes.

The installer seeded _bmad/custom/.gitignore so custom/*.user.toml
overrides stayed out of version control, but left the default
_bmad/config.user.toml — which holds the same personal install
answers — uncovered. Seed _bmad/.gitignore during install so both
user config locations behave consistently.

Fixes bmad-code-org#2456
@augmentcode

augmentcode Bot commented Jun 11, 2026

Copy link
Copy Markdown
🤖 Augment PR Summary

Summary: This PR ensures the per-user installer answers in _bmad/config.user.toml don’t get accidentally committed by automatically seeding/updating _bmad/.gitignore during install.

Changes:

  • Extend _installSharedScripts to also manage _bmad/.gitignore (in addition to _bmad/custom/.gitignore)
  • Add _ensureUserConfigGitignored helper to create or append the config.user.toml ignore rule without duplication
  • Add Test Suite 46 covering fresh install seeding, idempotent re-install, and append-to-existing behavior

Why: Aligns root user config handling with existing custom/*.user.toml ignore behavior to reduce accidental check-ins.

🤖 Was this summary useful? React with 👍 or 👎

@augmentcode augmentcode Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Review completed. 2 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

Comment thread tools/installer/core/installer.js Outdated

if (await fs.pathExists(gitignorePath)) {
const existing = await fs.readFile(gitignorePath, 'utf8');
if (existing.split(/\r?\n/).some((line) => line.trim() === entry)) return;

@augmentcode augmentcode Bot Jun 11, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

At if (existing... ) return, the early return skips this.installedFiles.add(gitignorePath), so on later installs with a fresh Installer instance _bmad/.gitignore can drop out of files-manifest.csv and be misclassified as custom/modified.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

scriptsDir: path.join(bmadDir46, 'scripts'),
};

const installer46 = new Installer();

@augmentcode augmentcode Bot Jun 11, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This suite reuses the same Installer instance across multiple _installSharedScripts calls; since real installs typically create a new Installer per run, this may miss regressions where _bmad/.gitignore isn’t re-tracked/manifested once it already contains config.user.toml.

Severity: low

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR resolves a bug where _bmad/config.user.toml was not automatically gitignored during installation. A new helper method ensures both user config locations (_bmad/.gitignore and _bmad/custom/.gitignore) keep personal configuration out of version control, with idempotent duplicate prevention and comprehensive test coverage.

Changes

User Config Gitignore Installation

Layer / File(s) Summary
User config gitignore helper implementation
tools/installer/core/installer.js
Added _ensureUserConfigGitignored(bmadDir) method that creates _bmad/.gitignore if missing and conditionally appends the config.user.toml ignore rule while preventing duplicates. Updated _installSharedScripts() documentation and integrated the helper call.
Idempotent gitignore seeding test
test/test-installation-components.js
Test Suite 46 exercises _installSharedScripts to verify .gitignore creation, correct ignore rule insertion, preservation of existing entries, and idempotent re-runs without duplicate lines.

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: adding config.user.toml to .gitignore in the _bmad directory during installation.
Description check ✅ Passed The description is well-detailed and directly related to the changeset, explaining what, why, and how the changes address the issue.
Linked Issues check ✅ Passed The pull request fully addresses issue #2456 by implementing .gitignore seeding for _bmad/config.user.toml during installation with idempotent behavior and comprehensive tests.
Out of Scope Changes check ✅ Passed All changes are directly related to the stated objective of ensuring _bmad/config.user.toml is gitignored; no out-of-scope modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install timed out. The project may have too many dependencies for the sandbox.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tools/installer/core/installer.js`:
- Around line 703-706: When .gitignore already exists and contains the entry,
the code returns early and never records the managed file in installedFiles;
update the installedFiles tracking (e.g., push or add gitignorePath or the
managed-file identifier into installedFiles) before returning from the
existing-entry branch (the block using gitignorePath, existing, entry), and
likewise ensure the branch that creates/writes the file (the later code that
writes when it didn't exist) also records the file into installedFiles (both
branches should call the same installedFiles update). Use the existing symbols
gitignorePath, entry, existing, and installedFiles (or the project’s
install-recording helper) to locate and add the tracking update so
manifest/file-tracking is consistent regardless of prior disk state.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ce671663-895d-4bd2-841b-4fd9268cd7f5

📥 Commits

Reviewing files that changed from the base of the PR and between fbb48ed and 10288d2.

📒 Files selected for processing (2)
  • test/test-installation-components.js
  • tools/installer/core/installer.js

Comment thread tools/installer/core/installer.js Outdated
Comment on lines +703 to +706
if (await fs.pathExists(gitignorePath)) {
const existing = await fs.readFile(gitignorePath, 'utf8');
if (existing.split(/\r?\n/).some((line) => line.trim() === entry)) return;
const separator = existing.length > 0 && !existing.endsWith('\n') ? '\n' : '';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

installedFiles tracking is skipped when .gitignore already has the rule.

If _bmad/.gitignore already contains config.user.toml, Line 705 returns before Line 711, so this managed file is not recorded in installedFiles. That makes manifest/file-tracking state depend on prior disk state.

Suggested fix
   async _ensureUserConfigGitignored(bmadDir) {
     const gitignorePath = path.join(bmadDir, '.gitignore');
     const entry = 'config.user.toml';

     if (await fs.pathExists(gitignorePath)) {
       const existing = await fs.readFile(gitignorePath, 'utf8');
-      if (existing.split(/\r?\n/).some((line) => line.trim() === entry)) return;
-      const separator = existing.length > 0 && !existing.endsWith('\n') ? '\n' : '';
-      await fs.writeFile(gitignorePath, `${existing}${separator}${entry}\n`, 'utf8');
+      if (!existing.split(/\r?\n/).some((line) => line.trim() === entry)) {
+        const separator = existing.length > 0 && !existing.endsWith('\n') ? '\n' : '';
+        await fs.writeFile(gitignorePath, `${existing}${separator}${entry}\n`, 'utf8');
+      }
     } else {
       await fs.writeFile(gitignorePath, `${entry}\n`, 'utf8');
     }
     this.installedFiles.add(gitignorePath);
   }

Also applies to: 711-711

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tools/installer/core/installer.js` around lines 703 - 706, When .gitignore
already exists and contains the entry, the code returns early and never records
the managed file in installedFiles; update the installedFiles tracking (e.g.,
push or add gitignorePath or the managed-file identifier into installedFiles)
before returning from the existing-entry branch (the block using gitignorePath,
existing, entry), and likewise ensure the branch that creates/writes the file
(the later code that writes when it didn't exist) also records the file into
installedFiles (both branches should call the same installedFiles update). Use
the existing symbols gitignorePath, entry, existing, and installedFiles (or the
project’s install-recording helper) to locate and add the tracking update so
manifest/file-tracking is consistent regardless of prior disk state.

bdsoha and others added 5 commits June 11, 2026 23:19
Address review: the early return when config.user.toml was already
ignored skipped installedFiles.add, dropping _bmad/.gitignore from
files-manifest.csv on re-installs. Suite 46 now uses a fresh Installer
per run, as production does, so the regression is actually exercised.
…-user-config

# Conflicts:
#	test/test-installation-components.js
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Default _bmad/config.user.toml file is not ignored during installation

2 participants