This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Beachball is a CLI tool for automating semantic version bumping, changelog generation, and npm publishing in monorepos and single-package repos.
v2: the current stable release branch frombeachball@latestand the doc site are published.main: contains development work for the next major release of beachball, version 3. Breaking changes are allowed if necessary.
packages/beachball:beachballpackagescripts: repo-internal scripts (@microsoft/beachball-scripts)
These commands work at the top level of the monorepo.
DO NOT run jest or tsc directly from the top level!
| Task | Command |
|---|---|
| Build | yarn build |
| Run all tests (NOT a specific test) | yarn test |
| Lint (code + deps) | yarn lint |
| Lint code only | yarn lint:code |
| Format | yarn format |
| Update snapshots | yarn update-snapshots |
These commands work in an individual package (cd packages/<name>).
| Task | Command |
|---|---|
| Build | yarn build |
Test (packages other than beachball) |
yarn test |
| Single test file (wraps jest) | yarn test <test path or name> |
(beachball) All tests in correct order |
yarn test:all |
(beachball) Unit tests only |
yarn test:unit |
(beachball) Functional tests only |
yarn test:func |
(beachball) E2E tests only |
yarn test:e2e |
| Lint | yarn lint |
| Update snapshots | yarn update-snapshots |
All these paths refer to the beachball package under packages/beachball.
Entry point: src/cli.ts dispatches to commands: check, change, bump, publish, canary, sync, init, config.
Key modules:
src/commands/- Command implementationssrc/bump/- Version bump calculation (bumpInMemoryis the core algorithm)src/changefile/- Reading/writing/prompting for change files (JSON inchange/dir)src/changelog/- Changelog generation (markdown and JSON)src/monorepo/- Package discovery via workspace-tools, dependency graph, package groupssrc/publish/- npm publish orchestration, git tagging, dependency-ordered publishingsrc/git/- Git operation wrappers using execasrc/options/- CLI arg parsing (yargs-parser) + config loading (cosmiconfig)src/validation/- Pre-command validation (change file presence, dependency checks)src/types/- TypeScript interfaces (BeachballOptionsis the central config type)
Option resolution: CLI args > beachball.config.js (via cosmiconfig) > defaults. getParsedOptions() returns both raw cliOptions and merged options.
No global state: process.cwd(), process.chdir(), and process.exit() are banned via ESLint. All operations take an explicit cwd parameter. process.exit() should only be called in cli.ts.
Imports: Use import "fs/promises" directly, not fs.promises (enables Jest mocking). Use import type for type-only imports (enforced).
Naming: Variables use camelCase or PascalCase. Unused parameters prefixed with _.
Test rules: Tests must import Jest APIs from @jest/globals (don't use implicit jest globals).
Style: Prettier with single quotes, 120 char width, trailing commas (ES5)
- You must update the documentation site when adding a new option or command
- Also consider whether documentation site updates are needed for other new features or behavior changes
- All headings in the documentation site and other markdown files must use sentence case
yarn buildyarn testyarn lintyarn format
- Use
/beachball-change-filesto generate a Beachball change file. - Check whether any documentation site or help text updates are needed for the change.
packages/beachball has three Jest projects:
- Unit (
src/__tests__/): Unit tests for individual functions (no filesystem) - Functional (
src/__functional__/): Single-function tests with realistic setups, or unit-like tests which must run against the actual filesystem - E2E (
src/__e2e__/): E2E tests covering major scenarios and entire commands
Test helpers in src/__fixtures__/ provide mock factories for repos, logs, package infos, and change files.
- Avoid manually creating complex object structures (such as
PackageInfos,ChangeInfo,BumpInfo, orBeachballOptions). Consider one of the following approaches instead:- call the real function for generating the structure if possible
- check if there's a helper under
__fixtures__ - check for a common pattern for creating/mocking this object in other tests
- When testing a function with complex parameters, consider creating a wrapper function in the test which fills in common defaults.
- Any test of a function which writes to the console should call
initMockLogs()to mock and capture output. - Beachball's logs are its UI. Often, tests should include complete inline snapshots of output (especially if it's only a few lines).
- Where reasonable, prefer complete tests of values:
expect(someObj).toEqual({...})rather thanexpect(someObj.foo).toEqual(...)orexpect(someObj).toMatchObject({...}), orexpect(someArray).toEqual([...])rather thanexpect(someArray).toContain(...)
The doc site uses Vuepress and is located under /docs. It uses a separate yarn installation to keep the docs dependencies separate.
- If running in a standalone agent environment, you must run
cd docs && yarnto install dependencies first - Doc changes can be validated with
cd docs && yarn docs:build - If adding a new page, you MUST add it to the sidebar in
docs/.vuepress/config.ts.