From b53f1832d80f87be2cfd88990b855c0e5f3cc926 Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Thu, 4 Jun 2026 13:49:44 +0200 Subject: [PATCH] feat(ci): simplify visual regression dispatch to twenty-ui only (#21215) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Only trigger visual regression on `CI UI` workflow (drop `CI Front`) - Remove tarball re-packaging step — `ci-privileged` now downloads the artifact directly via GitHub API - Remove `mode`/`project` parameters from the dispatch payload (hardcoded to twenty-ui in ci-privileged) - Pass `run_id` of the triggering CI UI workflow so ci-privileged can fetch the correct artifact ## Context Part of the fast visual regression CI initiative. The `ci-privileged` workflow has been simplified to only handle `twenty-ui` screenshots uploaded directly to Argos. ## Test plan - [x] Full E2E verified on production: screenshots → Argos build → diff results → PR comment --- .../workflows/visual-regression-dispatch.yaml | 75 +++++++------------ 1 file changed, 25 insertions(+), 50 deletions(-) diff --git a/.github/workflows/visual-regression-dispatch.yaml b/.github/workflows/visual-regression-dispatch.yaml index e2f85a53af6..45ed9500f32 100644 --- a/.github/workflows/visual-regression-dispatch.yaml +++ b/.github/workflows/visual-regression-dispatch.yaml @@ -1,12 +1,12 @@ name: Visual Regression Dispatch -# Uses workflow_run to dispatch visual regression to ci-privileged. -# This runs in the context of the base repo (not the fork), so it has -# access to secrets — making it work for external contributor PRs. +# Dispatches visual regression processing to ci-privileged after CI completes. +# Runs in the context of the base repo (not the fork) so it has access to secrets, +# making it work for external contributor PRs. on: workflow_run: - workflows: ['CI Front', 'CI UI'] + workflows: ['CI UI'] types: [completed] permissions: @@ -21,29 +21,28 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 5 steps: - - name: Determine project and artifact name + - name: Determine project id: project uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0 with: script: | const workflowName = context.payload.workflow_run.name; - if (workflowName === 'CI Front') { - core.setOutput('project', 'twenty-front'); - core.setOutput('artifact_name', 'storybook-static'); - core.setOutput('tarball_name', 'storybook-twenty-front-tarball'); - core.setOutput('tarball_file', 'storybook-twenty-front.tar.gz'); - core.setOutput('mode', 'storybook-tarball'); - } else if (workflowName === 'CI UI') { - core.setOutput('project', 'twenty-ui'); - core.setOutput('artifact_name', 'argos-screenshots-twenty-ui'); - core.setOutput('tarball_name', 'argos-screenshots-twenty-ui-tarball'); - core.setOutput('tarball_file', 'argos-screenshots-twenty-ui.tar.gz'); - core.setOutput('mode', 'argos-screenshots'); - } else { + const projects = { + 'CI UI': { project: 'twenty-ui', artifact: 'argos-screenshots-twenty-ui' }, + // Add more projects here when ready: + // 'CI Front': { project: 'twenty-front', artifact: 'argos-screenshots-twenty-front' }, + }; + + const config = projects[workflowName]; + if (!config) { core.setFailed(`Unexpected workflow: ${workflowName}`); + return; } - - name: Check if artifact exists + core.setOutput('project', config.project); + core.setOutput('artifact_name', config.artifact); + + - name: Check if screenshots artifact exists id: check-artifact uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0 with: @@ -61,7 +60,7 @@ jobs: core.setOutput('exists', found ? 'true' : 'false'); if (!found) { - core.info(`Artifact "${artifactName}" not found in run ${runId} — build was likely skipped`); + core.info(`Artifact "${artifactName}" not found in run ${runId} — skipping`); } - name: Get PR number @@ -73,8 +72,6 @@ jobs: const headBranch = context.payload.workflow_run.head_branch; const headRepo = context.payload.workflow_run.head_repository; - // workflow_run.pull_requests is empty for fork PRs, - // so fall back to searching by head label (owner:branch) let pullRequests = context.payload.workflow_run.pull_requests; let prNumber; @@ -82,7 +79,7 @@ jobs: prNumber = pullRequests[0].number; } else { const headLabel = `${headRepo.owner.login}:${headBranch}`; - core.info(`pull_requests is empty (likely a fork PR), searching by head label: ${headLabel}`); + core.info(`Searching for PR by head label: ${headLabel}`); const { data: prs } = await github.rest.pulls.list({ owner: context.repo.owner, @@ -98,7 +95,7 @@ jobs: } if (!prNumber) { - core.info('No pull request found for this workflow run — skipping'); + core.info('No pull request found — skipping'); core.setOutput('has_pr', 'false'); return; } @@ -107,45 +104,23 @@ jobs: core.setOutput('has_pr', 'true'); core.info(`PR #${prNumber}`); - - name: Download artifact from triggering run - if: steps.check-artifact.outputs.exists == 'true' && steps.pr-info.outputs.has_pr == 'true' - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 - with: - name: ${{ steps.project.outputs.artifact_name }} - path: artifact-content - run-id: ${{ github.event.workflow_run.id }} - github-token: ${{ github.token }} - - - name: Package artifact as tarball - if: steps.check-artifact.outputs.exists == 'true' && steps.pr-info.outputs.has_pr == 'true' - run: tar -czf /tmp/${{ steps.project.outputs.tarball_file }} -C artifact-content . - - - name: Upload tarball - if: steps.check-artifact.outputs.exists == 'true' && steps.pr-info.outputs.has_pr == 'true' - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 - with: - name: ${{ steps.project.outputs.tarball_name }} - path: /tmp/${{ steps.project.outputs.tarball_file }} - retention-days: 1 - - name: Dispatch to ci-privileged if: steps.check-artifact.outputs.exists == 'true' && steps.pr-info.outputs.has_pr == 'true' env: GH_TOKEN: ${{ secrets.CI_PRIVILEGED_DISPATCH_TOKEN }} PR_NUMBER: ${{ steps.pr-info.outputs.pr_number }} - RUN_ID: ${{ github.run_id }} + WORKFLOW_RUN_ID: ${{ github.event.workflow_run.id }} REPOSITORY: ${{ github.repository }} PROJECT: ${{ steps.project.outputs.project }} BRANCH: ${{ github.event.workflow_run.head_branch }} COMMIT: ${{ github.event.workflow_run.head_sha }} - MODE: ${{ steps.project.outputs.mode }} run: | gh api repos/twentyhq/ci-privileged/dispatches \ + --method POST \ -f event_type=visual-regression \ -f "client_payload[pr_number]=$PR_NUMBER" \ - -f "client_payload[run_id]=$RUN_ID" \ + -f "client_payload[run_id]=$WORKFLOW_RUN_ID" \ -f "client_payload[repo]=$REPOSITORY" \ -f "client_payload[project]=$PROJECT" \ -f "client_payload[branch]=$BRANCH" \ - -f "client_payload[commit]=$COMMIT" \ - -f "client_payload[mode]=$MODE" + -f "client_payload[commit]=$COMMIT"