Feature PR-6.3-dev Pending

User tests: Successful: Unsuccessful:

avatar Fr3shDev
Fr3shDev
20 Sep 2026

Pull Request resolves # .

  • I read the Generative AI policy and my contribution is either not created with the help of AI or is compatible with the policy and GNU/GPL 2 or later.

Summary of Changes

This is the result of Google Summer of Code 2026 for Joomla, mentored by @ditsuke and @Dileepadari. It was developed and reviewed in https://github.com/joomla-projects/gsoc26_automated_workflow and is submitted here as one branch.

Workflow transitions currently have to be run by a person. This adds rules that run them automatically.

The rule. Any transition can carry an automation rule: fire after a delay (minutes, hours, days, months) or on a cron schedule. A new scheduler task, workflow.automation, picks up due items each run and executes their transitions. Every rule runs as a chosen user, so permissions are checked exactly as they would be for a person clicking the button. A super user may choose any run-as user; anyone else may only keep the user the rule already has or pick themselves.

Which items, and when. A filter decides which items a rule applies to, and a condition decides whether the moment is right. Eight built-in checks (category, tag, author group, hits, day of week, date, days in stage, days since modified) with thirteen operators. The builder defaults to a simple mode where checks are joined by AND; OR, Not and nested expressions sit behind an Expert Mode option in the plugin. Two new events, onWorkflowConditionFields and onWorkflowResolveFields, let any extension add its own checks, so the list is not limited to what core knows about.

Visibility. An Upcoming Transitions tab per workflow and a site-wide list with workflow and stage filters, a badge in the articles list and a card in the article edit sidebar, an automation log per workflow and site-wide with the reason for every failure, and automated transitions marked in the workflow graph. Failures record a reason, take the item out of the queue until an administrator clears it, and are reported through the existing task notification plugin.

Schema. Three new tables: #__workflow_automation_rules, #__workflow_item_state and #__workflow_automation_log, with MySQL and PostgreSQL install and update SQL. Each scheduler run reconciles #__workflow_item_state against #__workflow_associations, so items created while workflows were off, moved by a batch stage change or imported directly are picked up rather than silently ignored.

Known gaps, raised here rather than left to be found:

  • There are no automated tests in this PR. The feature was tested by hand against a site with real data, including the failure paths. I would like guidance on where system tests for this should live, and I will add them.
  • plugins/workflow/remotecheck is an example plugin that asks an external service a yes/no question, written to prove the extension points work. If an example plugin does not belong in core, say so and I will drop those five files.
  • Parts of this were written with AI assistance. Every line was read, tested and revised by me, and the whole branch went through mentor review in the fork.

Testing Instructions

  1. Apply the patch, then run npm ci && npm run build so the new component assets are built.
  2. Go to System, Global Configuration, Articles, Integration, and set Enable Workflows to Yes.
  3. Go to Content, Workflows, and open the Basic Workflow. Open the Transitions tab, then open a transition.
  4. On the transition, open the Automation tab, enable it, choose Delay, and set 1 minute. Set Run as to a user allowed to make that change. Save.
  5. Open Content, Workflows, Upcoming Transitions. Any article sitting in that transition's from stage should be listed with the time it is due.
  6. Move an article into that stage, wait a minute, then run the scheduler: System, Scheduled Tasks, open Workflow: automated transitions, and click Run. From the CLI, php cli/joomla.php scheduler:run does the same.
  7. Check the article's stage has changed, and that Content, Workflows, Automation Log shows a row with a success exit code.
  8. Optional, filters: back on the transition's Automation tab, add a filter such as Category is X, and use Preview to list which items match before saving.

Actual result BEFORE applying this Pull Request

Every workflow transition has to be run by a person from the articles list or the article itself. There is no way to say "move this to Review three days after it enters Copywriting", no record of when an item entered its stage, and nothing showing what is due to happen next.

Expected result AFTER applying this Pull Request

Transitions run on their own, on a delay or a schedule, restricted to the items a rule selects, executed as a named user with that user's permissions. The administrator shows what is coming, what has already run and why anything failed.

Link to documentations

Please select:

  • Documentation link for guide.joomla.org:

  • No documentation changes for guide.joomla.org needed

  • Pull Request link for manual.joomla.org:

  • No documentation changes for manual.joomla.org needed

avatar Fr3shDev Fr3shDev - open - 20 Sep 2026
avatar Fr3shDev Fr3shDev - change - 20 Sep 2026
Status New ⇒ Pending
avatar joomla-cms-bot joomla-cms-bot - change - 20 Sep 2026
Category ⇒ Administration com_admin SQL Postgresql com_content com_workflow
avatar Fr3shDev Fr3shDev - change - 20 Sep 2026
Title
…
[6.2][AI] Automated workflow transitions
Automated workflow transitions
avatar Fr3shDev Fr3shDev - edited - 20 Sep 2026
avatar Fr3shDev Fr3shDev - change - 20 Sep 2026
The description was changed
avatar Fr3shDev Fr3shDev - edited - 20 Sep 2026
avatar Fr3shDev Fr3shDev - change - 20 Sep 2026
The description was changed
avatar Fr3shDev Fr3shDev - edited - 20 Sep 2026
avatar brianteeman
brianteeman - comment - 20 Sep 2026

This is a new feature so should be made against the 6.3-dev branch not the 6.2 branch

avatar brianteeman
brianteeman - comment - 20 Sep 2026

This is a new feature so should be made against the 6.3-dev branch not the 6.2 branch and the sql files need to be renamed accordingly

avatar Fr3shDev Fr3shDev - change - 20 Sep 2026
Labels Added: Feature PR-6.2-dev
avatar Fr3shDev
Fr3shDev - comment - 20 Sep 2026

Thanks for the thorough review @brianteeman. All the suggestions are in.

avatar brianteeman
brianteeman - comment - 20 Sep 2026

you still need to move this to the 6.3dev branch and rename the sql files accordingly. (does it even need two files or can they be combined into a single file now)

avatar Fr3shDev Fr3shDev - change - 20 Sep 2026
Labels Added: PR-6.3-dev
avatar Fr3shDev Fr3shDev - change - 21 Sep 2026
Labels Removed: PR-6.2-dev
avatar drmenzelit drmenzelit - change - 21 Sep 2026
Title
…
Automated workflow transitions
[6.3] Automated workflow transitions
avatar drmenzelit drmenzelit - edited - 21 Sep 2026
avatar Fr3shDev
Fr3shDev - comment - 22 Sep 2026

A walkthrough for anyone testing this
This is what it looks like and the fastest way to see it working in no time.

The two minute version
If you only do one thing, do this.

  1. Apply the patch, npm ci && npm run build.
  2. Content, Articles, Options, Integration, set Enable Workflows to Yes.
  3. Content, Workflows, open Basic Workflow, Transitions, open Publish
  4. Open the new Automation tab. Switch it on, choose Delay, set 1 minute, set Run as to your admin user. Save.
  5. Content, Articles, set any article's stage to Unpublished so it is sitting where that transition starts from.
  6. Wait a minute, then System, Scheduled Tasks, open Workflow Automation and click Run. Or php cli/joomla.php scheduler:run if you prefer the CLI.

The article is now Published, and nobody clicked anything. Everything below is detail untop of that.

The rule itself
Screenshot 2026-09-22 at 23 14 07
A rule lives on a transition, not on an article. It fires either after a delay counted from the moment an item entered the stage, or on a cron schedule.

Run as is the part worth poking at. The transition executes as that user with exactly their permissions, so the rule can never do something that user could not do by hand. Try setting a run-as user who lacks permission for that transition and watch it refuse rather than silently succeed. A super user can pick anyone; anyone else can only keep the user already stored on the rule, or pick themselves.

Choosing which items it applies to
Screenshot 2026-09-22 at 23 19 25
Two separate questions, kept separate on purpose. A filter decides which items the rule applies to. A condition decides whether now is the right moment to fire.

Eight checks are built in: category, tag, author group, hits, day of week, date, days in stage, days since last edited. By default they are joined with AND and that is all the interface shows. OR, Not and nested groups live behind an Expert Mode switch in the Workflow Automation plugin, because most people never need them.
Screenshot 2026-09-22 at 23 30 41
Screenshot 2026-09-22 at 23 31 17

Preview is the bit I would most like tested. It lists the items your filter currently matches, before you save.

Seeing what is queued
Screenshot 2026-09-22 at 23 33 38
Screenshot 2026-09-22 at 23 34 07
Every workflow has an Upcoming Transitions tab, and there is a site-wide list with workflow and stage fitlers and paging. These are computed live rather than stored, so they cannot drift out of sync with the rules.

Screenshot 2026-09-22 at 23 36 35 Screenshot 2026-09-22 at 23 37 05 Articles also carry a badge in the list, and the same information appears in the sidebar when you edit one.

If you need more power
Screenshot 2026-09-23 at 00 05 10
Screenshot 2026-09-23 at 00 06 32
Turning on Expert Mode in the Workflow Automation plugin unlocks OR, Not and nested groups in the same builder. It is off by default because most rules never need it, and a simple rule is easier to get right. A rule that already uses those constructs always opens in the full builder, so switching the option off never hides part of a rule you have saved.

Seeing what happened
Screenshot 2026-09-22 at 23 50 10
Every run is logged with an exit code: succeeded, refused, skipped, or failed. A failure records why, holds the item back instead of retrying it forever, and is reported through the existing task notification plugin.

To see a failure on purpose: as a super user, set Run as to an account that has no permission for that transition, for example a Registered user. The scheduler then refuses the transition and records the reason in the log.

If you are testing as anything other than a super user you will not be able to reproduce this, since the picker only offers you yourself or the user already stored on the rule.

Things worth trying to break

  • Set a rule on a transition from stage is "any". These are every transition in the default Basic Workflow.
  • Move an item by hand in between the scheduler picking it up and acting on it.
  • Turn workflows off, create some articles, turn workflows back on. Those items should still be picked up, because each run reconciles against #__workflow_associations.
  • Save a filter with a check that has no value chosen. It should refuse, rather than quietly saving as "no filter" and matching everything.
  • Two rules on different transitions that could both fire for the same item.

What it deliberately does not do
Per-article, scheduling was in the original proposal and was dropped: rules live on transitions only, so there is on place to look when something unexpectedly. Loop support was dropped for the same reason.

Questions are welcome.

avatar brianteeman
brianteeman - comment - 24 Sep 2026
image

in other places where we have a link like this to open a plugin we do it in a modal

example

image image
avatar brianteeman
brianteeman - comment - 24 Sep 2026

try to save an automation with rule type = cron and an empty cron expression

"Save failed with the following error:" but there is nothing following

image
avatar brianteeman
brianteeman - comment - 24 Sep 2026

try to save an automation with rule type = cron and an empty or invalid cron expression

"Save failed with the following error:" but there is nothing following

image
avatar brianteeman
brianteeman - comment - 24 Sep 2026

try to save a cron with an expression that matches the hint "/5***"

image image
avatar brianteeman
brianteeman - comment - 24 Sep 2026

try to save a cron with an expression that matches the hint "/5***"

image image
avatar brianteeman
brianteeman - comment - 24 Sep 2026

Try to save an automation with a filter that is empty

image

The second line of the error message says "Save failed with the following error:" but nothing follows

image
avatar brianteeman
brianteeman - comment - 24 Sep 2026

Try to save an automation with a filter or condition that is empty

image

The second line of the error message says "Save failed with the following error:" but nothing follows

image
avatar brianteeman
brianteeman - comment - 24 Sep 2026

There is no indication that automated transions are enabled for a transition in the list view. It is visible in the graph view

image image
avatar brianteeman
brianteeman - comment - 24 Sep 2026

Placeholders in fields that disappear are generally considered to be bad for accessibility and should be avoided (https://www.nngroup.com/articles/form-design-placeholders/)
This is especially true for this field where it is hard to tell that the hint is
/5 * * * *
and not
/5
**
image

avatar brianteeman
brianteeman - comment - 24 Sep 2026

Placeholders in fields that disappear are generally considered to be bad for accessibility and should be avoided (https://www.nngroup.com/articles/form-design-placeholders/)
This is especially true for this field where it is hard to tell that the hint is
*/5 * * * *
and not
*/5****
image

avatar brianteeman
brianteeman - comment - 24 Sep 2026

The css class text-muted fails accessibility contrast rules. It should be enough just to use small

small text-muted

image

small

image
avatar brianteeman
brianteeman - comment - 24 Sep 2026

where possible I would avoid adding css classes and just use existing classes - less to maintain and easier when a non-atum admin template is used

Example

custom css from this pr

image

existing small

image
avatar Fr3shDev
Fr3shDev - comment - 24 Sep 2026

Thanks for the in-depth review @brianteeman
All comments have been addressed.
Quick question on the custom CSS point though, could you say which element you had in mind? I have dropped text-muted throughout the builder, but I would rather remove the right class than guess and break a layout.

Two notes. Testing the save-error report turned up a second bug: the form stored whichever fields were posted, and since showon hides an input without stopping it from submitting, a delay rule kept the last cron expression typed, valid or not. So the form itself could write a row that would not parse. Fixed in the same commit.

On the Expert Mode modal, I left off data-reload-on-close. Core uses it from list views, but this opens from inside the transition edit form and reloading would discard unsaved work. The trade-off is that the builder only picks up the new setting on the next load. Happy to change it if you would rather match the pattern exactly.

avatar Fr3shDev
Fr3shDev - comment - 24 Sep 2026

Thanks for the in-depth review @brianteeman
All comments have been addressed.
Quick question on the custom CSS point though, could you say which element you had in mind? I have dropped text-muted throughout the builder, but I would rather remove the right class than guess and break a layout.

Two notes. Testing the save-error report turned up a second bug: the form stored whichever fields were posted, and since showon hides an input without stopping it from submitting, a delay rule kept the last cron expression typed, valid or not. So the form itself could write a row that would not parse. Fixed in the same commit.

The Expert Mode link uses the same data-joomla-dialog pattern, including data-reload-on-close.

avatar brianteeman
brianteeman - comment - 25 Sep 2026

This is not a suitable solution as only a mouse user can access the information
image

image

I suggest that you look at how the checkout icon and information is displayed and adopt that code pattern

image image
avatar brianteeman
brianteeman - comment - 25 Sep 2026

Create an autiomated rule with both an invalid filter AND an invalid condition and try to save

I would expect to get two error messages but I only get one

image image
avatar brianteeman
brianteeman - comment - 25 Sep 2026

I have dropped text-muted throughout the builder,

I am still seeing text-muted

avatar brianteeman
brianteeman - comment - 25 Sep 2026

If I disable all three plugins should I still be able to create automations? Because I can

image
avatar Fr3shDev
Fr3shDev - comment - 28 Sep 2026

Thanks for the comments @brianteeman I was able to address them and I also found some other bugs and loopholes in the process which I handled as well. Please keep testing and let me know, thanks again

avatar brianteeman
brianteeman - comment - 28 Sep 2026

Create an autiomated rule with both an invalid filter AND an invalid condition and try to save

I would expect to get two error messages but I only get one

still only getting one message

avatar brianteeman
brianteeman - comment - 28 Sep 2026

Workflow Task Plugin disabled

when disabled you get a message that the plugin is disabled but it would be better if you also got a link to enable the plugin - see redirects for example

image image
avatar brianteeman
brianteeman - comment - 28 Sep 2026

Workflow Automation Plugin disabled

When this plugin is disabled you still get an automation tab but it is empty with no explanation to the user why or what they need to do

image
avatar brianteeman
brianteeman - comment - 28 Sep 2026

accessibility

it is not possible to reach the tooltip here using the keyboard

image
avatar brianteeman
brianteeman - comment - 28 Sep 2026

I am pretty confused about this - or maybe i found a new problem?

with the sample data installed I created an automation for the publish transition

image

then I created a new article which by default is unpublished

after saving the article it says a transition will take place in 5 minutes
image

not sure why it says that because the automation is on the publish transition and this is unpublished

after waiting the required minutes nothing changes to the state of the article (which is what i expected as there was no automation on the unpublished transition) but the tooltip is updated to say due now

image

and in the article itself it says

image
avatar brianteeman
brianteeman - comment - 28 Sep 2026

I am pretty confused about this - or maybe i found a new problem?

with the sample data installed I created an automation for the publish transition

image

then I created a new article which by default is unpublished

after saving the article it says a transition will take place in 5 minutes
image

not sure why it says that because the automation is on the publish transition and this is unpublished

after waiting the required minutes nothing changes to the state of the article (which is what i expected as there was no automation on the unpublished transition) but the tooltip is updated to say due now

image

and in the article itself it says

image

update

now i am really confused - after returning some time later these articles are now published

avatar Fr3shDev
Fr3shDev - comment - 3 Oct 2026

Create an autiomated rule with both an invalid filter AND an invalid condition and try to save
I would expect to get two error messages but I only get one

still only getting one message

@brianteeman both errors are raised, but core keeps only one. FormField::validate() applies SubformRule to any subform field automatically, and SubformRule::test() returns $errors[0] and discards the rest, at [SubformRule.php:66] and again at line 79. The comment there says as much: "Pass the first error that occurred on the subform validation."

The filter and condition builders both live in the automation subform, so from the parent form's point of view they are one field and can carry one error. The message does name which builder is at fault and marks that field, so fixing it and saving surfaces the next one.

I could collect both into a single combined sentence by validating at the subform level instead, but then the error attaches to the whole subform rather than the builder that is wrong, which loses the field marking. That seemed a worse trade, but please let me know if that would be better

avatar Fr3shDev
Fr3shDev - comment - 3 Oct 2026

Thanks @brianteeman please take a look and let me know if anything else comes up.

avatar brianteeman
brianteeman - comment - 3 Oct 2026

I cant comment on the way that the code displays the error. I can only comment that you should display all errors

avatar Fr3shDev
Fr3shDev - comment - 6 Oct 2026

I cant comment on the way that the code displays the error. I can only comment that you should display all errors

Got it @brianteeman I just made some changes. Please test again and let me know how it goes, thanks!

Add a Comment

Login with GitHub to post a comment