Skip to content

Commit 0ee635f

Browse files
chore: code fencing for gh actions defined at builds.yml (MetaMask#26159)
<!-- 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** Wire Metro’s code-fence removal to **builds.yml** on GitHub Actions while keeping Bitrise/local behavior unchanged. **Why:** On GH Actions, build config (and thus which features are enabled) comes from `builds.yml` via `apply-build-config.js`, which can set `CODE_FENCING_FEATURES`. Metro previously only used `METAMASK_BUILD_TYPE` and `METAMASK_ENVIRONMENT`, so code fencing did not follow the same source of truth. **What changed:** - **GH Actions:** When `CODE_FENCING_FEATURES` is set, Metro uses that JSON array for code-fence removal; `INCLUDE_SAMPLE_FEATURE` still adds `sample-feature` when set. - **Bitrise/local:** When `CODE_FENCING_FEATURES` is not set, behavior is unchanged: features are derived from `METAMASK_BUILD_TYPE` + `METAMASK_ENVIRONMENT` via `getBuildTypeFeaturesFromEnv()`. - **Safety:** The env-based fallback returns new `Set` instances so adding `sample-feature` (or other mutations) does not mutate shared global sets. - **Docs:** Comments and JSDoc clarify the “legacy” (Bitrise/local) vs “GH Actions” paths. **Scope:** Only `metro.transform.js` (no workflow or script changes in this PR). --- ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: Added code fencing for gh actions defined at builds.yml ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** checking code fencing in all builds ✅ main-rc <img width="280" height="675" alt="main-test" src="https://github.com/user-attachments/assets/75d11555-3f76-4f80-bb48-c6a45cb99d64" /> main-exp <img width="280" height="675" alt="main-test" src="https://github.com/user-attachments/assets/04487ad6-359c-448c-9660-f2e139f88dbf" /> main-test <img width="280" height="675" alt="main-test" src="https://github.com/user-attachments/assets/319eb592-691f-4abe-93f3-f3a0467ac0bc" /> main-beta <img width="280" height="675" alt="main-test" src="https://github.com/user-attachments/assets/c38416cb-706f-488f-a031-bcac2d811d8c" /> flask-test <img width="280" height="675" alt="main-test" src="https://github.com/user-attachments/assets/12224fd6-6ac2-4726-b7f4-43ca10ea2f59" /> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [x] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [x] 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. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes the source of truth for code-fence feature gating in CI builds, so misconfigured `CODE_FENCING_FEATURES` could include/exclude fenced code unexpectedly across release flavors. > > **Overview** > Metro’s code-fence removal now **prefers `CODE_FENCING_FEATURES` (JSON from `builds.yml` via CI)** as the active feature set, falling back to the prior `METAMASK_BUILD_TYPE`/`METAMASK_ENVIRONMENT` logic when unset. > > `builds.yml` expands code-fencing anchors to explicitly define `beta` and `experimental` feature sets, and updates the `main-beta` and `main-exp` build configs to use them; the Metro fallback path also now returns fresh `Set` instances to avoid mutating shared feature sets when optionally adding `sample-feature`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit c474217. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Wei Sun <wei.sun@consensys.net>
1 parent d80bfbd commit 0ee635f

2 files changed

Lines changed: 59 additions & 16 deletions

File tree

builds.yml

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,26 @@ _code_fencing_main: &code_fencing_main
120120
- bitcoin
121121
- tron
122122

123+
# Beta code fencing features (main + beta feature)
124+
_code_fencing_beta: &code_fencing_beta
125+
- beta
126+
- preinstalled-snaps
127+
- keyring-snaps
128+
- multi-srp
129+
- solana
130+
- bitcoin
131+
- tron
132+
133+
# Experimental code fencing features (main + experimental)
134+
_code_fencing_experimental: &code_fencing_experimental
135+
- preinstalled-snaps
136+
- keyring-snaps
137+
- multi-srp
138+
- solana
139+
- bitcoin
140+
- tron
141+
- experimental
142+
123143
# Flask code fencing features (includes experimental)
124144
_code_fencing_flask: &code_fencing_flask
125145
- flask
@@ -186,7 +206,7 @@ builds:
186206
METAMASK_ENVIRONMENT: 'beta'
187207
METAMASK_BUILD_TYPE: 'main'
188208
secrets: *secrets
189-
code_fencing: *code_fencing_main
209+
code_fencing: *code_fencing_beta
190210
remote_feature_flags: *remote_feature_flags
191211

192212
# Release candidate
@@ -260,7 +280,7 @@ builds:
260280
IS_TEST: 'false'
261281
MM_ENABLE_SETTINGS_PAGE_DEV_OPTIONS: 'true'
262282
secrets: *secrets
263-
code_fencing: *code_fencing_main
283+
code_fencing: *code_fencing_experimental
264284
remote_feature_flags:
265285
<<: *remote_feature_flags
266286
# Override for experimental testing

metro.transform.js

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ const svgTransformer = require('react-native-svg-transformer');
1212

1313
// Code fence removal variables
1414
const fileExtsToScan = ['.js', '.jsx', '.cjs', '.mjs', '.ts', '.tsx'];
15+
16+
// All available features that can be used in code fences
1517
const availableFeatures = new Set([
1618
'flask',
1719
'preinstalled-snaps',
@@ -26,6 +28,7 @@ const availableFeatures = new Set([
2628
'experimental',
2729
]);
2830

31+
// Legacy (main) hardcoded feature sets — used when CODE_FENCING_FEATURES is not set (e.g. Bitrise / local)
2932
const mainFeatureSet = new Set([
3033
'preinstalled-snaps',
3134
'keyring-snaps',
@@ -53,51 +56,71 @@ const flaskFeatureSet = new Set([
5356
'solana',
5457
'tron',
5558
]);
56-
// Experimental feature set includes all main features plus experimental
5759
const experimentalFeatureSet = new Set([...mainFeatureSet, 'experimental']);
5860

5961
/**
60-
* Gets the features for the current build type, used to determine which code
61-
* fences to remove.
62+
* Gets features from METAMASK_BUILD_TYPE + METAMASK_ENVIRONMENT (main branch logic).
63+
* Used when CODE_FENCING_FEATURES is not set (Bitrise or local).
6264
*
6365
* @returns {Set<string>} The set of features to be included in the build.
6466
*/
65-
function getBuildTypeFeatures() {
67+
function getBuildTypeFeaturesFromEnv() {
6668
const buildType = process.env.METAMASK_BUILD_TYPE ?? 'main';
6769
const envType = process.env.METAMASK_ENVIRONMENT ?? 'production';
6870
let features;
6971

7072
switch (buildType) {
71-
// TODO: Remove uppercase QA once we've consolidated build types
7273
case 'qa':
7374
case 'QA':
7475
case 'main':
75-
// TODO: Refactor this once we've abstracted environment away from build type
7676
if (envType === 'exp') {
77-
// Only include experimental features in experimental environment
78-
features = experimentalFeatureSet;
77+
features = new Set(experimentalFeatureSet);
7978
break;
8079
}
81-
features = envType === 'beta' ? betaFeatureSet : mainFeatureSet;
80+
features =
81+
envType === 'beta' ? new Set(betaFeatureSet) : new Set(mainFeatureSet);
8282
break;
8383
case 'beta':
84-
features = betaFeatureSet;
84+
features = new Set(betaFeatureSet);
8585
break;
8686
case 'flask':
87-
features = flaskFeatureSet;
87+
features = new Set(flaskFeatureSet);
8888
break;
8989
default:
9090
throw new Error(
9191
`Invalid METAMASK_BUILD_TYPE of ${buildType} was passed to metro transform`,
9292
);
9393
}
9494

95-
// Add sample-feature only if explicitly enabled via env var
95+
return features;
96+
}
97+
98+
/**
99+
* Gets the features for the current build type, used to determine which code
100+
* fences to remove.
101+
*
102+
* Default (GH Actions): use CODE_FENCING_FEATURES from env (set by apply-build-config.js from builds.yml).
103+
* Fallback (Bitrise / local): use METAMASK_BUILD_TYPE + METAMASK_ENVIRONMENT with hardcoded sets.
104+
*
105+
* @returns {Set<string>} The set of features to be included in the build.
106+
*/
107+
function getBuildTypeFeatures() {
108+
let featureSet;
109+
110+
// Prefer GH Actions path: single source of truth from builds.yml
111+
if (process.env.CODE_FENCING_FEATURES) {
112+
const features = JSON.parse(process.env.CODE_FENCING_FEATURES);
113+
featureSet = new Set(features);
114+
} else {
115+
// Fallback for Bitrise / local dev builds
116+
featureSet = getBuildTypeFeaturesFromEnv();
117+
}
118+
96119
if (process.env.INCLUDE_SAMPLE_FEATURE === 'true') {
97-
features.add('sample-feature');
120+
featureSet.add('sample-feature');
98121
}
99122

100-
return features;
123+
return featureSet;
101124
}
102125

103126
/**

0 commit comments

Comments
 (0)