Skip to content

Have ert show hooked workflows in GUI#13397

Open
jonathan-eq wants to merge 1 commit intoequinor:mainfrom
jonathan-eq:23042026_show_workflow_status_in_gui
Open

Have ert show hooked workflows in GUI#13397
jonathan-eq wants to merge 1 commit intoequinor:mainfrom
jonathan-eq:23042026_show_workflow_status_in_gui

Conversation

@jonathan-eq
Copy link
Copy Markdown
Contributor

@jonathan-eq jonathan-eq commented Apr 23, 2026

Issue
Resolves #13320

Approach
This commit changes the GUI to:

  • Show iterations and updates in tabs to accommodate showing pre/post
    run/update workflows
  • Show pre-experiment and post-experiment workflows on main tab-bar
  • Pressing terminate experiment during hooked workflows cancels the
    workflow, and marks it as cancelled by user. Following workflows in
    the same hook will be marked as cancelled, as to not mislead the user.

(Screenshot of new behavior in GUI if applicable)

  • PR title captures the intent of the changes, and is fitting for release notes.
  • Added appropriate release note label
  • Commit history is consistent and clean, in line with the contribution guidelines.
  • Make sure unit tests pass locally after every commit (git rebase -i main --exec 'just rapid-tests')

When applicable

  • When there are user facing changes: Updated documentation
  • New behavior or changes to existing untested code: Ensured that unit tests are added (See Ground Rules).
  • Large PR: Prepare changes in small commits for more convenient review
  • Bug fix: Add regression test for the bug
  • Bug fix: Add backport label to latest release (format: 'backport release-branch-name')

@jonathan-eq jonathan-eq force-pushed the 23042026_show_workflow_status_in_gui branch 2 times, most recently from 0095d01 to 4e61524 Compare April 23, 2026 14:03
@jonathan-eq
Copy link
Copy Markdown
Contributor Author

jonathan-eq commented Apr 29, 2026

Changing iteration tabs does not always update the fm_overview table...
EDIT: It might be handled, it was atleast VERY rarely, and the test seems to be passing.

@jonathan-eq jonathan-eq force-pushed the 23042026_show_workflow_status_in_gui branch from 4e61524 to fd82164 Compare April 29, 2026 10:39
Comment thread src/_ert/events.py

from pydantic import BaseModel, ConfigDict, Field, TypeAdapter

from _ert.hook_runtime import HookRuntime
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had to move hook_runtime to _ert to avoid circular import

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Apr 29, 2026

Codecov Report

❌ Patch coverage is 97.87798% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.01%. Comparing base (b0a037a) to head (3edfd9e).
⚠️ Report is 33 commits behind head on main.

Files with missing lines Patch % Lines
src/ert/gui/experiments/run_dialog.py 96.82% 2 Missing ⚠️
src/ert/gui/experiments/view/iteration.py 96.07% 2 Missing ⚠️
src/ert/workflow_runner.py 96.72% 2 Missing ⚠️
src/ert/gui/experiments/view/workflow.py 99.20% 1 Missing ⚠️
src/ert/run_models/run_model.py 95.83% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #13397      +/-   ##
==========================================
- Coverage   90.05%   90.01%   -0.04%     
==========================================
  Files         459      461       +2     
  Lines       32040    32492     +452     
==========================================
+ Hits        28853    29249     +396     
- Misses       3187     3243      +56     
Flag Coverage Δ
cli-tests 37.19% <30.23%> (-0.32%) ⬇️
fuzz 43.98% <28.38%> (-0.25%) ⬇️
gui-tests 67.22% <90.98%> (+0.27%) ⬆️
performance-and-unit-tests 78.02% <82.22%> (+<0.01%) ⬆️
test 45.69% <40.05%> (-0.20%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/_ert/events.py 100.00% <100.00%> (ø)
src/_ert/hook_runtime.py 100.00% <100.00%> (ø)
src/ert/config/parsing/__init__.py 100.00% <100.00%> (ø)
src/ert/config/parsing/config_schema.py 100.00% <100.00%> (ø)
src/ert/config/workflow_fixtures.py 100.00% <100.00%> (ø)
src/ert/gui/experiments/view/__init__.py 100.00% <100.00%> (ø)
src/ert/run_models/event.py 100.00% <100.00%> (ø)
src/ert/run_models/update_run_model.py 97.91% <100.00%> (ø)
src/ert/gui/experiments/view/workflow.py 99.20% <99.20%> (ø)
src/ert/run_models/run_model.py 93.27% <95.83%> (+0.10%) ⬆️
... and 3 more

... and 19 files with indirect coverage changes

@jonathan-eq jonathan-eq force-pushed the 23042026_show_workflow_status_in_gui branch from 9181b64 to 4d0e6b6 Compare April 30, 2026 09:30
Comment thread src/_ert/events.py


class _WorkflowEvent(BaseModel):
hook: HookRuntime | None = None
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

workflow_runner tests required this to be optional

Comment thread src/_ert/hook_runtime.py
PRE_EXPERIMENT = "PRE_EXPERIMENT"
POST_EXPERIMENT = "POST_EXPERIMENT"

def workflow_tab_title(self) -> str:
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about this one. Maybe I should just change the strenum values directly(?)

from .workflow import WorkflowWidget


class IterationWidget(QWidget):
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the widget that allows us to group the tabs. Maybe TabGroupingWidget is better? It can contain UpdateWidget, RealizationWidget, and WorkflowWIdget.

Comment on lines +24 to +30
_STATUS_TO_BACKGROUND = {
WorkflowStatus.PENDING: QColor(*state.COLOR_PENDING),
WorkflowStatus.RUNNING: QColor(*state.COLOR_RUNNING),
WorkflowStatus.FINISHED: QColor(*state.COLOR_FINISHED),
WorkflowStatus.FAILED: QColor(*state.COLOR_FAILED),
WorkflowStatus.CANCELLED: QColor(*state.COLOR_CANCELLED),
}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very similar to the statuses and look we have in evaluator. The tables can probably at some point be combined (if we want to add the duration field for workflows too).

Comment on lines +33 to +34
"Workflow job": 0,
"Status": 1,
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe all should be uppercase?

@jonathan-eq jonathan-eq force-pushed the 23042026_show_workflow_status_in_gui branch 3 times, most recently from 2e60d28 to d466b09 Compare May 5, 2026 06:33
@jonathan-eq jonathan-eq requested a review from Copilot May 5, 2026 06:49
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces workflow lifecycle events (batch + per-workflow started/finished/cancelled) and wires them through the run model into the GUI so workflow execution can be visualized in dedicated tabs (including per-iteration/update grouping). It also centralizes HookRuntime under _ert and updates affected tests accordingly.

Changes:

  • Add new workflow event types (Workflow*Event, WorkflowStatus) and emit them from RunModel.run_workflows() and WorkflowRunner.run_blocking().
  • Introduce GUI widgets/tabs (WorkflowWidget, IterationWidget) and update RunDialog to place workflow hooks before/after iteration/update tabs.
  • Expand unit/UI test coverage to assert event emission and GUI tab ordering/behavior for workflows.

Reviewed changes

Copilot reviewed 22 out of 24 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/ert/unit_tests/workflow_runner/test_workflow_runner.py Adds tests asserting per-workflow events include hook/iteration/workflow_name and capture stdout; adds cancellation event assertions.
tests/ert/unit_tests/run_models/test_base_run_model.py Adds test for workflow batch events across multiple workflows, including non-stopping failures.
tests/ert/unit_tests/gui/experiments/test_run_dialog.py Updates GUI unit tests for new IterationWidget structure and adds test for workflow tabs placement around iteration tab.
tests/ert/ui_tests/gui/test_workflow_widget.py New UI test suite validating WorkflowWidget status/label/output rendering and row coloring.
tests/ert/ui_tests/gui/test_update_runs.py Extends UI tests to validate workflow hook tab placement across experiment/iteration/update lifecycle.
tests/ert/ui_tests/gui/test_restart_ensemble_experiment.py Adjusts UI tests to navigate through IterationWidget to reach RealizationWidget.
tests/ert/ui_tests/gui/test_docs_screenshots.py Updates screenshot test navigation for IterationWidget nesting.
tests/ert/ui_tests/gui/conftest.py Updates common GUI test helper to account for IterationWidget tab nesting.
src/ert/workflow_runner.py Emits workflow started/finished/cancelled events and aggregates stdout/stderr across jobs.
src/ert/run_models/update_run_model.py Reorders RunModelUpdateBeginEvent/status emission relative to pre-update workflows.
src/ert/run_models/run_model.py Emits workflow batch started/finished events and passes hook/iteration/name into WorkflowRunner.
src/ert/run_models/event.py Extends run-model event union to include WorkflowEvent.
src/ert/gui/experiments/view/workflow.py New WorkflowWidget displaying workflow status and stdout/stderr in a table with status coloring.
src/ert/gui/experiments/view/iteration.py New IterationWidget to group Run/Update/Workflow sub-tabs per iteration/update.
src/ert/gui/experiments/view/init.py Exports IterationWidget and WorkflowWidget.
src/ert/gui/experiments/run_dialog.py Reworks tab management to use IterationWidget containers and to create/update workflow tabs on workflow events.
src/ert/config/workflow_fixtures.py Switches HookRuntime import to _ert.hook_runtime.
src/ert/config/parsing/hook_runtime.py Removes local HookRuntime definition (moved to _ert).
src/ert/config/parsing/config_schema.py Updates schema typing to use _ert.hook_runtime.HookRuntime.
src/ert/config/parsing/init.py Re-exports _ert.hook_runtime.HookRuntime from parsing package.
src/_ert/hook_runtime.py New home for HookRuntime plus workflow_tab_title() helper for GUI labels.
src/_ert/events.py Adds WorkflowStatus and workflow event models to the shared events module.

Comment thread src/ert/workflow_runner.py Outdated
Comment on lines +185 to +190
logger.info(f"Workflow job {jobrunner.name} starting")
jobrunner.run(args, fixtures=self.fixtures)
try:
jobrunner.run(args, fixtures=self.fixtures)
except Exception as err:
stdout = ""
stderr = str(err)
Comment thread src/ert/workflow_runner.py Outdated
Comment on lines +186 to +188
try:
jobrunner.run(args, fixtures=self.fixtures)
except Exception as err:
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be step 2!

Comment on lines +220 to +222
item.setText("-" if text == "" else text) # noqa: PLC1901
item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
item.setToolTip(text)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't passing None be fine?

@jonathan-eq
Copy link
Copy Markdown
Contributor Author

Now it is possible to cancel hooked workflows while they are running. It is very similar to the fm step statuses during evaluation.

Screen.Recording.2026-05-05.at.14.59.47.mov

@jonathan-eq jonathan-eq force-pushed the 23042026_show_workflow_status_in_gui branch from de417eb to 5f7baed Compare May 5, 2026 13:23
@jonathan-eq jonathan-eq changed the title init Have ert show hooked workflows in GUI May 5, 2026
@jonathan-eq jonathan-eq requested a review from Copilot May 5, 2026 13:24
@jonathan-eq jonathan-eq marked this pull request as ready for review May 5, 2026 13:24
@jonathan-eq jonathan-eq force-pushed the 23042026_show_workflow_status_in_gui branch from 5f7baed to b3a7616 Compare May 5, 2026 13:27
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 23 out of 25 changed files in this pull request and generated 6 comments.

Comment on lines +880 to +884
iteration=workflow_iteration,
workflow_names=workflow_names,
status=WorkflowStatus.CANCELLED,
)
)
Comment on lines +225 to +227
item.setText("-" if text == "" else text) # noqa: PLC1901
item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
item.setToolTip(text)
Comment on lines +201 to +203
@pytest.mark.usefixtures("use_tmpdir")
def test_run_workflows_emits_events_for_following_workflow_after_non_stopping_failure():
WorkflowCommon.createExternalDumpJob()
Comment on lines +280 to +283
def test_run_workflows_cancels_active_workflow_and_stops_following_workflows(
use_tmpdir,
):
WorkflowCommon.createExternalDumpJob()
@pytest.mark.filterwarnings(
"ignore:Use of legacy_ertscript_workflow is deprecated.*:DeprecationWarning"
)
def test_run_dialog_places_all_workflow_hooks_in_expected_tabs(qtbot, tmp_path):
Comment on lines +478 to +480
def test_esmda_with_all_workflows_produces_expected_final_gui(
qtbot, tmp_path, source_root, run_experiment
):
@jonathan-eq
Copy link
Copy Markdown
Contributor Author

Found a new bug: #13487

@jonathan-eq jonathan-eq force-pushed the 23042026_show_workflow_status_in_gui branch 2 times, most recently from b563a68 to 3cac030 Compare May 6, 2026 12:51
This commit changes the GUI to:
* Show iterations and updates in tabs to accommodate showing pre/post
  run/update workflows
* Show pre-experiment and post-experiment workflows on main tab-bar
* Pressing terminate experiment during hooked workflows cancels the
  workflow, and marks it as cancelled by user. Following workflows in
  the same hook will be marked as cancelled, as to not mislead the user.
@jonathan-eq jonathan-eq force-pushed the 23042026_show_workflow_status_in_gui branch from 3cac030 to 12957a2 Compare May 6, 2026 12:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Store output from workflows

3 participants