Skip to content

fix(INFRA-3631): add job-level permissions to shadow CI caller#30252

Merged
bsgrigorov merged 6 commits into
mainfrom
phase5d/shadow-ci-job-permissions
May 15, 2026
Merged

fix(INFRA-3631): add job-level permissions to shadow CI caller#30252
bsgrigorov merged 6 commits into
mainfrom
phase5d/shadow-ci-job-permissions

Conversation

@alucardzom
Copy link
Copy Markdown
Contributor

@alucardzom alucardzom commented May 15, 2026

Description

This PR finishes INFRA-3631 Namespace shadow CI work in two parts:

1. workflow_call permission cap (startup fix)
With workflow_call, the caller job’s permissions cap the callee. The shadow-ci caller job in ci.yml now declares the permissions downstream jobs need (id-token, statuses, issues, pull-requests, etc.) so shadow runs do not hit startup_failure (see TEC-54198 / prior validation runs in this thread).

2. Token Exchange for shadow dispatch (latest)
The ci-namespace-shadow.yml dispatcher no longer uses a dedicated GitHub App (create-github-app-token). It follows the same pattern as triage-forwarder.yml: OIDC (id-token: write, audience api://token-exchange-service) → POST $TOKEN_EXCHANGE_URL/api/exchange/token with targetRepo = this repo and scoped requested_permissions (metadata/contents read, actions write).

  • TES policy (binds minted tokens to this workflow file via GitHub OIDC claim workflow_ref, not job_workflow_ref): deploy token-exchange-service#77 before relying on exchange in production.
  • Fork PRs: the dispatcher job is skipped when pull_request.head.repo != github.repository, so OIDC exchange never runs for untrusted forks.
  • Duplicate side effects: ci.yml gates status/comment/bundle steps when runner_provider=namespace so shadow runs stay read-mostly at the GitHub API layer.

Changelog

CHANGELOG entry: null

Related issues

Fixes: INFRA-3631

Related: TEC-54198 (TechOps — workflow_call permission inheritance)

Token exchange policy PR: consensys-vertical-apps/token-exchange-service#77

Manual testing steps

Feature: Namespace shadow CI dispatcher

  Scenario: Shadow workflow uses token exchange after TES deploy
    Given TOKEN_EXCHANGE_URL is set and TES policy from PR #77 is deployed
    When a non-fork pull_request triggers ci-namespace-shadow.yml
    Then the dispatch job exchanges OIDC for a token and successfully workflow_dispatch'es ci.yml with runner_provider=namespace

  Scenario: Fork PR does not call token exchange
    Given a pull request from a fork head repository
    When ci-namespace-shadow.yml runs
    Then the dispatch job is skipped and no exchange request is made

Screenshots/Recordings

N/A (CI / GitHub Actions only.)

Before

N/A

After

N/A

Pre-merge author checklist

Performance checks (if applicable)

  • I've tested on Android
  • I've tested with a power user scenario
  • I've instrumented key operations with Sentry traces for production performance metrics

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Note

Medium Risk
Changes GitHub Actions authentication and dispatch flow for shadow CI and conditions out status/comment/publishing steps when running on namespace, which could affect CI observability or external integrations if misconfigured.

Overview
Reworks the Namespace shadow CI workflow to be fire-and-forget by dispatching ci.yml via workflow_dispatch instead of calling it directly, so shadow flakes don’t appear as PR checks or block the merge queue.

Adds OIDC-based Token Exchange Service authentication (scoped actions: write token) for the dispatcher, skips the dispatcher entirely for fork PRs, and posts a step summary linking the originating PR to the dispatched run.

Updates ci.yml to accept optional pr_number/head_sha inputs (used for run-name correlation) and to disable side-effecting behavior on runner_provider=namespace (e.g., commit status publishing, bundle-size shipping, PR comments, fixture-validation reporting) to avoid duplicate statuses/comments and external pushes.

Reviewed by Cursor Bugbot for commit e65e564. Bugbot is set up for automated code reviews on this repo. Configure here.

@alucardzom alucardzom requested a review from a team as a code owner May 15, 2026 13:59
@alucardzom alucardzom added team-mobile-platform Mobile Platform team no-changelog no-changelog Indicates no external facing user changes, therefore no changelog documentation needed labels May 15, 2026
@github-actions
Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamaskbotv2 metamaskbotv2 Bot added the team-dev-ops DevOps team label May 15, 2026
@github-actions github-actions Bot added the pr-not-ready-for-e2e Skip E2E and block merging. Remove this label once the PR is ready to run the E2E tests. label May 15, 2026
@metamaskbotv2 metamaskbotv2 Bot added the INVALID-PR-TEMPLATE PR's body doesn't match template label May 15, 2026
tommasini
tommasini previously approved these changes May 15, 2026
@alucardzom alucardzom enabled auto-merge May 15, 2026 14:07
@alucardzom alucardzom disabled auto-merge May 15, 2026 14:19
@alucardzom alucardzom force-pushed the phase5d/shadow-ci-job-permissions branch from 256f96e to e9a5e8b Compare May 15, 2026 14:21
Comment thread .github/workflows/ci-namespace-shadow.yml Outdated
Add job-level permissions to the shadow-ci caller job. With
workflow_call the caller's permissions cap the callee — ci.yml
jobs declare statuses/issues/pull-requests write, so the caller
must grant at least the same or the workflow fails at startup.

Write permissions are required for the workflow to start but the
shadow should not post duplicate statuses or PR comments. A
follow-up will gate those write steps in ci.yml to skip when
running under the shadow workflow.
@alucardzom alucardzom force-pushed the phase5d/shadow-ci-job-permissions branch from e9a5e8b to 33bcfc1 Compare May 15, 2026 14:27
Gate the 4 write steps in ci.yml to skip when runner_provider is
namespace. This prevents the shadow CI workflow from posting duplicate
commit statuses and PR comments while keeping the jobs running for
their outputs (fingerprint, E2E selection, fixture validation).

- post-build-source-hash: skip status post, keep fingerprint output
- js-bundle-size-check: skip commit status post on main
- smart-e2e-selection: set post-comment to false
- report-fixture-validation: skip PR comment post
@github-actions github-actions Bot added size-S and removed size-XS labels May 15, 2026
Replace workflow_call with gh workflow run so shadow jobs stay out of PR
checks (ALLGREEN). Add optional pr_number/head_sha inputs and run-name for
correlation. Skip ship-js-bundle-size-check on Namespace shadow to avoid
duplicate pushes to mobile_bundlesize_stats.

Secrets: wire ACTIONS_WRITE_TOKEN for dispatch; intended token is a
fine-grained PAT on this repo with Actions: Read and write (plus Metadata:
Read).

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions github-actions Bot added size-M and removed size-S labels May 15, 2026
Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c9f88bf. Configure here.

Comment thread .github/workflows/ci-namespace-shadow.yml
bsgrigorov and others added 2 commits May 15, 2026 10:21
Replace ACTIONS_WRITE_TOKEN with actions/create-github-app-token and document
repo variable/secret names plus required installation permissions.

Co-authored-by: Cursor <cursoragent@cursor.com>
Replace GitHub App token with TOKEN_EXCHANGE_URL exchange aligned to TES policy.

Co-authored-by: Cursor <cursoragent@cursor.com>
@bsgrigorov bsgrigorov requested a review from Copilot May 15, 2026 17:55
@metamaskbotv2 metamaskbotv2 Bot removed the INVALID-PR-TEMPLATE PR's body doesn't match template label May 15, 2026
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 adjusts the Namespace “shadow CI” integration so it can trigger the main ci.yml pipeline without blocking PR checks, and adds correlation inputs/guards to prevent shadow runs from producing duplicate side effects (commit statuses, PR comments, external repo writes).

Changes:

  • Adds run-name plus pr_number / head_sha inputs to ci.yml for better identification/correlation of shadow-dispatched runs.
  • Gates several side-effecting steps/jobs in ci.yml to skip when runner_provider == 'namespace'.
  • Reworks ci-namespace-shadow.yml from a workflow_call-based caller to a “fire-and-forget” dispatcher that uses OIDC token exchange + gh workflow run to start ci.yml.

Reviewed changes

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

File Description
.github/workflows/ci.yml Adds shadow correlation inputs/run-name and skips side-effecting steps on Namespace runs.
.github/workflows/ci-namespace-shadow.yml Replaces workflow_call with an OIDC-authenticated dispatcher that triggers ci.yml via workflow_dispatch.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/ci.yml
name: ci

run-name: >-
${{ inputs.pr_number && format('ci [shadow PR #{0} @ {1}]', inputs.pr_number, inputs.head_sha) || '' }}
Comment thread .github/workflows/ci.yml
retry_wait_seconds: 30
command: yarn install --immutable
- name: Post build-source-hash commit status
if: ${{ inputs.runner_provider != 'namespace' }}
Comment thread .github/workflows/ci-namespace-shadow.yml
Copy link
Copy Markdown
Contributor

@Cal-L Cal-L left a comment

Choose a reason for hiding this comment

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

LGTM

@bsgrigorov bsgrigorov removed the pr-not-ready-for-e2e Skip E2E and block merging. Remove this label once the PR is ready to run the E2E tests. label May 15, 2026
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: None (no tests recommended)
  • Selected Performance tags: None (no tests recommended)
  • Risk Level: low
  • AI Confidence: 95%
click to see 🤖 AI reasoning details

E2E Test Selection:
The two changed files are purely CI/infrastructure workflow files with no impact on application code, E2E test logic, or test infrastructure:

  1. ci-namespace-shadow.yml: Refactored from workflow_call (which nested shadow jobs into PR check suite, risking merge queue blocks on flakes) to a workflow_dispatch fire-and-forget pattern using OIDC token exchange. This is a CI orchestration improvement that prevents shadow CI flakes from blocking merges.

  2. ci.yml: Added pr_number/head_sha inputs for shadow run correlation, a run-name for identification, and inputs.runner_provider != 'namespace' guards on steps that would cause duplicate side effects (commit status posting, bundle size stats, PR comments, fixture results reporting) when running as a Namespace shadow.

Neither file touches:

  • Any application source code
  • E2E test files or test infrastructure (tests/ directory)
  • Test page objects, fixtures, or helpers
  • Any component, controller, or service
  • Performance-sensitive code paths

The changes are purely about CI runner orchestration and preventing duplicate side effects in shadow runs. No E2E tests need to run to validate these changes, and no performance tests are warranted.

Performance Test Selection:
No application code, rendering logic, data loading, or performance-sensitive paths were modified. These are purely CI workflow orchestration changes with no impact on app performance.

View GitHub Actions results

@sonarqubecloud
Copy link
Copy Markdown

@bsgrigorov bsgrigorov added this pull request to the merge queue May 15, 2026
Merged via the queue into main with commit 667412b May 15, 2026
154 of 156 checks passed
@bsgrigorov bsgrigorov deleted the phase5d/shadow-ci-job-permissions branch May 15, 2026 20:44
@github-actions github-actions Bot locked and limited conversation to collaborators May 15, 2026
@metamaskbotv2 metamaskbotv2 Bot added the release-7.79.0 Issue or pull request that will be included in release 7.79.0 label May 15, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

no-changelog no-changelog Indicates no external facing user changes, therefore no changelog documentation needed release-7.79.0 Issue or pull request that will be included in release 7.79.0 size-M team-dev-ops DevOps team team-mobile-platform Mobile Platform team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants