@@ -32,6 +32,8 @@ export async function action(): Promise<void> {
32
32
yellow : ( msg : string ) => console . log ( chalk . yellow ( msg ) )
33
33
}
34
34
35
+ const actionType = isESM ( ) ? 'esm' : 'cjs'
36
+
35
37
// Output the configuration
36
38
printTitle ( CoreMeta . colors . cyan , 'Configuration' )
37
39
console . log ( )
@@ -134,11 +136,23 @@ export async function action(): Promise<void> {
134
136
'No package.json file found in the action directory or any parent directories.'
135
137
)
136
138
137
- // If the package manager is `npm` or `pnpm`, then a `node_modules` directory
138
- // should exist somewhere in the project. If the package manager is `yarn`,
139
- // then we need to first check for `node_modules` (for non-PnP versions), or
140
- // we can try unplugging the dependencies from the yarn cache.
141
- if ( process . env . NODE_PACKAGE_MANAGER === 'npm' ) {
139
+ // If the package manager is `npm`, we can assume there is a `node_modules`
140
+ // directory somewhere in the project.
141
+ //
142
+ // Actions that use `pnpm` will also have a `node_modules` directory, however
143
+ // in testing it seems that the `node_modules/@actions/<pkg>` dependency can
144
+ // only be properly stubbed for CJS actions. For ESM actions, this should
145
+ // instead point to the pnpm cache.
146
+ //
147
+ // If the package manager is `yarn`, then we need to first check for
148
+ // `node_modules` (for non-PnP versions), or we can try unplugging the
149
+ // dependencies from the yarn cache.
150
+ if (
151
+ process . env . NODE_PACKAGE_MANAGER === 'npm' ||
152
+ ( process . env . NODE_PACKAGE_MANAGER === 'pnpm' && actionType === 'cjs' ) ||
153
+ ( process . env . NODE_PACKAGE_MANAGER === 'yarn' &&
154
+ fs . existsSync ( path . join ( EnvMeta . actionPath , 'node_modules' ) ) )
155
+ ) {
142
156
/**
143
157
* Get the path in the npm cache for each package.
144
158
* `npm ls <package> --json --long`
@@ -179,7 +193,10 @@ export async function action(): Promise<void> {
179
193
Object . keys ( stubs ) . forEach ( key => {
180
194
stubs [ key as keyof typeof stubs ] . base = npmList . dependencies ?. [ key ] ?. path
181
195
} )
182
- } else if ( process . env . NODE_PACKAGE_MANAGER === 'pnpm' ) {
196
+ } else if (
197
+ process . env . NODE_PACKAGE_MANAGER === 'pnpm' &&
198
+ actionType === 'esm'
199
+ ) {
183
200
/**
184
201
* Get the path in the pnpm cache for each package.
185
202
* `pnpm list <package> --json`
@@ -217,87 +234,38 @@ export async function action(): Promise<void> {
217
234
pnpmList [ 0 ] . dependencies ?. [ key ] ?. path
218
235
} )
219
236
} else if ( process . env . NODE_PACKAGE_MANAGER === 'yarn' ) {
220
- // Depending on the version and configuration for yarn, a `node_modules`
221
- // directory may or may not exist. Also, the CLI commands are different
222
- // across versions for getting the path to a dependency.
223
-
224
- // First check if a `node_modules` directory exists in the target action
225
- // path (or a parent path).
226
- if ( fs . existsSync ( path . join ( EnvMeta . actionPath , 'node_modules' ) ) ) {
227
- // Get the path in the npm cache for each package. This will work if there
228
- // is a `node_modules` directory (`yarn list` does not provide the path).
229
- // `npm ls <package> --json --long`
230
-
231
- /**
232
- * Example Output
233
- *
234
- * {
235
- * "path": "<workspace>/typescript-action",
236
- * "_dependencies": {
237
- * "@actions /core": "^1.11.1",
238
- * "@actions/github": "^6.0.0"
239
- * },
240
- * "dependencies": {
241
- * "@actions /core": {
242
- * "path": "<workspace>/typescript-action/node_modules/@actions /core",
243
- * },
244
- * "@actions/github": {
245
- * "path": "<workspace>/typescript-action/node_modules/@actions /github",
246
- * }
247
- * }
248
- * }
249
- */
250
- const npmList = JSON . parse (
251
- execSync (
252
- `npm ls ${ Object . keys ( stubs ) . join ( ' ' ) } --json --long`
253
- ) . toString ( )
254
- ) as {
255
- path : string
256
- dependencies ?: {
257
- [ key : string ] : { path : string }
258
- }
259
- }
260
-
261
- if ( Object . keys ( npmList . dependencies ?? { } ) . length === 0 )
262
- throw new Error ( 'Something went wrong with npm list' )
263
-
264
- Object . keys ( stubs ) . forEach ( key => {
265
- stubs [ key as keyof typeof stubs ] . base =
266
- npmList . dependencies ?. [ key ] ?. path
267
- } )
268
- } else {
269
- // At this point, it's likely yarn is running in PnP mode.
270
- printTitle ( CoreMeta . colors . magenta , 'Yarn: Unplugging Dependencies' )
271
- console . log ( )
272
-
273
- // For now, we need to `unplug` each dependency to get the path to the
274
- // package.
275
- // TODO: Is there a better way to do this without unplugging?
276
- needsReplug = true
277
-
278
- for ( const key of Object . keys ( stubs ) ) {
279
- // This may fail if the package is not a dependency for this action.
280
- try {
281
- const output = execSync ( `yarn unplug ${ key } ` ) . toString ( )
282
- console . log ( `Unplugged: ${ key } ` )
283
-
284
- // Next, get the path to the package. Unfortunately using the `--json`
285
- // flag with `yarn unplug` does not output the target path, so we need
286
- // to parse it from the plaintext output.
287
- const packagePath = output . match (
288
- / W i l l u n p a c k .* t o (?< packagePath > .* ) /
289
- ) ?. groups ?. packagePath
290
-
291
- if ( ! packagePath ) throw new Error ( `Could not unplug ${ key } ` )
292
-
293
- stubs [ key as keyof typeof stubs ] . base = path . join (
294
- packagePath ,
295
- 'node_modules' ,
296
- key
297
- )
298
- } catch {
299
- // This is fine...
300
- }
237
+ // Note: The CLI commands are different across yarn versions for getting the
238
+ // path to a dependency.
239
+
240
+ // At this point, it's likely yarn is running in PnP mode.
241
+ printTitle ( CoreMeta . colors . magenta , 'Yarn: Unplugging Dependencies' )
242
+ console . log ( )
243
+
244
+ // For now, we need to `unplug` each dependency to get the path to the
245
+ // package.
246
+ needsReplug = true
247
+
248
+ for ( const key of Object . keys ( stubs ) ) {
249
+ // This may fail if the package is not a dependency for this action.
250
+ try {
251
+ const output = execSync ( `yarn unplug ${ key } ` ) . toString ( )
252
+ console . log ( `Unplugged: ${ key } ` )
253
+
254
+ // Next, get the path to the package. Unfortunately using the `--json`
255
+ // flag with `yarn unplug` does not output the target path, so we need
256
+ // to parse it from the plaintext output.
257
+ const packagePath = output . match ( / W i l l u n p a c k .* t o (?< packagePath > .* ) / )
258
+ ?. groups ?. packagePath
259
+
260
+ if ( ! packagePath ) throw new Error ( `Could not unplug ${ key } ` )
261
+
262
+ stubs [ key as keyof typeof stubs ] . base = path . join (
263
+ packagePath ,
264
+ 'node_modules' ,
265
+ key
266
+ )
267
+ } catch {
268
+ // This is fine...
301
269
}
302
270
}
303
271
}
@@ -317,7 +285,7 @@ export async function action(): Promise<void> {
317
285
// Stub the `@actions/toolkit` libraries and run the action. Quibble and
318
286
// local-action require a different approach depending on if the called action
319
287
// is written in ESM.
320
- if ( isESM ( ) ) {
288
+ if ( actionType === 'esm' ) {
321
289
await quibble . esm (
322
290
path . resolve (
323
291
stubs [ '@actions/github' ] . base ?? '' ,
0 commit comments