Skip to content

[#131] Added Diffy visual regression workflow with PR label gate.#2516

Merged
AlexSkrypnyk merged 30 commits into
mainfrom
feature/131-diffy-vr
May 28, 2026
Merged

[#131] Added Diffy visual regression workflow with PR label gate.#2516
AlexSkrypnyk merged 30 commits into
mainfrom
feature/131-diffy-vr

Conversation

@AlexSkrypnyk
Copy link
Copy Markdown
Member

@AlexSkrypnyk AlexSkrypnyk commented May 27, 2026

Closes #131

Summary

Adds an opt-in Diffy-powered visual regression workflow to the Vortex template. After a deployment completes, the new notify-diffy notification channel dispatches a GitHub Actions repository_dispatch event that triggers test-vr.yml. The workflow extracts the PR number from the deployed environment URL by matching the pr-<number> segment (host-agnostic - works with Lagoon, Acquia, and any cloud host that follows that URL convention), checks the configured PR label, runs a Diffy comparison via the pinned diffy-cli, fetches the result, and posts a sticky summary comment to the PR. Automated dependency-update PRs (matching deps/* by default) bypass the label gate.

Changes

Notify channel - notify-diffy

  • New .vortex/tooling/src/notify-diffy shell script. Dispatches a repository_dispatch event to GitHub Actions via the REST API; does not call Diffy directly.
  • Standard VORTEX_NOTIFY_* env vars with Diffy-specific overrides (VORTEX_NOTIFY_DIFFY_TOKEN, VORTEX_NOTIFY_DIFFY_REPOSITORY, VORTEX_NOTIFY_DIFFY_SOURCE_ENV, VORTEX_NOTIFY_DIFFY_EVENT_TYPE, VORTEX_NOTIFY_DIFFY_BRANCHES).
  • Skips on pre_deployment; supports optional branch allowlist to avoid unnecessary dispatches.
  • Dispatch payload contains only branch, target_url, label, source_env - no PR number, no commit SHA. The workflow derives the PR from the deployed URL.
  • Validates curl and php as prerequisites; wraps the authenticated curl call with set +x / restore so the GitHub token never leaks under VORTEX_DEBUG=1.
  • One-line addition to .vortex/tooling/src/notify router to invoke the channel when diffy appears in VORTEX_NOTIFY_CHANNELS.
  • New .vortex/tooling/tests/unit/notify-diffy.bats with five BATS tests: pre-deployment skip, post-deployment dispatch, branch-filter skip, dispatch failure (HTTP 401), missing-token validation.

GitHub Actions workflow - test-vr.yml

  • New .github/workflows/test-vr.yml with two jobs: vr-compare and vr-report.
  • Workflow-level least-privilege permissions (contents: read, pull-requests: read). vr-report overrides with pull-requests: write only on the job that posts the comment.
  • vr-compare parses the PR number from target_url via sed -n 's|.*pr-\([0-9]\{1,\}\).*|\1|p', checks the VR label (case-insensitive), installs the pinned Diffy CLI, runs diffy project:compare against the target URL, polls the comparison status with visible progress until done or until VR_DIFFY_MAX_WAIT is exceeded, then fetches the diff result and exposes diff_id, pr_number, skipped, changes_percent, shared_url, pages_changed, and pages_total as job outputs.
  • vr-report is a thin job that posts a sticky PR comment via marocchino/sticky-pull-request-comment@70d2764d1a7d5d9560b100cbea0077fc8f633987 # v3 (same action build-test-deploy.yml uses for the coverage comment). Re-deploys edit the same comment rather than stacking.
  • Automated dependency PRs bypass the label gate when the head branch matches VR_DIFFY_AUTO_BRANCHES (default deps/*, supports comma-separated glob patterns).
  • workflow_dispatch entry point with source_env, target_url, label inputs for ad-hoc comparisons.
  • All tunables read from GitHub Actions repository variables (VR_DIFFY_PROJECT_ID, VR_DIFFY_CLI_VERSION, VR_DIFFY_MAX_WAIT, VR_DIFFY_PR_LABEL, VR_DIFFY_AUTO_BRANCHES, VR_DIFFY_POLL_INTERVAL, VR_DIFFY_SOURCE_ENV). Only the API key is a secret (VR_DIFFY_API_KEY).

Installer

  • New .vortex/installer/src/Prompts/Handlers/VisualRegression.php handler. Default off; multi-paragraph prompt description explaining the three trigger modes (label-gated PRs, dependency-update PRs, manual). process() removes the workflow file when answered "no".
  • Updated .vortex/installer/src/Prompts/PromptManager.php: registered the handler, slotted under the Continuous Integration section after CiProvider, added a Visual regression testing row to the response summary, bumped TOTAL_RESPONSES from 33 to 34.
  • New .vortex/installer/tests/Functional/Handlers/VisualRegressionHandlerProcessTest.php with visual_regression_enabled and visual_regression_disabled fixture scenarios.
  • Updated AbstractHandlerDiscoveryTestCase and AbstractHandlerTypeTest to register the new handler in the discovery-defaults baseline and type-inference data provider.

Documentation

  • New .vortex/docs/content/tools/diffy.mdx - tool-introduction page. Describes Diffy's capabilities (cross-environment comparison, breakpoints, DOM manipulation, CLI, REST API), account/project setup, pricing model, hero screenshot. Vortex-implementation details deliberately live elsewhere.
  • New .vortex/docs/content/development/visual-regression.mdx - workflow page. Owns all integration details: account setup, repository secrets/variables tables, deployment-side configuration, two trigger entry points with vertical ASCII flow diagrams (system-boundary boxes for GitHub / Hosting environment / Diffy), automated dependency PR handling with default-behavior matrix, URL-based PR resolution explanation, missed-window behavior, job descriptions, branch-protection wiring instructions, costs and quotas, disable instructions.
  • Updated features.mdx: promoted Visual regression from "coming soon" to a shipped feature.
  • Updated contributing/roadmap.mdx: removed Visual regression from the future-goals list.
  • Updated .vortex/CLAUDE.md: added "When the installer prompt flow changes" trigger documenting the ahoy update-snapshots and ahoy update-installer-video follow-ups (with explicit note that the video command does not auto-commit).
  • Updated .vortex/docs/CLAUDE.md: added two writing rules - **Vortex** must always be bold in prose, and ASCII diagrams (vertical preferred) are preferred over Mermaid.

Before / After

Deployment notification flow

Before
──────
Deployment
  └─► notify router
        ├─► notify-email
        ├─► notify-slack
        ├─► notify-newrelic
        ├─► notify-github
        ├─► notify-jira
        └─► notify-webhook

After
─────
Deployment
  └─► notify router
        ├─► notify-email
        ├─► notify-slack
        ├─► notify-newrelic
        ├─► notify-github
        ├─► notify-jira
        ├─► notify-webhook
        └─► notify-diffy
              │
              ▼
        repository_dispatch (vr_run)
              │ payload: { branch, target_url, label, source_env }
              ▼
        ┌─ test-vr.yml ───────────────────────────┐
        │                                         │
        │  vr-compare                             │
        │    1. parse PR from target_url          │
        │    2. gate on VR label or deps/*        │
        │    3. install Diffy CLI, authenticate   │
        │    4. project:compare → diff_id         │
        │    5. poll until completed              │
        │    6. fetch diff result → outputs       │
        │                                         │
        │  vr-report                              │
        │    1. sticky PR comment                 │
        │                                         │
        └─────────────────────────────────────────┘

Installer prompt sequence (Continuous Integration section)

Before                         After
──────                         ─────
CI provider                    CI provider
                          -->  Visual regression testing with Diffy?

PR resolution

Before (earlier draft)         After (shipped)
──────                         ─────
notify-diffy sends sha         notify-diffy sends URL only
workflow calls:                workflow extracts PR via:
gh api commits/{sha}/pulls     sed 's|.*pr-\([0-9]\+\).*|\1|' on URL
                                 (host-agnostic, no API call)

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 27, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds Diffy visual regression: a GitHub Actions workflow to run/poll comparisons and post PR reports, a deployment dispatch script and router wiring to trigger it, installer prompts/tests to opt-in, and documentation pages updating features and roadmap.

Changes

Diffy Visual Regression Integration

Layer / File(s) Summary
GitHub Actions test-vr workflow
.github/workflows/test-vr.yml
Workflow orchestrates visual regression testing via Diffy: triggers on deployment dispatch or manual invocation, extracts PR from TARGET_URL, gates by PR label or branch allowlist, installs/uses Diffy CLI to start and poll comparisons, and exposes results for reporting.
Deployment dispatch trigger
.vortex/tooling/src/notify, .vortex/tooling/src/notify-diffy, .vortex/tooling/tests/unit/notify-diffy.bats
notify-diffy builds and POSTs a repository_dispatch payload from deployment, loads env files, validates inputs, optionally filters branches, and prints structured logs. Router wiring enables the diffy notify channel. Bats tests cover skip, success, branch filtering, HTTP errors, and missing-token validation.
Installer configuration handler
.vortex/installer/src/Prompts/Handlers/VisualRegression.php, .vortex/installer/src/Prompts/PromptManager.php, .vortex/installer/tests/Functional/Handlers/VisualRegressionHandlerProcessTest.php, .vortex/installer/tests/Unit/Handlers/AbstractHandlerDiscoveryTestCase.php, .vortex/installer/tests/Unit/Handlers/AbstractHandlerTypeTest.php
Adds a VisualRegression prompt handler (default false), wires it into PromptManager (TOTAL_RESPONSES, prompt order, processor order), supports discovery and removal of the generated workflow, and adds unit/functional tests for discovery, type inference, and enable/disable behavior.
User documentation
.vortex/docs/content/contributing/roadmap.mdx, .vortex/docs/content/development/visual-regression.mdx, .vortex/docs/content/features.mdx, .vortex/docs/content/tools/diffy.mdx
Adds development and tools documentation describing Diffy integration, triggers, required secrets/variables, gating behavior, costs/quotas, and how to disable; updates features doc and removes Visual Regression from roadmap future goals.
sequenceDiagram
  participant Deployer
  participant GitHubActions
  participant DiffyAPI
  participant PullRequest
  Deployer->>GitHubActions: repository_dispatch / workflow_dispatch (sha, target_url, label)
  GitHubActions->>GitHubActions: resolve PR from TARGET_URL
  GitHubActions->>GitHubActions: evaluate label/branch gate
  GitHubActions->>DiffyAPI: start comparison (project_id, source, target, sha)
  GitHubActions->>DiffyAPI: poll comparison status (diff_id)
  DiffyAPI->>GitHubActions: return results / metrics
  GitHubActions->>PullRequest: post PR comment with report URL and metrics
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

I am a rabbit with testing flair,
I summon Diffy to scan the air,
From deploy to PR I chase each hue,
Pixel by pixel I check what’s new,
I thump for bugs and leave a carrot-view 🐰✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: a Diffy-powered visual regression workflow with a PR label gate. It aligns with the primary objective and the most significant additions across the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 90.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/131-diffy-vr

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/test-vr.yml:
- Around line 14-57: Add an explicit least-privilege permissions block to the
workflow (in .github/workflows/test-vr.yml) so the token only has the scopes
needed to read PR metadata and post comments; add a top-level permissions map
(not per-step) with pull-requests: write (to post comments/PR updates) and
contents: read (to read repo/PR metadata), e.g. add a permissions section above
jobs or alongside env; ensure the vr-compare job uses the workflow-level
permissions and do not grant broader scopes like repo or write to everything.
- Around line 83-88: The current pr resolution uses `gh pr list --search
"${SHA}"` and reads `pr_number` from `.[0].number`, which can return incorrect
matches; replace that search-based lookup with the commits→pulls API by calling
`gh api /repos/${{ github.repository }}/commits/${SHA}/pulls` (or equivalent `gh
api` invocation) and extract the PR number from the first item’s `number` field
(e.g., response[0].number) to set `pr_number`, with the same fallback behavior
if the API returns empty; update the step that defines `pr_number` (currently
using `pr_number="$(gh pr list ... --search "${SHA}" ... --jq '.[0].number //
empty' ...)"`) to use the `gh api` call and `--jq` to safely pull `.[0].number
// empty`.

In @.vortex/docs/content/tools/diffy.mdx:
- Around line 96-99: Update the docs in diffy.mdx to stop recommending setting
VORTEX_VR_DIFFY_API_KEY to an empty value as a way to disable Diffy; instead
instruct readers to remove "diffy" from VORTEX_NOTIFY_CHANNELS and delete (or
disable) the .github/workflows/test-vr.yml workflow. Specifically, remove the
sentence suggesting the empty env-var "fail noisily" approach and replace it
with a clear directive to remove the channel or delete/disable the workflow so
CI does not produce avoidable red builds; reference VORTEX_NOTIFY_CHANNELS,
VORTEX_VR_DIFFY_API_KEY, and .github/workflows/test-vr.yml in the updated
guidance.

In @.vortex/installer/src/Prompts/PromptManager.php:
- Around line 222-223: getResponsesSummary() currently omits the new
VisualRegression response added via ->add(fn($r, $pr, $n): mixed =>
$this->prompt(VisualRegression::class), VisualRegression::id()), so the
confirmation view drops that choice; update getResponsesSummary() to include the
VisualRegression::id() key and its human-readable label/value (matching how
other prompts are summarized), ensuring the summary extracts the response from
the prompt store using VisualRegression::id() and formats it consistently with
the existing entries.

In @.vortex/tooling/src/notify-diffy:
- Around line 77-80: The script currently only checks for curl availability in
the loop "for cmd in curl; do command -v \"${cmd}\" ..." but later calls "php
-r" to build the payload; add php to the dependency check (or add an explicit
command -v php check before the php -r block) so the script fails fast with a
clear error; update the same check used for curl (or create a separate check) to
call fail "Command php is not available" if php is missing.
- Line 17: The script enables xtrace with set -x when VORTEX_DEBUG=1 which leaks
VORTEX_NOTIFY_DIFFY_TOKEN because the Authorization header is printed; to fix,
avoid tracing around the sensitive header by surrounding the token usage with
tracing off/on: call set +x before constructing or invoking the Authorization
header (or the curl command that includes it) and then restore set -x afterward
(or save/restore the shell xtrace state), referencing the VORTEX_DEBUG check,
the set -x/set +x calls, the VORTEX_NOTIFY_DIFFY_TOKEN variable and the
Authorization header/curl invocation so the header is never emitted to the logs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: acd541d8-ec31-4cce-add4-8265719c7671

📥 Commits

Reviewing files that changed from the base of the PR and between 5fa4488 and c5252be.

⛔ Files ignored due to path filters (1)
  • .vortex/installer/tests/Fixtures/handler_process/visual_regression_enabled/.github/workflows/test-vr.yml is excluded by !.vortex/installer/tests/Fixtures/**
📒 Files selected for processing (13)
  • .github/workflows/test-vr.yml
  • .vortex/docs/content/contributing/roadmap.mdx
  • .vortex/docs/content/development/visual-regression.mdx
  • .vortex/docs/content/features.mdx
  • .vortex/docs/content/tools/diffy.mdx
  • .vortex/installer/src/Prompts/Handlers/VisualRegression.php
  • .vortex/installer/src/Prompts/PromptManager.php
  • .vortex/installer/tests/Functional/Handlers/VisualRegressionHandlerProcessTest.php
  • .vortex/installer/tests/Unit/Handlers/AbstractHandlerDiscoveryTestCase.php
  • .vortex/installer/tests/Unit/Handlers/AbstractHandlerTypeTest.php
  • .vortex/tooling/src/notify
  • .vortex/tooling/src/notify-diffy
  • .vortex/tooling/tests/unit/notify-diffy.bats

Comment thread .github/workflows/test-vr.yml
Comment thread .github/workflows/test-vr.yml Outdated
Comment thread .vortex/docs/content/tools/diffy.mdx Outdated
Comment thread .vortex/installer/src/Prompts/PromptManager.php
Comment thread .vortex/tooling/src/notify-diffy
Comment thread .vortex/tooling/src/notify-diffy Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/test-vr.yml (1)

68-97: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Skip PR-number resolution for workflow_dispatch runs

For workflow_dispatch, github.sha is the commit SHA of the ref used to trigger the run, and GET /repos/{owner}/{repo}/commits/{sha}/pulls can return merged PRs associated with that commit—so resolving pr_number this way can target an unrelated historical PR during manual compares.

Suggested fix
       - name: Resolve PR number from commit SHA
         id: resolve_pr
         env:
           GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
         run: |
           set -euo pipefail
+
+          if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
+            echo "pr_number=" >> "$GITHUB_OUTPUT"
+            exit 0
+          fi
 
           # Hint from dispatch payload (some hosts can expose PR number;
           # use it directly to skip the API call if present).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/test-vr.yml around lines 68 - 97, The step with id
"resolve_pr" currently always tries to derive pr_number from the commit SHA; add
a guard to skip that resolution for workflow_dispatch runs by checking the event
name (GITHUB_EVENT_NAME or github.event_name) at the top of the run block and
short-circuiting with an empty pr_number and a notice when the event is
"workflow_dispatch", so the later gh API call that uses SHA (and variables
SHA/pr_number) is not executed for manual dispatches.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/test-vr.yml:
- Around line 35-37: The workflow currently grants pull-requests: write at the
top-level permissions which gives all jobs (including vr-compare) unnecessary
write access; change the top-level permissions to only include contents: read
and move pull-requests: write into the job-level permissions for the vr-report
job (the job named "vr-report") so that only that job gets PR write rights;
ensure vr-compare keeps the default or an explicit job-level permissions that
does not include pull-requests: write.

---

Outside diff comments:
In @.github/workflows/test-vr.yml:
- Around line 68-97: The step with id "resolve_pr" currently always tries to
derive pr_number from the commit SHA; add a guard to skip that resolution for
workflow_dispatch runs by checking the event name (GITHUB_EVENT_NAME or
github.event_name) at the top of the run block and short-circuiting with an
empty pr_number and a notice when the event is "workflow_dispatch", so the later
gh API call that uses SHA (and variables SHA/pr_number) is not executed for
manual dispatches.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f79f2857-b2b3-4a7d-9f41-9c17bf569161

📥 Commits

Reviewing files that changed from the base of the PR and between 7027130 and 749461c.

📒 Files selected for processing (4)
  • .github/workflows/test-vr.yml
  • .vortex/docs/content/tools/diffy.mdx
  • .vortex/installer/src/Prompts/PromptManager.php
  • .vortex/tooling/src/notify-diffy

Comment thread .github/workflows/test-vr.yml Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
.vortex/tooling/tests/unit/notify-diffy.bats (1)

29-49: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Assert the dispatch payload in the happy-path test.

This only checks log lines. The critical contract here is the repository_dispatch body, and a regression that drops source_env, renames target_url, or adds pr_number would still pass. Please inspect the mocked curl arguments in this case as well.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.vortex/tooling/tests/unit/notify-diffy.bats around lines 29 - 49, The test
Notify: diffy, post_deployment only asserts log lines but must also assert the
actual repository_dispatch payload sent via curl; update the test (the block
that sets up mock_curl via mock_command "curl" and calls run
./.vortex/tooling/src/notify) to capture the curl invocation arguments and add
assertions that the JSON body includes the expected keys/values (repository,
event_type, and the payload fields: source_env, target_url, label/pr branch info
and diffy token/repo) to prevent regressions like renamed/removed fields; use
the existing mock command helpers to inspect the recorded curl request and
assert the precise JSON fields and values are present.
.github/workflows/test-vr.yml (1)

132-139: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Match the VR opt-in label literally.

grep -qx "${needle}" treats DIFFY_PR_LABEL as a regex; labels like vr[beta] or release.* can incorrectly fail/pass the gate. Switch to fixed-string matching.

🩹 Proposed fix
-          if echo "${labels_lower}" | grep -qx "${needle}"; then
+          if echo "${labels_lower}" | grep -Fqx -- "${needle}"; then
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/test-vr.yml around lines 132 - 139, The label check
currently builds needle from DIFFY_PR_LABEL and uses grep -qx which treats the
needle as a regex; update the check to use fixed-string matching (e.g., grep -F
-x -q or grep -Fxq) so labels like vr[beta] or release.* are matched literally;
modify the condition that references needle/labels_lower and replace the grep
flags accordingly to ensure exact, literal label comparison.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.vortex/CLAUDE.md:
- Around line 102-104: Replace the misleading phrase "write commits
automatically" in the guidance about the ahoy commands with wording that
accurately reflects their behavior: state that `ahoy update-snapshots` and `ahoy
update-installer-video` "update generated files automatically" (or "update files
automatically") rather than implying they create VCS commits; keep the note that
you should run these commands after the installer code change is committed
because the regeneration compares against the committed baseline.

In @.vortex/docs/content/development/visual-regression.mdx:
- Around line 258-268: The docs overstate the vr-compare job interface: update
the `vr-compare` section to reflect that the job only exposes the outputs
`diff_id`, `pr_number`, and `skipped` and does not fetch final diff results or
expose change percentage, page counts, or shared report URL; remove or move any
bullets claiming result fetching/fields to the downstream job documentation and
clearly state that final diff retrieval and reporting are handled by the
downstream step(s).
- Around line 124-131: The documentation is inconsistent: the `notify-diffy`
description claims PRs are extracted from a pr-<number> URL and that no commit
SHA is sent, but the workflow actually resolves PRs via the commits/{sha}/pulls
API; update the text to state that the payload includes the commit SHA and that
the workflow looks up PRs using commits/{sha}/pulls (and still verifies the VR
label case-insensitively), remove or replace the pr-<number> URL-extraction
guidance, and apply the same correction to the other affected section noted (the
block also referenced in the comment).

In @.vortex/installer/src/Prompts/Handlers/VisualRegression.php:
- Line 33: The prompt string "Automatically triggers comparisons for
dependency-update pull requests." in the VisualRegression handler is
misleadingly unconditional; update the text in the VisualRegression prompt (the
string literal in the VisualRegression class/handler) to state that dependency
PR auto-runs are allowlist-based and gated by branch-patterns (e.g.,
"Automatically triggers comparisons for allowlisted dependency-update pull
requests matching configured branch patterns."). Ensure the revised wording
replaces the original literal so users understand the gated behavior.

---

Outside diff comments:
In @.github/workflows/test-vr.yml:
- Around line 132-139: The label check currently builds needle from
DIFFY_PR_LABEL and uses grep -qx which treats the needle as a regex; update the
check to use fixed-string matching (e.g., grep -F -x -q or grep -Fxq) so labels
like vr[beta] or release.* are matched literally; modify the condition that
references needle/labels_lower and replace the grep flags accordingly to ensure
exact, literal label comparison.

In @.vortex/tooling/tests/unit/notify-diffy.bats:
- Around line 29-49: The test Notify: diffy, post_deployment only asserts log
lines but must also assert the actual repository_dispatch payload sent via curl;
update the test (the block that sets up mock_curl via mock_command "curl" and
calls run ./.vortex/tooling/src/notify) to capture the curl invocation arguments
and add assertions that the JSON body includes the expected keys/values
(repository, event_type, and the payload fields: source_env, target_url,
label/pr branch info and diffy token/repo) to prevent regressions like
renamed/removed fields; use the existing mock command helpers to inspect the
recorded curl request and assert the precise JSON fields and values are present.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f683ef89-a3ff-4204-a9ba-db7e3c5ff5fc

📥 Commits

Reviewing files that changed from the base of the PR and between d826166 and 69d8345.

⛔ Files ignored due to path filters (1)
  • .vortex/docs/static/img/installer.svg is excluded by !**/*.svg
📒 Files selected for processing (11)
  • .github/workflows/test-vr.yml
  • .vortex/CLAUDE.md
  • .vortex/docs/CLAUDE.md
  • .vortex/docs/content/development/visual-regression.mdx
  • .vortex/docs/content/tools/diffy.mdx
  • .vortex/docs/static/img/diffy-hero.webp
  • .vortex/docs/static/img/installer.json
  • .vortex/installer/CLAUDE.md
  • .vortex/installer/src/Prompts/Handlers/VisualRegression.php
  • .vortex/tooling/src/notify-diffy
  • .vortex/tooling/tests/unit/notify-diffy.bats

Comment thread .vortex/CLAUDE.md Outdated
Comment on lines +124 to +131
`notify-diffy` dispatches the workflow with a payload containing the
branch, target URL, label, and source environment - **no PR number, no
commit SHA**. The workflow itself extracts the PR number from the
deployed environment URL by matching the `pr-<number>` segment (e.g.
`https://pr-123.example.com/` resolves to PR #123) and verifies the
`VR` label is present (case-insensitive). If the target URL has no
`pr-<number>` segment, the deployment is not a PR environment and the
run is skipped.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot May 28, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

PR resolution docs conflict with workflow contract.

These sections document URL-based PR extraction (pr-<number>) and explicitly say no commit SHA is sent, but the PR objective/workflow contract for this change resolves PR via commit SHA (commits/{sha}/pulls). Please align this page with the SHA-based lookup path to avoid incorrect operator setup and debugging assumptions.

Also applies to: 225-244

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.vortex/docs/content/development/visual-regression.mdx around lines 124 -
131, The documentation is inconsistent: the `notify-diffy` description claims
PRs are extracted from a pr-<number> URL and that no commit SHA is sent, but the
workflow actually resolves PRs via the commits/{sha}/pulls API; update the text
to state that the payload includes the commit SHA and that the workflow looks up
PRs using commits/{sha}/pulls (and still verifies the VR label
case-insensitively), remove or replace the pr-<number> URL-extraction guidance,
and apply the same correction to the other affected section noted (the block
also referenced in the comment).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Not applying. The docs describe the current implementation, which deliberately resolves PRs by parsing the deployed environment URL for a pr-<number> segment - not via the commits/{sha}/pulls API. An earlier draft used the SHA-based lookup, but that approach was replaced at the maintainer's direction several commits ago because (a) the notify-diffy payload no longer carries a commit SHA, and (b) the deployed URL is the canonical identifier of a PR environment across all hosting providers. The current vr-compare step (Resolve PR number from target URL in .github/workflows/test-vr.yml) reflects this, and the docs match. The "no commit SHA" line is intentional and accurate.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@AlexSkrypnyk, understood — my comment was based on stale information from the PR objectives summary, which reflected an earlier draft. The current implementation is clearly URL-based (pr-<number> segment extraction), the notify-diffy payload intentionally carries no commit SHA, and the docs accurately match the code. I'll note this for future reviews.

(ᴗ˳ᴗ)


✏️ Learnings added
Learnt from: AlexSkrypnyk
Repo: drevops/vortex PR: 2516
File: .vortex/docs/content/development/visual-regression.mdx:124-131
Timestamp: 2026-05-28T03:49:09.111Z
Learning: In the Vortex Diffy visual regression workflow (`.github/workflows/test-vr.yml`), PR resolution is intentionally done by parsing the deployed environment URL for a `pr-<number>` segment (e.g. `https://pr-123.example.com/` → PR `#123`), NOT via the `commits/{sha}/pulls` GitHub API. The `notify-diffy` payload deliberately carries no commit SHA; the deployed URL is the canonical PR environment identifier. The documentation in `.vortex/docs/content/development/visual-regression.mdx` is correct when it states this URL-based approach and "no commit SHA".

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Comment thread .vortex/docs/content/development/visual-regression.mdx
Comment thread .vortex/installer/src/Prompts/Handlers/VisualRegression.php Outdated
@AlexSkrypnyk AlexSkrypnyk added this to the 1.39.0 milestone May 28, 2026
… result fetch into vr-compare, sticky PR comment.
@AlexSkrypnyk AlexSkrypnyk force-pushed the feature/131-diffy-vr branch from c819668 to 2a1efe0 Compare May 28, 2026 04:51
@github-actions
Copy link
Copy Markdown

Code coverage (threshold: 90%)

  Classes: 100.00% (1/1)
  Methods: 100.00% (2/2)
  Lines:   98.53% (201/204)
Per-class coverage
Drupal\ys_demo\Plugin\Block\CounterBlock
  Methods: 100.00% ( 2/ 2)   Lines: 100.00% ( 10/ 10)

@AlexSkrypnyk

This comment has been minimized.

2 similar comments
@AlexSkrypnyk
Copy link
Copy Markdown
Member Author

Code coverage (threshold: 90%)

  Classes: 100.00% (1/1)
  Methods: 100.00% (2/2)
  Lines:   98.53% (201/204)
Per-class coverage
Drupal\ys_demo\Plugin\Block\CounterBlock
  Methods: 100.00% ( 2/ 2)   Lines: 100.00% ( 10/ 10)

@AlexSkrypnyk
Copy link
Copy Markdown
Member Author

Code coverage (threshold: 90%)

  Classes: 100.00% (1/1)
  Methods: 100.00% (2/2)
  Lines:   98.53% (201/204)
Per-class coverage
Drupal\ys_demo\Plugin\Block\CounterBlock
  Methods: 100.00% ( 2/ 2)   Lines: 100.00% ( 10/ 10)

@codecov
Copy link
Copy Markdown

codecov Bot commented May 28, 2026

Codecov Report

❌ Patch coverage is 84.61538% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.04%. Comparing base (9c7c3c0) to head (2a1efe0).

Files with missing lines Patch % Lines
...Unit/Handlers/AbstractHandlerDiscoveryTestCase.php 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2516      +/-   ##
==========================================
- Coverage   86.50%   86.04%   -0.46%     
==========================================
  Files          93       87       -6     
  Lines        4661     4515     -146     
  Branches       47        3      -44     
==========================================
- Hits         4032     3885     -147     
- Misses        629      630       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@AlexSkrypnyk AlexSkrypnyk merged commit 90365f3 into main May 28, 2026
30 checks passed
@AlexSkrypnyk AlexSkrypnyk deleted the feature/131-diffy-vr branch May 28, 2026 05:16
@github-project-automation github-project-automation Bot moved this from BACKLOG to Release queue in Vortex May 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Release queue

Development

Successfully merging this pull request may close these issues.

Add integration with Diffy for Visual Regression

1 participant