@@ -9,108 +9,161 @@ const {defineConfig} = require('@yarnpkg/types');
9
9
* @typedef {import('@yarnpkg/types').Yarn.Constraints.Dependency } Dependency
10
10
*/
11
11
12
+ // Helpers
13
+
14
+ // These packages in tools/ were private upstream in React Native and don't follow the same versioning as the public packages
15
+ const PACKAGES_TO_IGNORE = [ '@react-native/eslint' , 'public-api' ] ;
16
+
12
17
/**
13
- * Enforce that react-native-macos declares a peer dependency on react-native on release branches,
14
- * except on the main branch, where there is no published version of React Native to align to.
18
+ * Get the React Native macOS workspace
15
19
* @param {Context } context
20
+ * @returns {Workspace | null } Workspace
16
21
*/
17
- function expectReactNativePeerDependency ( { Yarn} ) {
22
+ const getReactNativeMacOSWorkspace = ( { Yarn} ) => {
18
23
const rnmWorkspace = Yarn . workspace ( { ident : 'react-native-macos' } ) ;
19
24
if ( ! rnmWorkspace ) {
20
25
// Report error on root workspace since react-native-macos doesn't exist
21
26
Yarn . workspace ( ) . error ( 'react-native-macos workspace must exist in the monorepo' ) ;
22
- return ;
23
27
}
28
+ return rnmWorkspace ;
29
+ }
24
30
25
- // Check if react-native-macos version is 1000.0.0 - implying we are on the main branch
26
- const isMainBranch = rnmWorkspace . manifest . version === '1000.0.0' ;
27
- if ( ! isMainBranch ) {
28
- const rnPeerDependency = rnmWorkspace . pkg . peerDependencies . get ( 'react-native' ) ;
29
- if ( ! rnPeerDependency ) {
30
- rnmWorkspace . error ( 'react-native-macos must declare a peer dependency on react-native on release branches' ) ;
31
- }
31
+ /**
32
+ * Get the peer dependency on react-native declared by react-native-macos
33
+ * @param {Context } context
34
+ * @returns {string | undefined } Peer dependency version
35
+ */
36
+ const getReactNativePeerDependency = ( { Yarn} ) => {
37
+ const rnmWorkspace = getReactNativeMacOSWorkspace ( { Yarn} ) ;
38
+
39
+ const rnPeerDependency = rnmWorkspace ?. pkg . peerDependencies . get ( 'react-native' ) ;
40
+ if ( ! rnPeerDependency ) {
41
+ rnmWorkspace ?. error ( 'react-native-macos must declare a peer dependency on react-native on release branches' ) ;
32
42
}
43
+ return rnPeerDependency ;
33
44
}
34
45
35
46
/**
36
- * Enforce that all @react-native/ scoped packages use the same version
37
- * as the react-native peer dependency declared in react-native-macos.
38
- * On the main branch, enforce that we use workspace:* for @react-native/ packages.
47
+ * // Check if react-native-macos version is 1000.0.0, implying we are on the main branch
48
+ * @param {Context } context
49
+ * @returns {boolean }
50
+ */
51
+ const isMainBranch = ( { Yarn} ) => {
52
+ const rnmWorkspace = getReactNativeMacOSWorkspace ( { Yarn} ) ;
53
+ return rnmWorkspace ?. manifest . version === '1000.0.0' ;
54
+ }
55
+
56
+ // Constraints
57
+
58
+ /**
59
+ * Enforce that all @react-native/ scoped packages are private
60
+ * @param {Context } context
61
+ */
62
+ function enforcePrivateReactNativeScopedPackages ( { Yarn} ) {
63
+ for ( const dependency of Yarn . dependencies ( ) ) {
64
+ if ( dependency . ident . startsWith ( '@react-native/' ) ) {
65
+ Yarn . workspace ( { ident : dependency . ident } ) ?. set ( 'private' , true ) ;
66
+ }
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Enforce that react-native-macos declares a peer dependency on react-native on release branches,
72
+ * and that this version is consistent across all @react-native/ scoped packages.
73
+ * Do not enforce on the main branch, where there is no published version of React Native to align to.
39
74
* @param {Context } context
40
75
*/
41
76
function enforceReactNativeVersionConsistency ( { Yarn} ) {
42
- const rnmWorkspace = Yarn . workspace ( { ident : 'react-native-macos' } ) ;
43
- if ( ! rnmWorkspace ) {
44
- // Report error on root workspace since react-native-macos doesn't exist
45
- Yarn . workspace ( ) . error ( 'react-native-macos workspace must exist in the monorepo' ) ;
46
- return ;
47
- }
77
+ if ( ! isMainBranch ( { Yarn} ) ) {
78
+ const reactNativePeerDependency = getReactNativePeerDependency ( { Yarn} ) ;
48
79
49
- // Check if react-native-macos version is 1000.0.0 - implying we are on the main branch
50
- const isMainBranch = rnmWorkspace . manifest . version === '1000.0.0' ;
51
-
52
- let targetVersion ;
53
- if ( isMainBranch ) {
54
- // On main branch, use workspace:* for @react-native/ packages
55
- targetVersion = 'workspace:*' ;
56
- } else {
57
- const rnPeerDependency = rnmWorkspace . pkg . peerDependencies . get ( 'react-native' ) ;
58
- if ( ! rnPeerDependency ) {
59
- rnmWorkspace . error ( 'react-native-macos must declare a peer dependency on react-native on release branches' ) ;
60
- return ;
80
+ // Enforce this version on all @react -native/ scoped packages
81
+ for ( const workspace of Yarn . workspaces ( ) ) {
82
+ if ( workspace . ident ?. startsWith ( '@react-native/' ) && ! PACKAGES_TO_IGNORE . includes ( workspace . ident ) ) {
83
+ workspace . set ( 'version' , reactNativePeerDependency ) ;
84
+ }
61
85
}
62
- targetVersion = rnPeerDependency ;
63
- } // Enforce this version on all @react -native/ scoped packages across all workspaces
86
+ }
87
+ }
88
+
89
+ /**
90
+ * Enforce that all @react-native/ scoped dependencies use the same version
91
+ * as the react-native peer dependency declared in react-native-macos.
92
+ * Do not enforce on the main branch, where there is no published version of React Native to align to.
93
+ * @param {Context } context
94
+ */
95
+ function enforceReactNativeDependencyConsistency ( { Yarn} ) {
64
96
for ( const dependency of Yarn . dependencies ( ) ) {
65
- if ( dependency . ident . startsWith ( '@react-native/' ) ) {
66
- // Check if the target package is private (not published)
67
- const targetWorkspace = Yarn . workspace ( { ident : dependency . ident } ) ;
68
- const isPrivatePackage = targetWorkspace && targetWorkspace . manifest . private ;
69
-
70
- if ( isPrivatePackage ) {
71
- // Private packages should always use workspace:* since they're not published
72
- dependency . update ( 'workspace:*' ) ;
97
+ if ( dependency . ident . startsWith ( '@react-native/' ) ) {
98
+ if ( ! isMainBranch ( { Yarn} ) ) {
99
+ const reactNativeVersion = getReactNativePeerDependency ( { Yarn} ) ;
100
+
101
+ const isRNM = dependency . workspace . ident === 'react-native-macos' ;
102
+ const isRNMForkedPackage = dependency . workspace . ident ?. startsWith ( '@react-native-macos/' ) ;
103
+
104
+ if ( isRNM || isRNMForkedPackage ) {
105
+ // Don't use `workspace:*` for packages we publish until nx release with Yarn 4 supports it.
106
+ dependency . update ( reactNativeVersion ) ;
107
+ } else {
108
+ dependency . update ( 'workspace:*' ) ;
109
+ }
73
110
} else {
74
- dependency . update ( targetVersion ) ;
111
+ dependency . update ( 'workspace:*' ) ;
75
112
}
76
113
}
77
114
}
78
115
}
79
116
80
117
/**
81
- * Enforce that all @react-native-macos/ scoped packages use the same version
82
- * as react-native-macos, but only for non-private packages.
118
+ * Enforce that all public @react-native-macos/ scoped packages' versions
119
+ * are consistent with react-native-macos
120
+ * Do not enforce on the main branch, where we do not publish nightlies yet.
83
121
* @param {Context } context
84
122
*/
85
123
function enforceReactNativeMacosVersionConsistency ( { Yarn} ) {
86
- const rnmWorkspace = Yarn . workspace ( { ident : 'react-native-macos' } ) ;
87
- if ( ! rnmWorkspace ) {
88
- // Report error on root workspace since react-native-macos doesn't exist
89
- Yarn . workspace ( ) . error ( 'react-native-macos workspace must exist in the monorepo' ) ;
90
- return ;
91
- }
124
+ if ( ! isMainBranch ( { Yarn} ) ) {
125
+ const rnmWorkspace = getReactNativeMacOSWorkspace ( { Yarn} ) ;
126
+ const rnmVersion = rnmWorkspace ?. manifest . version ;
92
127
93
- const targetVersion = rnmWorkspace . manifest . version ;
94
- if ( ! targetVersion ) {
95
- rnmWorkspace . error ( 'react-native-macos must have a version' ) ;
96
- return ;
97
- }
128
+ // Enforce this version on all non-private @react-native-macos/ scoped packages
129
+ for ( const workspace of Yarn . workspaces ( ) ) {
130
+ const isReactNativeMacosScoped = workspace . ident && workspace . ident . startsWith ( '@react-native-macos/' ) ;
131
+ const isPrivate = workspace . manifest . private ;
132
+
133
+ if ( isReactNativeMacosScoped && ! isPrivate ) {
134
+ workspace . set ( 'version' , rnmVersion ) ;
135
+ }
136
+ }
137
+ }
138
+ }
98
139
99
- // Enforce this version on all non-private @react-native-macos/ scoped packages
100
- for ( const workspace of Yarn . workspaces ( ) ) {
101
- const isReactNativeMacosScoped = workspace . ident && workspace . ident . startsWith ( '@react-native-macos/' ) ;
102
- const isPrivate = workspace . manifest . private ;
103
-
104
- if ( isReactNativeMacosScoped && ! isPrivate ) {
105
- workspace . set ( 'version' , targetVersion ) ;
140
+ /**
141
+ * Enforce that all @react-native-macos/ scoped dependencies use the same version
142
+ * as the react-native-macos
143
+ * Do not enforce on the main branch, where there is no published version of React Native to align to.
144
+ * @param {Context } context
145
+ */
146
+ function enforceReactNativeMacOSDependencyConsistency ( { Yarn} ) {
147
+ const rnmWorkspace = getReactNativeMacOSWorkspace ( { Yarn} ) ;
148
+ const rnmVersion = rnmWorkspace ?. manifest . version ;
149
+
150
+ for ( const dependency of Yarn . dependencies ( ) ) {
151
+ if ( dependency . ident . startsWith ( '@react-native-macos/' ) ) {
152
+ if ( ! isMainBranch ( { Yarn} ) ) {
153
+ dependency . update ( rnmVersion ) ;
154
+ } else {
155
+ dependency . update ( 'workspace:*' ) ;
156
+ }
106
157
}
107
158
}
108
159
}
109
160
110
161
module . exports = defineConfig ( {
111
162
constraints : async ctx => {
112
- expectReactNativePeerDependency ( ctx ) ;
163
+ enforcePrivateReactNativeScopedPackages ( ctx ) ;
113
164
enforceReactNativeVersionConsistency ( ctx ) ;
165
+ enforceReactNativeDependencyConsistency ( ctx ) ;
114
166
enforceReactNativeMacosVersionConsistency ( ctx ) ;
167
+ enforceReactNativeMacOSDependencyConsistency ( ctx ) ;
115
168
} ,
116
169
} ) ;
0 commit comments