CRITICAL: This is a public repository. Never include private WordPress.com URLs (e.g., *.wordpress.com internal sites) in PR descriptions, commit messages, code comments, or any public-facing text. Use the p2 shorthand syntax instead (e.g., peKye1-1Z1-p2).
projects/plugins/— WordPress pluginsprojects/packages/— Composer/PHP packagesprojects/js-packages/— JavaScript/npm packagesprojects/github-actions/— GitHub Actionstools/— Monorepo toolingdocs/— Documentation
Projects define build steps in composer.json:
.scripts.build-production— Production build (setNODE_ENV=production).scripts.build-development— Development build.scripts.test-php— PHP tests.scripts.test-js— JavaScript tests
FORCE_PULL=1— Force pull latest Docker imageBUILD_LOCAL=1— Build Docker image locallyDEBUG=1— Enable debug output
The jp command runs pnpm jetpack inside the monorepo Docker container. Install globally: npm install -g @automattic/jetpack-cli (this is a global install, safe to run even inside a Jetpack checkout). jp commands work from git worktrees — the CLI resolves to the monorepo root automatically.
jp build plugins/jetpack # Build a project
jp build plugins/jetpack --deps # Build with dependencies
jp watch plugins/jetpack # Watch and rebuild on changes
jp test php plugins/jetpack # Run PHP tests
jp test js plugins/jetpack # Run JS tests
jp changelog add # Add changelog entry (interactive)
jp generate # Create new project (interactive wizard)
jp install plugins/jetpack # Install project dependencies
jp clean plugins/jetpack # Clean build artifacts
jp docker up -d # Start Docker environment
jp docker install # Install WordPress in Docker
jp phan # Run PHP static analysisUse jp generate to create new projects:
- Plugins:
jp generate plugin --name my-plugin(choose "Starter plugin" for React admin page example, or "Blank plugin" for minimal scaffolding) - Packages:
jp generate package --name my-package - JS Packages:
jp generate js-package --name my-js-package - GitHub Actions:
jp generate github-action --name my-action
Detailed guidelines are in docs/coding-guidelines.md.
- Use WordPress naming conventions for functions and classes
- Prefix global PHP functions and hooks with
jetpack_ - Use lowercase with underscores for PHP functions
- Follow WordPress React component naming patterns
- Use BEM-like naming for SCSS
- Follow WordPress PHP Coding Standards
- Use proper WordPress prefix for functions and classes
- Implement WordPress nonce verification for form handling and AJAX
- Follow WordPress database operations best practices (
$wpdbprepared statements) - Structure plugin hooks logically
When adding a version number in a DocBlock, MUST use $$next-version$$:
@since $$next-version$$@deprecated $$next-version$$@deprecated since $$next-version$$_deprecated_function( __METHOD__, 'package-$$next-version$$' );
The $$next-version$$ placeholder is automatically replaced with the correct version at release time. Do NOT replace these with actual version numbers.
- Write modern ES6+ code following WordPress JS standards
- Use
@wordpress/elementinstead of importing React directly - Use WordPress data stores (
@wordpress/data) for state management - Use
@wordpress/i18nfor translations with an appropriate unique text domain - Follow WordPress component lifecycle patterns and accessibility guidelines
- When using TypeScript with Webpack, use
@babel/preset-typescriptrather thants-loader
- Use BEM-like naming conventions
- Use CSS logical properties instead of physical direction/dimension mappings to make styles RTL-aware by default (reference: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Logical_Properties)
jp test php <project> -v # PHPUnit tests (verbose)
jp test js <project> # Jest tests
jp test coverage <project> # Generate coverage report- Packages (
jp test php packages/...,jp test js packages/...): Work immediately with no extra setup. The monorepo Docker container handles everything. - Plugins: Some plugins use mocked WordPress environments (WorDBless/Brain Monkey) and their tests work immediately. Others (notably
plugins/jetpack) require a full WordPress test environment:jp docker up -d— Start Docker WordPress containersjp docker install— Install WordPress in Docker Then run:jp test php plugins/jetpack
- If you've modified package versions or dependencies between monorepo packages, run
tools/fixup-project-versions.shto update lock files before testing. - If a project's
composer.jsondoesn't definetest-js, the JS test step is skipped automatically — this is normal, not an error.
After modifying a project, run its tests and static analysis:
jp test php <project> # PHP tests
jp test js <project> # JS tests (skipped if not defined)
jp phan <project> # Static analysis
jp test coverage <project> # Generate coverage report (optional)- Use PHPUnit with WordPress test framework and
yoast/phpunit-polyfills - Follow WordPress testing conventions, use WordPress fixtures and mocks
- Test WordPress hooks and filters
- Test class names MUST end in "Test"
- Every test class MUST be in a file with a matching name (e.g., class
My_Unit_TestinMy_Unit_Test.php)
See docs/automated-testing.md for full testing guidelines.
- Use Jest with
@testing-library/react - Follow WordPress testing patterns for async testing and mocking
See projects/packages/my-jetpack/_inc/components/connection-status-card/test/component.tsx for a representative example.
Every PR touching /projects MUST include a changelog file in the project's changelog/ directory. Changes outside /projects (e.g., tools/, docs/, .github/) do NOT need changelog entries.
Run jp changelog add and follow the prompts.
jp changelog add <project> -s <significance> -t <type> -e "<entry>" [-f <filename>]Parameters:
-s, --significance:patch|minor|major-t, --type:security|added|changed|deprecated|removed|fixed-e, --entry: Changelog entry text-f, --file: Filename (defaults to git branch name)-c, --comment: For trivial changes with empty entry, explain why no entry needed
Examples:
# Standard changelog entry
jp changelog add packages/connection -s patch -t fixed -e "Connection: Fix issue with site registration."
# Jetpack plugin (uses different types: major, enhancement, compat, bugfix, other)
jp changelog add plugins/jetpack -s patch -t bugfix -e "Connection: Fix issue with site registration."
# Trivial change (no user-facing entry needed)
jp changelog add packages/connection -s patch -t changed -e "" -c "Update internal documentation"Note: Jetpack plugin uses custom changelog types defined in projects/plugins/jetpack/composer.json at .extra.changelogger.types.
Significance: patch
Type: fixed
Connection: Fix issue with site registration.
Entries MUST:
- Be grammatically correct and free of typos
- Start with a capital letter and end with a period
- Use imperative mood (e.g., "Add feature." not "Added feature" or "Adds feature")
- Use a component/feature prefix when the change is specific to a component (e.g., "Connection: Fix timeout issue with site registration.")
- NOT use the package/project name as a prefix within that same package
- Describe the change from a user's perspective, not the implementation details
PR descriptions MUST follow the template in .github/PULL_REQUEST_TEMPLATE.md — CI checks expect the metadata format defined there.
gh pr create --title "Title" --body-file pr-body.md --label "[Status] Needs Review" --label "Enhancement" --assignee @meWhen reviewing code, check for:
- Adherence to
docs/coding-guidelines.md - Inconsistent naming conventions and typos
- Missing documentation for public APIs
- Missing explanations for complex or non-obvious logic
- Inefficient algorithms
- CSS/SCSS files not using logical properties for RTL
Do NOT suggest modifying $$next-version$$ placeholders — these are intentionally used and replaced during release.
Before introducing new dependencies:
- Survey existing packages within the monorepo for similar functionality
- Check for reusable components, utilities, or hooks in shared packages
- Review existing WordPress core and Jetpack APIs
- Prioritize internal packages and APIs over external dependencies
- Do NOT edit WordPress core files — all changes must be in plugins/packages
- Do NOT modify
$$next-version$$placeholders — they are replaced automatically at release time - Reuse monorepo packages before adding external dependencies — check
projects/packages/andprojects/js-packages/first - Git merge conflicts: after resolving, use
git commit --no-edit --no-verify— pre-commit hooks can make unintended changes to merge commit files
If you discover a pattern or pitfall not covered here, mention it to the developer so they can decide whether to update this file.