Skip to content

Latest commit

 

History

History
136 lines (97 loc) · 9.5 KB

AGENTS.md

File metadata and controls

136 lines (97 loc) · 9.5 KB

Beachball copilot instructions

Trust these instructions. Only search the codebase if information here is incomplete or found to be in error (notify the user if an error is found). Following these steps will minimize failed commands and CI rejections.

What this repo is

Beachball is a CLI tool for automating semantic version bumping, changelog generation, and npm publishing in monorepos and single-package repos. This repo is a Yarn 4 monorepo of ~2,000 files. The main deliverable is the beachball npm package.

  • Runtime: Node.js >=22.23.4 (repo developed on Node 22; CI also runs Node 24). TypeScript files can be run directly with node (no extra flags).
  • Language: TypeScript ~6.0. The beachball and p-graph package output is CommonJS (other packages use ESM).
  • Package manager: Yarn 4 (Berry), nodeLinker: node-modules. Some dependency versions are shared via Yarn catalogs (catalogs in .yarnrc.yml). Never use npm install.
  • Task runner: lage orchestrates build, test, lint across workspaces (config: lage.config.js).
  • Testing: Jest 30 via Babel.
  • Linting/formatting: ESLint 9 flat config + Prettier.
  • Dependency consistency: syncpack + depcheck.

Branches

  • main (default): development for beachball v3 (alpha). Breaking changes allowed.
  • v2: current stable release. Non-breaking changes should target v2.

Build and validation commands

Always run yarn --immutable first if dependencies may be out of date.

Repo root commands

When validating the entire repo, run the following commands in order:

Step Command Notes / timing (validated)
Install yarn --immutable Required before any build/test/lint.
Build yarn build ~8s. Runs lage build bundle across all workspaces.
Lint yarn lint ~10s. Runs eslint + depcheck + syncpack via lage.
Test (all) yarn test Runs all workspace tests via lage.
Update snapshots yarn update-snapshots Use after intentional output changes.

Do NOT run jest or tsc directly from the repo root. yarn build and yarn lint must succeed with zero warnings.

The pre-commit hook runs Prettier (yarn format) automatically on all staged files using lint-staged. Do not manually run yarn format, Prettier, or a formatting check after routine edits. Run formatting commands only when explicitly requested, when preparing a PR without committing locally, or when diagnosing a formatting failure.

Package-level commands

When developing in a single package, use these commands first before building/validating the entire repo. Run cd packages/<name> then:

Task Command
Build a single package yarn build
Test (packages other than beachball) yarn test
(beachball) All tests, correct order yarn test:all
(beachball) All unit tests yarn test:unit (~3s)
(beachball) All functional tests yarn test:func
(beachball) All E2E tests yarn test:e2e (slow)
Single test file/name (wraps jest), ANY package yarn test <path or name>
Update snapshots yarn update-snapshots

In the beachball package, do NOT use test:* commands to run a single test. Use yarn test <path or name>.

Prefer scripts over running binaries directly. If you must run a binary such as jest, use yarn run -T <binary>.

Required before each commit

Run all of: yarn build, yarn test, and yarn lint. Prettier runs automatically in the pre-commit hook.

Required before creating a PR

  • Use the /beachball-change-file skill to generate a Beachball change file if needed. Sometimes it's not needed, but verify by running yarn checkchange (CI also runs this).
  • Check whether documentation site or CLI help text updates are needed.

Repo layout

  • packages/beachball — main package (see architecture below).
  • packages/p-graph — promise graph runner, used by beachball.
  • packages/proper-changelog — changelog/release notes helper.
  • packages/esrp-npm-release — helper for the Microsoft release process.
  • scripts — repo-internal scripts (@microsoft/beachball-scripts); shared build/test/eslint config lives in scripts/config.
  • actions/* — GitHub Action definitions (check-for-modified-files, install-beachball, should-release); their dist/ is committed and must be rebuilt via yarn build+yarn bundle if src changes.
  • yarn-plugins/* — Yarn v4 plugins (engines, npmrc) loaded by the repo's own .yarnrc.yml. Each builds a bundle via yarn build+yarn bundle into a committed dist/plugin.js, which must be rebuilt and committed if src changes. See yarn-plugins/README.md.
  • renovate/ - Renovate presets migrated from m365-renovate-config; scripts under renovate/scripts; presets under renovate/presets; auto-updated readme
  • docs/ — Vuepress documentation site with its own separate Yarn install.
  • change/ — pending Beachball change files (JSON).
  • Root config: beachball.config.js, lage.config.js, syncpack.config.js, .prettierrc.json5, .yarnrc.yml. Per-package: tsconfig.json, jest.config.js, eslint.config.*.

beachball package architecture (paths under packages/beachball)

  • Entry point: src/cli.ts dispatches commands: check, change, bump, publish, canary, sync, init, config.
  • src/commands/ — command implementations.
  • src/bump/ — version bump calculation (bumpInMemory is the core algorithm).
  • src/changefile/ — reading/writing/prompting for change files.
  • src/changelog/ — changelog generation (markdown + JSON).
  • src/monorepo/ — package discovery (workspace-tools), dependency graph, package groups.
  • src/publish/ — npm publish orchestration, git tagging, dependency-ordered publishing.
  • src/git/ — git operation wrappers using nano-spawn.
  • src/options/ — CLI arg parsing + config loading.
  • src/validation/ — pre-command validation.
  • src/types/ — TypeScript interfaces (BeachballOptions is the central config type).
  • Option resolution: CLI args > config (usually beachball.config.js) > defaults. getOptions() returns both raw cliOptions and merged options.

Coding standards

  • No global state: process.cwd(), process.chdir(), and process.exit() are banned via ESLint. Pass an explicit cwd. process.exit() may only be used in cli.ts.
  • Imports: use import "fs/promises" directly (not fs.promises) to enable Jest mocking. Use import type for type-only imports (enforced).
  • Naming: camelCase or PascalCase; unused parameters prefixed with _.
  • Style: Prettier — single quotes, 120 char width, ES5 trailing commas.
  • Markdown: use sentence case for headings. NEVER manually wrap lines in .md files (except within code blocks).

Testing standards

packages/beachball has three Jest projects: unit (src/__tests__/, no filesystem), functional (src/__functional__/, realistic setups / real filesystem), e2e (src/__e2e__/, full commands, uses verdaccio). Fixtures/mock factories are in src/__fixtures__/.

  • Import Jest APIs from @jest/globals (no implicit globals).
  • Prefer real generator functions or __fixtures__ helpers over hand-building complex objects (PackageInfos, ChangeInfo, BumpInfo, BeachballOptions).
  • When testing a function with complex parameters, consider creating a wrapper function in the test which fills in common defaults.
  • Any test that writes to the console must call initMockLogs().
  • Beachball's logs are its UI. Often, tests should include complete inline snapshots of output (especially if it's only a few lines).
  • Prefer complete value assertions (toEqual({...}), toEqual([...])) over partial matchers.

Documentation site

Vuepress site under docs/ with a separate Yarn install. (Ignore docs/v2/ when reading or updating documentation unless the task explicitly targets the v2 docs.)

To edit/validate:

  1. cd docs && yarn --immutable (install docs deps first).
  2. yarn docs:build to validate.
  3. When adding a new page, you MUST add it to the sidebar in docs/.vuepress/config.ts.

You must update the doc site when adding a new option or command.

CI checks (must pass before merge)

Defined in .github/workflows/pr.yml. Replicate locally with the commands above.

  • build job (ubuntu + windows, node 22/npm 10 and node 24/npm 11): yarn --immutable, yarn build --verbose, yarn checkchange --verbose, yarn format:check and yarn lint --verbose (ubuntu/node22 only), yarn test --verbose, plus extra Windows-bash tests.
  • actions job: builds, then runs check-for-modified-files — if action dist/ changed, run yarn build and commit the updated dist files.
  • docs job: cd docs && yarn --immutable && yarn docs:build.