Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Edit Flow

Editorial workflow plugin with custom statuses, editorial comments, and notifications.

## Plugin Details

| Property | Value |
|----------|-------|
| **Main file** | `edit_flow.php` |
| **Text domain** | `edit-flow` |
| **Function prefix** | `ef_` |
| **Namespace** | Global (legacy) |
| **Source directory** | `modules/` |
| **Version** | 0.10.3 |

## Architecture

- Modular architecture in `modules/` directory
- Each feature is a separate module
- Main class: `edit_flow` (note underscore in filename)

## Testing

```bash
composer test:unit # Unit tests
composer test:integration # Integration tests
npm run test-e2e # Playwright E2E tests
```

## Notes

- Tier 1 plugin (well-maintained)
- WordPress.org hosted
- Has E2E tests with Playwright

## Standards

Follow the standards documented in `~/code/plugin-standards/`.
Original file line number Diff line number Diff line change
@@ -1,11 +1,36 @@
name: E2E and JS tests
name: E2E Tests

on:
pull_request:
push:
branches-ignore:
- develop
- main
paths:
- '**.js'
- '**.jsx'
- '**.ts'
- '**.tsx'
- '**.scss'
- '**.css'
- 'package.json'
- 'package-lock.json'
- 'webpack.config.js'
- '.wp-env.json'
- 'tests/e2e/**'
- '.github/workflows/e2e-tests.yml'
pull_request:
branches: [develop, main]
paths:
- '**.js'
- '**.jsx'
- '**.ts'
- '**.tsx'
- '**.scss'
- '**.css'
- 'package.json'
- 'package-lock.json'
- 'webpack.config.js'
- '.wp-env.json'
- 'tests/e2e/**'
- '.github/workflows/e2e-tests.yml'
workflow_dispatch:

# Disable all permissions by default; grant minimal permissions per job
permissions: {}
Expand All @@ -16,7 +41,7 @@ concurrency:

jobs:
build:
name: Build and Lint
name: Build
runs-on: ubuntu-latest
permissions:
contents: read
Expand Down Expand Up @@ -60,9 +85,6 @@ jobs:
echo "| custom-status-block.js | $(du -h build/custom-status-block.js | cut -f1) |" >> $GITHUB_STEP_SUMMARY
echo "| calendar-react.js | $(du -h build/calendar-react.js | cut -f1) |" >> $GITHUB_STEP_SUMMARY

- name: Run Lint JS
run: npm run lint-js

- name: Upload build artifacts
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
Expand All @@ -71,7 +93,7 @@ jobs:
retention-days: 1

test:
name: E2E and Jest tests
name: E2E Tests
# Pin to ubuntu-22.04 for Playwright compatibility
# ubuntu-latest (24.04) has library version mismatches with Playwright's WebKit dependencies
runs-on: ubuntu-22.04
Expand Down Expand Up @@ -106,5 +128,5 @@ jobs:
- name: Install WordPress with wp-env
run: npm run wp-env start

- name: Run tests
run: npm run test
- name: Run E2E tests
run: npm run test-e2e
21 changes: 17 additions & 4 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
name: Integration Tests

on:
pull_request:
push:
branches-ignore:
- develop
- main
paths:
- '**.php'
- 'composer.json'
- 'composer.lock'
- 'phpunit.xml.dist'
- '.wp-env.json'
- '.github/workflows/integration.yml'
pull_request:
branches: [develop, main]
paths:
- '**.php'
- 'composer.json'
- 'composer.lock'
- 'phpunit.xml.dist'
- '.wp-env.json'
- '.github/workflows/integration.yml'
workflow_dispatch:

# Disable all permissions by default; grant minimal permissions per job
permissions: {}
Expand Down
60 changes: 60 additions & 0 deletions .github/workflows/js-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: JS Tests

on:
push:
paths:
- '**.js'
- '**.jsx'
- '**.ts'
- '**.tsx'
- 'package.json'
- 'package-lock.json'
- 'jest.config.js'
- '.github/workflows/js-tests.yml'
pull_request:
branches: [develop, main]
paths:
- '**.js'
- '**.jsx'
- '**.ts'
- '**.tsx'
- 'package.json'
- 'package-lock.json'
- 'jest.config.js'
- '.github/workflows/js-tests.yml'
workflow_dispatch:

# Disable all permissions by default; grant minimal permissions per job
permissions: {}

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
lint-and-test:
name: Lint and Jest Tests
runs-on: ubuntu-latest
permissions:
contents: read

steps:
- name: Checkout code
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false

- name: Set up NodeJS 20
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
with:
node-version: '20'
cache: npm

- name: Install dependencies
run: npm ci

- name: Run Lint JS
run: npm run lint-js

- name: Run Jest tests
run: npm run test-jest
19 changes: 15 additions & 4 deletions .github/workflows/php-lint.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
name: PHP Lint

on:
pull_request:
push:
branches-ignore:
- develop
- main
paths:
- '**.php'
- 'composer.json'
- 'composer.lock'
- '.phpcs.xml.dist'
- '.github/workflows/php-lint.yml'
pull_request:
branches: [develop, main]
paths:
- '**.php'
- 'composer.json'
- 'composer.lock'
- '.phpcs.xml.dist'
- '.github/workflows/php-lint.yml'
workflow_dispatch:

# Disable all permissions by default; grant minimal permissions per job
permissions: {}
Expand Down
48 changes: 48 additions & 0 deletions .wordpress-org/blueprints/blueprint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"$schema": "https://playground.wordpress.net/blueprint-schema.json",
"landingPage": "/wp-admin/index.php?page=calendar",
"preferredVersions": {
"php": "8.2",
"wp": "latest"
},
"phpExtensionBundles": [
"kitchen-sink"
],
"steps": [
{
"step": "installPlugin",
"pluginData": {
"resource": "wordpress.org/plugins",
"slug": "edit-flow"
},
"options": {
"activate": true
}
},
{
"step": "runPHP",
"code": "<?php /* Initialize Edit Flow modules and capabilities */ require_once 'wordpress/wp-load.php'; if ( function_exists( 'EditFlow' ) ) { if ( isset( EditFlow()->custom_status ) ) { EditFlow()->custom_status->install(); } if ( isset( EditFlow()->calendar ) ) { EditFlow()->calendar->install(); } } $role = get_role( 'administrator' ); if ( $role ) { $role->add_cap( 'ef_view_calendar' ); } ?>"
},
{
"step": "runPHP",
"code": "<?php /* Create editor user */ require_once 'wordpress/wp-load.php'; $user_id = wp_create_user( 'editor', 'password', 'editor@example.com' ); if ( ! is_wp_error( $user_id ) ) { $user = new WP_User( $user_id ); $user->set_role( 'editor' ); update_user_meta( $user_id, 'first_name', 'Sarah' ); update_user_meta( $user_id, 'last_name', 'Editor' ); wp_update_user( array( 'ID' => $user_id, 'display_name' => 'Sarah Editor' ) ); } ?>"
},
{
"step": "runPHP",
"code": "<?php /* Create writer user */ require_once 'wordpress/wp-load.php'; $user_id = wp_create_user( 'writer', 'password', 'writer@example.com' ); if ( ! is_wp_error( $user_id ) ) { $user = new WP_User( $user_id ); $user->set_role( 'author' ); update_user_meta( $user_id, 'first_name', 'James' ); update_user_meta( $user_id, 'last_name', 'Writer' ); wp_update_user( array( 'ID' => $user_id, 'display_name' => 'James Writer' ) ); } ?>"
},
{
"step": "runPHP",
"code": "<?php /* Create sample posts with various statuses */ require_once 'wordpress/wp-load.php'; $writer = get_user_by( 'login', 'writer' ); $editor = get_user_by( 'login', 'editor' ); wp_insert_post( array( 'post_title' => 'New Feature: AI-Powered Content Suggestions', 'post_content' => 'This article explores how AI can help content creators brainstorm and refine their ideas.', 'post_status' => 'pitch', 'post_author' => $writer->ID, 'post_date' => date( 'Y-m-d H:i:s', strtotime( '+3 days' ) ), ) ); wp_insert_post( array( 'post_title' => 'Guide to Remote Team Collaboration', 'post_content' => 'Remote work has transformed how editorial teams collaborate.', 'post_status' => 'assigned', 'post_author' => $writer->ID, 'post_date' => date( 'Y-m-d H:i:s', strtotime( '+5 days' ) ), ) ); $progress_post = wp_insert_post( array( 'post_title' => '10 Tips for Better Editorial Workflows', 'post_content' => 'Streamlining your editorial workflow can save hours each week.', 'post_status' => 'in-progress', 'post_author' => $writer->ID, 'post_date' => date( 'Y-m-d H:i:s', strtotime( '+1 day' ) ), ) ); update_option( 'ef_demo_progress_post_id', $progress_post ); wp_insert_post( array( 'post_title' => 'The Future of Digital Publishing', 'post_content' => 'Digital publishing continues to evolve rapidly.', 'post_status' => 'pending', 'post_author' => $editor->ID, 'post_date' => date( 'Y-m-d H:i:s', strtotime( '+2 days' ) ), ) ); wp_insert_post( array( 'post_title' => 'Interview: Leading Through Change', 'post_content' => 'In this exclusive interview, we speak with industry leaders.', 'post_status' => 'draft', 'post_author' => 1, 'post_date' => date( 'Y-m-d H:i:s', strtotime( '+7 days' ) ), ) ); wp_insert_post( array( 'post_title' => 'Weekly Roundup: Content Strategy Insights', 'post_content' => 'This week in content strategy: new research on reader engagement.', 'post_status' => 'future', 'post_author' => $editor->ID, 'post_date' => date( 'Y-m-d H:i:s', strtotime( '+4 days' ) ), ) ); ?>"
},
{
"step": "runPHP",
"code": "<?php /* Add editorial comments to demonstrate collaboration */ require_once 'wordpress/wp-load.php'; $post_id = get_option( 'ef_demo_progress_post_id' ); if ( $post_id ) { $editor = get_user_by( 'login', 'editor' ); $writer = get_user_by( 'login', 'writer' ); wp_insert_comment( array( 'comment_post_ID' => $post_id, 'comment_content' => 'Great start! Could you expand on tip #3 about visual calendars?', 'comment_type' => 'editorial-comment', 'user_id' => $editor->ID, 'comment_author' => $editor->display_name, 'comment_author_email' => $editor->user_email, 'comment_approved' => 'editorial-comment', ) ); wp_insert_comment( array( 'comment_post_ID' => $post_id, 'comment_content' => 'Thanks Sarah! I will add a calendar screenshot and expand that section.', 'comment_type' => 'editorial-comment', 'user_id' => $writer->ID, 'comment_author' => $writer->display_name, 'comment_author_email' => $writer->user_email, 'comment_approved' => 'editorial-comment', ) ); delete_option( 'ef_demo_progress_post_id' ); } ?>"
},
{
"step": "login",
"username": "admin",
"password": "password"
}
]
}
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,26 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.10.3] - 2026-01-12

### Added

* feat: add WordPress Playground blueprint for live preview by @GaryJones in [#885](https://github.com/Automattic/Edit-Flow/pull/885)

### Fixed

* fix: prevent Edit Flow nonce checks from killing unrelated forms by @GaryJones in [#883](https://github.com/Automattic/Edit-Flow/pull/883)
* fix: add missing imports for Extended Post Status block editor panel by @GaryJones in [#884](https://github.com/Automattic/Edit-Flow/pull/884)

### Documentation

* docs: move Development section from README to CONTRIBUTING by @GaryJones in [#880](https://github.com/Automattic/Edit-Flow/pull/880)

### Maintenance

* ci: optimise CI workflows with path filters and split tests by @GaryJones in [#881](https://github.com/Automattic/Edit-Flow/pull/881)
* test: add integration test for revision nonce handling by @GaryJones in [#879](https://github.com/Automattic/Edit-Flow/pull/879)

## [0.10.2] - 2026-01-07

### Fixed
Expand Down Expand Up @@ -395,6 +415,7 @@ This is a major update with significant bug fixes, new features, and modernised

* Ability to assign custom statuses to posts.

[0.10.3]: https://github.com/Automattic/Edit-Flow/compare/0.10.2...0.10.3
[0.10.2]: https://github.com/Automattic/Edit-Flow/compare/0.10.1...0.10.2
[0.10.1]: https://github.com/Automattic/Edit-Flow/compare/0.10.0...0.10.1
[0.10.0]: https://github.com/Automattic/Edit-Flow/compare/0.9.9...0.10.0
Expand Down
37 changes: 37 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,43 @@ Here's a sample of what a great summary looks like:

Screenshots: *screenshot of behavior/error goes here*

Development Setup
------

This plugin uses `wp-env` for development and is required to run the tests written for the plugin. `wp-env` requires Docker so please ensure you have that installed on your system first. To install `wp-env`, use the following command:

```
npm -g i @wordpress/env
```

Read more about `wp-env` [here](https://www.npmjs.com/package/@wordpress/env).

This plugin also uses Composer to manage PHP dependencies. Composer can be downloaded [here](https://getcomposer.org/download/).

###### Getting started

1. Clone the plugin repo: `git clone git@github.com:Automattic/Edit-Flow.git`
2. Change to cloned directory: `cd /path/to/repo`
3. Install PHP dependencies: `composer install`
4. Install NPM dependencies: `npm install`
5. Start dev environment: `wp-env start`

###### Running tests

Ensure that the dev environment has already been started with `wp-env start`.

**PHP Integration Tests:**
1. Integration test: `composer run integration`
2. Multi-site integration test: `composer run integration-ms`

**E2E Tests (Playwright):**
1. Run E2E tests: `npm run test-e2e`
2. Run with visible browser: `npm run test-e2e:headed`
3. Debug mode: `npm run test-e2e:debug`

**JavaScript Tests:**
1. Run Jest tests: `npm run test-jest`

Creating and submitting Patches
------

Expand Down
Loading
Loading