Skip to content

Latest commit

 

History

History
194 lines (132 loc) · 7.68 KB

File metadata and controls

194 lines (132 loc) · 7.68 KB

Contributing

Thanks for helping users adopt the latest features with your codemods!

Using an AI coding agent (Codex, Cursor, Claude Code, Aider, etc.)? See AGENTS.md for codemod authoring guidance and common mistakes to avoid.

Development setup

This repository uses pnpm (see packageManager in the root package.json), Changesets for releases, and oxfmt + oxlint (not Prettier/ESLint) for formatting and linting.

# Install dependencies (also wires the Husky pre-commit hook)
pnpm install

# Format all files
pnpm run format

# Check formatting without writing
pnpm run format:check

# Lint all files
pnpm run lint

# Lint and auto-fix
pnpm run lint:fix

# Run all codemod package tests
pnpm run test

# Typecheck all codemod scripts (root tsconfig)
pnpm run check-types

# Same checks as CI (tests + typecheck)
pnpm run ci

# Verify URLs in tracked Markdown
pnpm run docs:links

Run one workspace package (the pnpm --filter value is the name field in that package's package.json):

pnpm --filter <package-name> test

For example:

pnpm --filter sample-codemod test

Typechecking runs once from the repository root via pnpm run check-types (see root tsconfig.json).

Use Node 22 locally (see .nvmrc) to match CI.

Pre-commit hook

After pnpm install, Husky runs lint-staged before each commit: oxfmt and oxlint on staged files, plus targeted pnpm test when you touch codemods/**/scripts/**/*.ts. If something fails, fix or stage the updates and try again.

The hook only inspects staged files. CI runs full-repo format, lint, and typecheck on every pull request, so unchanged files can still fail there even if the hook passed.

CI

Three workflows support quality and releases:

  • ci.yaml — Pull request checks: runs on Ubuntu for PRs to main. Format, lint, and typecheck run across the full repo. Tests run only for codemod packages changed in the PR, or the full test suite when root tooling files change (for example package.json, pnpm-lock.yaml, or the workflow itself).
  • release.yml + publish.yml — Release automation: see Release workflow below.

Match the local checks (pnpm run format, pnpm run lint, pnpm run ci) before you push.

Before you open a PR

  • Issue: Check for an existing issue, or open one first.
  • Safety: Codemods must be safe, predictable, and idempotent (running twice should not change code again). Avoid mixing patterns with different safety levels.
  • Naming: In codemod.yaml, the codemod name must start with @<scope>, where <scope> is this repo's GitHub org.
  • Tests: Add multiple fixtures (positive and negative).
  • Docs: Update the README for your codemod.

Making changes

  1. Create a branch from main.
  2. Make your changes and add or update fixtures under tests/<case>/.
  3. Run pnpm run format, pnpm run lint, and pnpm run ci to verify everything passes.
  4. Add a changeset for every codemod package you touched (see below).
  5. Open a pull request.

Adding a changeset

This repo uses Changesets for versioning and releases. Every PR that changes a codemod package under codemods/ should include a changeset, unless you use the skip-changeset label (see CI). Details live in .changeset/README.md.

pnpm changeset

Follow the prompts:

  1. Select the affected codemod(s).
  2. Choose the semver bump — patch for fixes, minor for new features, major for breaking changes.
  3. Write a short summary.

Commit the new Markdown file under .changeset/ with your PR.

pnpm run version-packages (run by automation on main, not usually by hand) runs changeset version, which bumps version in each affected package.json. Do not edit version in package.json by hand — automation owns that field.

Release workflow

Releases are fully automated via .github/workflows/release.yml and .github/workflows/publish.yml on every push to main:

  1. Merge a PR that includes one or more changesets into main.
  2. The release job detects the pending changesets and runs pnpm run version-packages (changeset version), which bumps version in each affected package.json.
  3. The bot opens (or updates) a Version Packages pull request on branch changeset-release/version-packages — it does not push directly to main.
  4. Merge that PR (required checks apply like any other PR).
  5. On the next push to main, scripts/tag-and-publish.sh creates a <name>@v<version> git tag for every bumped package and pushes the tags.
  6. The publish job fans out a parallel matrix over the changed directories and publishes each codemod via codemod/publish-action.

For emergencies (re-publish a specific codemod without a full release cycle), use the Publish Codemod (Manual) workflow (.github/workflows/publish.yml) and supply the codemod slug.

Do not hand-edit version in package.json to simulate a release — automation owns bumps.

Adding a new codemod

Scaffold a new codemod with the CLI:

npx codemod init

New packages live under codemods/, for example:

codemods/<slug>/
  scripts/codemod.ts   # JSSG transform
  tests/               # input / expected fixtures
  codemod.yaml         # manifest
  workflow.yaml
  package.json
  README.md
  SKILL.md

Conventions:

  • The codemod name in codemod.yaml and package.json must start with @<scope> (e.g. @myorg/my-codemod).
  • Keep rewrites conservative. If a step requires a human decision, prefer a detector or recipe parameter over an unsafe transform.
  • Use an existing sibling codemod as a template. See docs/CODEMOD-TEMPLATE.md for the full package spec.

Test your codemod locally against a sample project:

cd /path/to/sample/project
npx codemod workflow run -w /path/to/my-codemod/workflow.yaml

Package shape

Each codemod package should include:

  • package.json with at least a test script.
  • codemod.yaml, workflow.yaml, README.md, SKILL.md
  • scripts/codemod.ts
  • tests/<case>/input.* and tests/<case>/expected.*

Keep transformations atomic and verifiable with fixtures.

Checks

Command What it does
pnpm run format Auto-format with oxfmt
pnpm run format:check Check formatting (no writes)
pnpm run lint Lint with oxlint (type-aware)
pnpm run lint:fix Lint and auto-fix with oxlint
pnpm run test Run all codemod tests
pnpm run check-types Typecheck all codemod scripts (root tsconfig.json)
pnpm run ci Full check (test + typecheck)
pnpm run docs:links Verify Markdown links

Pull requests

Type Usage
feat New codemod or capability
fix Bugfix in a transform or test
docs Documentation-only changes
refactor Non-feature, non-bugfix code changes
test Add or update fixtures/tests
chore Tooling, CI, formatting, repo hygiene

License

By contributing, you agree that your work will be licensed under the MIT License.