Skip to content

Commit 2600ea4

Browse files
authored
test: MM 1525 - Create a production sync job to sync feature flags from PROD (MetaMask#27405)
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## Description Automates detection of drift between the local feature flag registry and production, with CI workflow and Slack notification so the team is alerted when the registry diverges from what is live. **Why:** The local feature flag registry can drift from production without notice, causing E2E or config problems. **What was added:** - **Production sync script** (`tests/feature-flags/sync-production-flags.ts`): Fetches from production client-config API, compares to registry, and reports drift (new flags, removed flags, value mismatches, inProd mismatches). Excludes `mobileMinimumVersions`. - **CLI:** `yarn feature-flags:sync`, `yarn feature-flags:sync:check`, `yarn feature-flags:sync:update` - **Daily CI workflow:** Runs sync check, uploads drift report artifact, notifies Slack on drift - **Unit tests:** For drift detection logic ## Changelog CHANGELOG entry: null ## Related issues Fixes: https://consensyssoftware.atlassian.net/browse/MMQA-1525 ## Manual testing steps ```gherkin Feature: Feature flag registry drift detection Scenario: Developer checks for registry drift Given the local feature flag registry may differ from production When the developer runs `yarn feature-flags:sync` Then they see a report of new, removed, or mismatched flags (or no drift) Scenario: Developer updates registry from production Given drift is detected between registry and production When the developer runs `yarn feature-flags:sync:update` Then the registry file is updated and Prettier-formatted Scenario: CI detects drift Given the workflow runs and production differs from the registry When the workflow completes Then a drift report artifact is uploaded and Slack is notified ``` ## Screenshots/Recordings <img width="720" height="188" alt="image" src="https://github.com/user-attachments/assets/e6d466c5-119e-4f49-a45c-d6affec641ac" /> <img width="594" height="154" alt="image" src="https://github.com/user-attachments/assets/7e9127f1-0e42-4611-a992-31efb0d5de1a" /> ## Pre-merge author checklist - [ ] I've followed MetaMask Contributor Docs and MetaMask Mobile Coding Standards - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using JSDoc format if applicable - [ ] I've applied the right labels on the PR ## Pre-merge reviewer checklist - [ ] I've manually tested the PR - [ ] I confirm this PR addresses all acceptance criteria and includes necessary testing evidence <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Adds a scheduled GitHub Actions workflow that fetches production flags, writes artifacts, and can open PRs/notify Slack, which could generate noise or unintended updates if the sync logic or API behavior is wrong. > > **Overview** > Adds an automated production drift detector for the feature-flag registry. A new `tests/feature-flags/sync-production-flags.ts` CLI fetches flags from the production client-config API, compares them to `tests/feature-flags/feature-flag-registry.ts`, emits a JSON report, and supports `--check` (exit 1 on drift) and `--update` (rewrite registry values, add/remove entries, and flip stale `inProd` flags). > > Introduces unit coverage for drift detection and registry rewriting, and wires it into CI via a scheduled/manual GitHub Actions workflow that runs the check weekly, uploads drift artifacts, opens an automated PR with the updated registry, and posts a Slack notification when drift is found. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 0bc4a67. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent d99884d commit 2600ea4

4 files changed

Lines changed: 1145 additions & 0 deletions

File tree

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
name: Check Feature Flag Registry Drift PROD
2+
3+
on:
4+
schedule:
5+
# Run every Tuesday at 01:00 UTC
6+
- cron: "0 1 * * 2"
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: write
11+
pull-requests: write
12+
13+
jobs:
14+
check-feature-flag-registry:
15+
name: Check feature flag registry against production
16+
environment: default-branch
17+
runs-on: ubuntu-latest
18+
timeout-minutes: 15
19+
outputs:
20+
has-drift: ${{ steps.check.outputs.HAS_DRIFT }}
21+
steps:
22+
- name: Checkout repository
23+
uses: actions/checkout@v4
24+
25+
- name: Setup Node.js
26+
uses: actions/setup-node@v4
27+
with:
28+
node-version-file: ".nvmrc"
29+
cache: "yarn"
30+
31+
- name: Install dependencies with retry
32+
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 #v3.0.2
33+
with:
34+
timeout_minutes: 10
35+
max_attempts: 3
36+
retry_wait_seconds: 30
37+
command: yarn install --immutable
38+
39+
- name: Check for drift and generate report
40+
id: check
41+
shell: bash
42+
run: |
43+
set +e
44+
yarn feature-flags:sync:check 2>&1 | tee sync-report.txt
45+
EXIT="${PIPESTATUS[0]}"
46+
set -e
47+
echo "HAS_DRIFT=$( [ "$EXIT" -eq 1 ] && echo true || echo false )" >> "$GITHUB_OUTPUT"
48+
echo "HAS_ERROR=$( [ "$EXIT" -eq 2 ] && echo true || echo false )" >> "$GITHUB_OUTPUT"
49+
# Succeed for 0 (no drift) and 1 (drift); fail for 2 (API/script error)
50+
[ "$EXIT" -eq 0 ] || [ "$EXIT" -eq 1 ] || exit "$EXIT"
51+
52+
- name: Update registry and prepare artifacts
53+
if: steps.check.outputs.HAS_DRIFT == 'true'
54+
shell: bash
55+
run: |
56+
yarn feature-flags:sync:update
57+
cp sync-report.json report.json
58+
59+
- name: Upload drift report
60+
if: steps.check.outputs.HAS_DRIFT == 'true'
61+
uses: actions/upload-artifact@v4
62+
with:
63+
name: drift-report
64+
path: report.json
65+
66+
- name: Upload updated registry
67+
if: steps.check.outputs.HAS_DRIFT == 'true'
68+
uses: actions/upload-artifact@v4
69+
with:
70+
name: updated-registry
71+
path: tests/feature-flags/feature-flag-registry.ts
72+
73+
create-drift-pr:
74+
name: Create PR for feature flag registry drift
75+
needs: check-feature-flag-registry
76+
if: needs.check-feature-flag-registry.outputs.has-drift == 'true'
77+
uses: MetaMask/github-tools/.github/workflows/create-pr-feature-flag-registry-drift.yml@e37c7027dd6f73d20f36b1d9dbeab3b084874eb6
78+
with:
79+
repository: metamask-mobile
80+
registry-file-path: tests/feature-flags/feature-flag-registry.ts
81+
registry-artifact-name: updated-registry
82+
report-artifact-name: drift-report
83+
workflow-run-url: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
84+
pr-title-prefix: 'test: Sync Feature Flag Registry'
85+
pr-label: 'team-qa,no-changelog'
86+
secrets:
87+
github-token: ${{ secrets.GITHUB_TOKEN }}
88+
89+
notify-slack:
90+
name: Notify Slack on drift
91+
needs: [check-feature-flag-registry, create-drift-pr]
92+
if: always() && needs.check-feature-flag-registry.outputs.has-drift == 'true' && !cancelled()
93+
runs-on: ubuntu-latest
94+
environment: default-branch
95+
steps:
96+
- name: Send Slack notification
97+
uses: MetaMask/github-tools/.github/actions/feature-flag-drift-slack-noti@e37c7027dd6f73d20f36b1d9dbeab3b084874eb6
98+
with:
99+
title: MetaMask Mobile
100+
slack-webhook: ${{ secrets.SLACK_WEBHOOK_FEATURE_FLAG_DRIFT }}
101+
workflow-run-url: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
102+
pr-url: ${{ needs.create-drift-pr.outputs.pr-url || '' }}

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,9 @@
134134
"gen-bundle:android": "yarn react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/main.jsbundle",
135135
"circular:deps": "dpdm ./app/* --circular --exit-code circular:1 --warning=false",
136136
"generate-icons": "yarn ts-node app/component-library/components/Icons/Icon/scripts/generate-assets.ts",
137+
"feature-flags:sync": "ts-node tests/feature-flags/sync-production-flags.ts",
138+
"feature-flags:sync:check": "ts-node tests/feature-flags/sync-production-flags.ts --check",
139+
"feature-flags:sync:update": "ts-node tests/feature-flags/sync-production-flags.ts --update",
137140
"worktree:create": "yarn ts-node --transpile-only scripts/worktree-create.ts",
138141
"worktree:remove": "yarn ts-node --transpile-only scripts/worktree-remove.ts",
139142
"a:start": "scripts/perps/agentic/start-metro.sh",

0 commit comments

Comments
 (0)