Skip to content

Commit 976baed

Browse files
committed
Merge branch 'master' into release
2 parents 4722ad3 + f180478 commit 976baed

File tree

209 files changed

+4501
-7457
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

209 files changed

+4501
-7457
lines changed
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
name: PR Description Validation
2+
3+
on:
4+
pull_request:
5+
types: [opened, edited, synchronize]
6+
7+
jobs:
8+
validate-pr-description:
9+
runs-on: ubuntu-latest
10+
name: Validate PR Description
11+
12+
steps:
13+
- name: Validate PR Description
14+
uses: actions/github-script@v7
15+
with:
16+
script: |
17+
const prBody = context.payload.pull_request.body || '';
18+
console.log('Validating PR body...');
19+
20+
// Define required sections from the PR template
21+
const requiredSections = [
22+
{
23+
name: 'Description',
24+
header: '## Description',
25+
placeholder: 'Enter description to help the reviewer understand what\'s the change about...'
26+
},
27+
{
28+
name: 'Changelog',
29+
header: '## Changelog',
30+
placeholder: 'Add a quick message for our users about this change'
31+
},
32+
{
33+
name: 'Additional info',
34+
header: '## Additional info',
35+
placeholder: 'If applicable, add additional info such as link to the bug being fixed by this PR'
36+
}
37+
];
38+
39+
const missingOrEmptySections = [];
40+
const completedSections = [];
41+
42+
// Validate each required section
43+
for (const section of requiredSections) {
44+
console.log(`Checking section: ${section.name}`);
45+
46+
// Check if section header exists
47+
if (!prBody.includes(section.header)) {
48+
missingOrEmptySections.push({
49+
name: section.name,
50+
issue: 'Section is missing completely'
51+
});
52+
continue;
53+
}
54+
55+
// Extract content after the section header
56+
const sectionRegex = new RegExp(
57+
`${section.header.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\s*(?:<!--[\\s\\S]*?-->)?\\s*([\\s\\S]*?)(?=##|$)`,
58+
'i'
59+
);
60+
61+
const match = prBody.match(sectionRegex);
62+
63+
if (!match) {
64+
missingOrEmptySections.push({
65+
name: section.name,
66+
issue: 'Section header found but no content detected'
67+
});
68+
continue;
69+
}
70+
71+
let content = match[1].trim();
72+
73+
// Remove HTML comments from content for validation
74+
content = content.replace(/<!--[\s\S]*?-->/g, '').trim();
75+
76+
// Check if section is empty or contains only template text
77+
if (!content || content.length === 0) {
78+
missingOrEmptySections.push({
79+
name: section.name,
80+
issue: 'Section is empty - please add content'
81+
});
82+
} else if (content.includes(section.placeholder)) {
83+
missingOrEmptySections.push({
84+
name: section.name,
85+
issue: 'Section contains template placeholder text - please replace with actual content'
86+
});
87+
} else {
88+
completedSections.push(section.name);
89+
console.log(`✅ ${section.name} section is properly filled`);
90+
}
91+
}
92+
93+
// Create feedback message
94+
let commentBody = '';
95+
let statusIcon = '';
96+
let statusTitle = '';
97+
98+
if (missingOrEmptySections.length === 0) {
99+
// All sections are complete
100+
statusIcon = '✅';
101+
statusTitle = 'PR Description Validation Passed';
102+
commentBody += `## ${statusIcon} ${statusTitle}\n\n`;
103+
commentBody += 'All required sections are properly filled out:\n\n';
104+
105+
completedSections.forEach(section => {
106+
commentBody += `- ✅ **${section}**\n`;
107+
});
108+
109+
commentBody += '\nYour PR is good for review! 🚀\n';
110+
111+
} else {
112+
// Some sections are missing or incomplete
113+
statusIcon = '❌';
114+
statusTitle = 'PR Description Validation Failed';
115+
commentBody += `## ${statusIcon} ${statusTitle}\n\n`;
116+
commentBody += 'The following required sections need attention:\n\n';
117+
118+
missingOrEmptySections.forEach(section => {
119+
commentBody += `- ❌ **${section.name}**: ${section.issue}\n`;
120+
});
121+
122+
if (completedSections.length > 0) {
123+
commentBody += '\n**Completed sections:**\n';
124+
completedSections.forEach(section => {
125+
commentBody += `- ✅ **${section}**\n`;
126+
});
127+
}
128+
129+
commentBody += '\n---\n\n';
130+
commentBody += '### Required Sections:\n';
131+
commentBody += '- [ ] **Description** - Explain what changes are being made and why\n';
132+
commentBody += '- [ ] **Changelog** - User-facing summary, this will show in the release notes (include component names, relevant props, and general purpose)\n';
133+
commentBody += '- [ ] **Additional info** - Links to related issues, Jira tickets\n\n';
134+
commentBody += 'Please update your PR description to include all required sections with meaningful content.\n';
135+
}
136+
137+
commentBody += '\n---\n';
138+
commentBody += '_This validation ensures all sections from the [PR template](/wix/react-native-ui-lib/blob/master/.github/pull_request_template.md) are properly filled._';
139+
140+
// Find existing validation comment to update it
141+
const { data: comments } = await github.rest.issues.listComments({
142+
owner: context.repo.owner,
143+
repo: context.repo.repo,
144+
issue_number: context.payload.pull_request.number,
145+
});
146+
147+
const botComment = comments.find(comment =>
148+
comment.user.type === 'Bot' &&
149+
comment.body.includes('PR Description Validation')
150+
);
151+
152+
if (botComment) {
153+
// Update existing comment
154+
await github.rest.issues.updateComment({
155+
owner: context.repo.owner,
156+
repo: context.repo.repo,
157+
comment_id: botComment.id,
158+
body: commentBody
159+
});
160+
console.log('Updated existing validation comment');
161+
} else {
162+
// Create new comment
163+
await github.rest.issues.createComment({
164+
owner: context.repo.owner,
165+
repo: context.repo.repo,
166+
issue_number: context.payload.pull_request.number,
167+
body: commentBody
168+
});
169+
console.log('Created new validation comment');
170+
}
171+
172+
// Set workflow status
173+
if (missingOrEmptySections.length > 0) {
174+
const failureMessage = `Missing or incomplete sections: ${missingOrEmptySections.map(s => s.name).join(', ')}`;
175+
core.setFailed(failureMessage);
176+
console.log(`❌ Validation failed: ${failureMessage}`);
177+
} else {
178+
console.log('✅ PR description validation passed - all sections complete!');
179+
}

.gitignore

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ DerivedData
2121
*.ipa
2222
*.xcuserstate
2323
project.xcworkspace
24-
ios/.xcode.env.local
24+
**/.xcode.env.local
2525

2626
# Android/IntelliJ
2727
#
@@ -43,11 +43,17 @@ expoDemo/android/gradlew.bat
4343
node_modules/
4444
npm-debug.log
4545

46-
# yarn
46+
# Yarn
47+
.yarn/*
4748
yarn-error.log
4849
**/.yarn/cache
4950
**/.yarn/install-state.gz
5051
**/.yarn/yarn.build.json
52+
!.yarn/patches
53+
!.yarn/plugins
54+
!.yarn/releases
55+
!.yarn/sdks
56+
!.yarn/versions
5157

5258
.vscode
5359

@@ -74,7 +80,7 @@ docs/components/**
7480
!scripts/build
7581

7682
# Ruby / CocoaPods
77-
/ios/Pods/
83+
**/Pods/
7884
/vendor/bundle/
7985
/ios/Podfile.lock
8086
expoDemo/ios/Pods

Gemfile

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ source 'https://rubygems.org'
33
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
44
ruby ">= 2.6.10"
55

6-
# Cocoapods 1.15 introduced a bug which break the build. We will remove the upper
7-
# bound in the template on Cocoapods with next React Native release.
8-
gem 'cocoapods', '>= 1.13', '< 1.15'
9-
gem 'activesupport', '>= 6.1.7.5', '< 7.1.0'
6+
# Exclude problematic versions of cocoapods and activesupport that causes build failures.
7+
gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1'
8+
gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0'
9+
gem 'xcodeproj', '< 1.26.0'
10+
gem 'concurrent-ruby', '< 1.3.4'
1011

android/app/build.gradle

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,16 @@ apply plugin: "com.facebook.react"
1313
*/
1414
react {
1515
/* Folders */
16-
// The root of your project, i.e. where "package.json" lives. Default is '..'
16+
// The root of your project, i.e. where "package.json" lives. Default is '../..'
1717
root = file("../../")
18-
// The folder where the react-native NPM package is. Default is ../node_modules/react-native
18+
// The folder where the react-native NPM package is. Default is ../../node_modules/react-native
1919
reactNativeDir = file("../../node_modules/react-native")
20-
// The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen
21-
// codegenDir = file("../node_modules/@react-native/codegen")
22-
// The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js
23-
// cliFile = file("../node_modules/react-native/cli.js")
20+
// reactNativeDir = file("../../node_modules/react-native")
21+
// The folder where the react-native Codegen package is. Default is ../../node_modules/@react-native/codegen
22+
// codegenDir = file("../../node_modules/@react-native/codegen")
23+
// The cli.js file which is the React Native CLI entrypoint. Default is ../../node_modules/react-native/cli.js
24+
// cliFile = file("../../node_modules/react-native/cli.js")
25+
2426
/* Variants */
2527
// The list of variants to that are debuggable. For those we're going to
2628
// skip the bundling of the JS bundle and the assets. By default is just 'debug'.
@@ -51,6 +53,8 @@ react {
5153
//
5254
// The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map"
5355
// hermesFlags = ["-O", "-output-source-map"]
56+
57+
/* Autolinking */
5458
autolinkLibrariesWithApp()
5559
}
5660

@@ -122,7 +126,6 @@ android {
122126
dependencies {
123127
// The version of react-native is set by the React Native Gradle Plugin
124128
implementation("com.facebook.react:react-android")
125-
implementation("com.facebook.react:flipper-integration:0.73.9")
126129

127130
implementation project(':react-native-navigation')
128131
implementation 'com.facebook.fresco:fresco:2.5.0'
@@ -135,4 +138,3 @@ dependencies {
135138
}
136139
}
137140

138-
// apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)

android/app/src/main/AndroidManifest.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
android:icon="@mipmap/ic_launcher"
99
android:roundIcon="@mipmap/ic_launcher_round"
1010
android:allowBackup="false"
11-
android:theme="@style/AppTheme">
11+
android:theme="@style/AppTheme"
12+
android:supportsRtl="true">
1213
<activity
1314
android:name=".MainActivity"
1415
android:label="@string/app_name"

android/app/src/main/java/com/rnuilib/MainApplication.kt

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import com.facebook.react.ReactPackage
99
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
1010
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
1111
import com.facebook.react.defaults.DefaultReactNativeHost
12-
import com.facebook.react.flipper.ReactNativeFlipper
12+
import com.facebook.react.soloader.OpenSourceMergedSoMapping
1313
import com.facebook.soloader.SoLoader
1414
import com.reactnativenavigation.NavigationApplication
1515
import com.wix.reactnativeuilib.UiLibPackageList;
@@ -35,15 +35,6 @@ class MainApplication : NavigationApplication() {
3535
}
3636

3737
override val reactHost: ReactHost
38-
get() = getDefaultReactHost(this.applicationContext, reactNativeHost)
39-
40-
override fun onCreate() {
41-
super.onCreate()
42-
SoLoader.init(this, false)
43-
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
44-
// If you opted-in for the New Architecture, we load the native entry point for this app.
45-
load()
46-
}
47-
ReactNativeFlipper.initializeFlipper(this, reactNativeHost.reactInstanceManager)
48-
}
38+
get() = getDefaultReactHost(applicationContext, reactNativeHost)
39+
4940
}

android/app/src/main/java/com/rnuilib/MainApplicationReactNativeHost.java

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,9 @@
22
import android.app.Application;
33
import androidx.annotation.NonNull;
44
import com.facebook.react.PackageList;
5-
import com.facebook.react.ReactInstanceManager;
65
import com.facebook.react.ReactNativeHost;
76
import com.facebook.react.ReactPackage;
87
import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
9-
import com.facebook.react.bridge.JSIModulePackage;
10-
import com.facebook.react.bridge.JSIModuleProvider;
11-
import com.facebook.react.bridge.JSIModuleSpec;
12-
import com.facebook.react.bridge.JSIModuleType;
13-
import com.facebook.react.bridge.JavaScriptContextHolder;
14-
import com.facebook.react.bridge.ReactApplicationContext;
15-
import com.facebook.react.bridge.UIManager;
16-
import com.facebook.react.fabric.ComponentFactory;
17-
import com.facebook.react.fabric.CoreComponentsRegistry;
18-
import com.facebook.react.fabric.EmptyReactNativeConfig;
19-
import com.facebook.react.fabric.FabricJSIModuleProvider;
20-
import com.facebook.react.uimanager.ViewManagerRegistry;
21-
import com.rnuilib.BuildConfig;
22-
import java.util.ArrayList;
238
import java.util.List;
249
/**
2510
* A {@link ReactNativeHost} that helps you load everything needed for the New Architecture, both
@@ -59,43 +44,4 @@ protected String getJSMainModuleName() {
5944
// for the new architecture and to use TurboModules correctly.
6045
return new MainApplicationTurboModuleManagerDelegate.Builder();
6146
}
62-
@Override
63-
protected JSIModulePackage getJSIModulePackage() {
64-
return new JSIModulePackage() {
65-
@Override
66-
public List<JSIModuleSpec> getJSIModules(
67-
final ReactApplicationContext reactApplicationContext,
68-
final JavaScriptContextHolder jsContext) {
69-
final List<JSIModuleSpec> specs = new ArrayList<>();
70-
// Here we provide a new JSIModuleSpec that will be responsible of providing the
71-
// custom Fabric Components.
72-
specs.add(
73-
new JSIModuleSpec() {
74-
@Override
75-
public JSIModuleType getJSIModuleType() {
76-
return JSIModuleType.UIManager;
77-
}
78-
@Override
79-
public JSIModuleProvider<UIManager> getJSIModuleProvider() {
80-
final ComponentFactory componentFactory = new ComponentFactory();
81-
CoreComponentsRegistry.register(componentFactory);
82-
// Here we register a Components Registry.
83-
// The one that is generated with the template contains no components
84-
// and just provides you the one from React Native core.
85-
MainComponentsRegistry.register(componentFactory);
86-
final ReactInstanceManager reactInstanceManager = getReactInstanceManager();
87-
ViewManagerRegistry viewManagerRegistry =
88-
new ViewManagerRegistry(
89-
reactInstanceManager.getOrCreateViewManagers(reactApplicationContext));
90-
return new FabricJSIModuleProvider(
91-
reactApplicationContext,
92-
componentFactory,
93-
new EmptyReactNativeConfig(),
94-
viewManagerRegistry);
95-
}
96-
});
97-
return specs;
98-
}
99-
};
100-
}
10147
}

android/app/src/main/res/drawable/rn_edit_text_material.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
android:insetLeft="@dimen/abc_edit_text_inset_horizontal_material"
1515
android:insetRight="@dimen/abc_edit_text_inset_horizontal_material"
1616
android:insetTop="@dimen/abc_edit_text_inset_top_material"
17-
android:insetBottom="@dimen/abc_edit_text_inset_bottom_material">
17+
android:insetBottom="@dimen/abc_edit_text_inset_bottom_material"
18+
>
1819
<selector>
1920
<!--
2021
This file is a copy of abc_edit_text_material (https://bit.ly/3k8fX7I).

0 commit comments

Comments
 (0)