@effected/github-actions 0.20.0 → 0.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/PackageManagerInstaller.js +24 -22
- package/index.d.ts +4 -2
- package/internal/shim.js +30 -0
- package/package.json +5 -5
|
@@ -4,6 +4,7 @@ import { digestFileHex } from "./internal/digest.js";
|
|
|
4
4
|
import { isWindowsRunner } from "./internal/runner.js";
|
|
5
5
|
import { typeAt } from "./internal/fsProbe.js";
|
|
6
6
|
import { PNPM_EXE_PREFIX, detectMusl, isNodeScript, pnpmExeTarget, strongestSri } from "./internal/pnpmExe.js";
|
|
7
|
+
import { cmdShim, gitBashShim, posixShim } from "./internal/shim.js";
|
|
7
8
|
import { ToolInstaller } from "./ToolInstaller.js";
|
|
8
9
|
import { Context, Effect, FileSystem, Layer, Option, Path, Schema } from "effect";
|
|
9
10
|
import { ChildProcess, ChildProcessSpawner } from "effect/process";
|
|
@@ -100,8 +101,10 @@ var AmbientPackageManager = class extends Schema.Class("AmbientPackageManager")(
|
|
|
100
101
|
* `binDir` is the directory a consumer hands to `ActionOutputs.addPath` to
|
|
101
102
|
* make the manager invokable by name in subsequent workflow steps. For the
|
|
102
103
|
* npm-registry managers it is the entry's `.bin` directory of executable
|
|
103
|
-
* shims this installer writes (`#!/bin/sh` exec wrappers
|
|
104
|
-
*
|
|
104
|
+
* shims this installer writes (`#!/bin/sh` exec wrappers; on Windows a
|
|
105
|
+
* `.cmd` wrapper plus an extensionless Git Bash sibling per bin, because
|
|
106
|
+
* Git Bash does not apply `PATHEXT` and never resolves the `.cmd` by the
|
|
107
|
+
* bare name); for bun it is the entry directory itself, because the cached
|
|
105
108
|
* `bun` binary is directly executable and a shim would add nothing but a
|
|
106
109
|
* fork. `bins` still maps each published bin name to the underlying entry —
|
|
107
110
|
* a Node script to run with `node` for npm, yarn and pnpm 11 and earlier; an
|
|
@@ -150,17 +153,6 @@ var CachedPackageManager = class extends Schema.Class("CachedPackageManager")({
|
|
|
150
153
|
const InstalledPackageManager = Schema.Union([AmbientPackageManager, CachedPackageManager]);
|
|
151
154
|
/** The shim directory name inside a cached npm-registry-manager entry. */
|
|
152
155
|
const SHIM_DIR = ".bin";
|
|
153
|
-
/**
|
|
154
|
-
* The POSIX shim body: an `exec` wrapper so the shim's process *becomes* the
|
|
155
|
-
* target, and `"$@"` so arguments survive quoting intact. A Node script
|
|
156
|
-
* (`.js`/`.mjs`/`.cjs`) runs under `node`; anything else — pnpm 12's native
|
|
157
|
-
* binary, its `#!/bin/sh` alias scripts — is exec'd directly, because handing
|
|
158
|
-
* a shell script or a Mach-O to node is exactly the "Invalid or unexpected
|
|
159
|
-
* token" failure this rule exists to prevent.
|
|
160
|
-
*/
|
|
161
|
-
const posixShim = (target) => isNodeScript(target) ? `#!/bin/sh\nexec node "${target}" "$@"\n` : `#!/bin/sh\nexec "${target}" "$@"\n`;
|
|
162
|
-
/** The Windows shim body, CRLF-terminated as cmd expects; same node-vs-direct rule. */
|
|
163
|
-
const cmdShim = (target) => isNodeScript(target) ? `@echo off\r\nnode "${target}" %*\r\n` : `@echo off\r\n"${target}" %*\r\n`;
|
|
164
156
|
/** The bin names pnpm's wrapper publishes, every one of which becomes the native binary on Windows. */
|
|
165
157
|
const PNPM_NATIVE_BIN_NAMES = [
|
|
166
158
|
"pnpm",
|
|
@@ -229,8 +221,16 @@ const make = Effect.gen(function* () {
|
|
|
229
221
|
const windows = yield* isWindowsRunner(env);
|
|
230
222
|
const musl = detectMusl();
|
|
231
223
|
const bunBinaryName = windows ? "bun.exe" : "bun";
|
|
232
|
-
|
|
233
|
-
|
|
224
|
+
/**
|
|
225
|
+
* The shim files one bin gets, as file-name/body pairs: the extensionless
|
|
226
|
+
* `#!/bin/sh` exec wrapper on POSIX; on Windows the `.cmd` wrapper for
|
|
227
|
+
* `cmd.exe` and PowerShell PLUS the extensionless Git Bash sibling — Git
|
|
228
|
+
* Bash does not apply `PATHEXT`, so a bare name never resolves to the
|
|
229
|
+
* `.cmd`. Both flavours derive from the same target, so every distinction
|
|
230
|
+
* the `.cmd` applies (pnpm 12's native binary vs its aliases, node-vs-
|
|
231
|
+
* direct dispatch) the sibling applies identically.
|
|
232
|
+
*/
|
|
233
|
+
const shimFiles = (name, target) => windows ? [[`${name}.cmd`, cmdShim(target)], [name, gitBashShim(target)]] : [[name, posixShim(target)]];
|
|
234
234
|
const errorFor = (pin) => (fields) => new PackageManagerInstallerError({
|
|
235
235
|
name: pin.name,
|
|
236
236
|
version: pin.version.toString(),
|
|
@@ -363,8 +363,9 @@ const make = Effect.gen(function* () {
|
|
|
363
363
|
})), Effect.orElseSucceed(() => false));
|
|
364
364
|
const rootBins = (bins, directory) => Object.fromEntries(Object.entries(bins).map(([name, relative]) => [name, path.join(directory, relative)]));
|
|
365
365
|
/**
|
|
366
|
-
* Write
|
|
367
|
-
*
|
|
366
|
+
* Write the shim files of every bin into `<into>/.bin`, each naming
|
|
367
|
+
* `<finalDirectory>/<relative>` — the POSIX exec wrapper, or on Windows
|
|
368
|
+
* BOTH the `.cmd` wrapper and its extensionless Git Bash sibling.
|
|
368
369
|
*
|
|
369
370
|
* @remarks
|
|
370
371
|
* `into` and `finalDirectory` are DIFFERENT on the install path on purpose:
|
|
@@ -372,8 +373,9 @@ const make = Effect.gen(function* () {
|
|
|
372
373
|
* ToolInstaller renames into place (the cache only ever contains complete
|
|
373
374
|
* entries), while their contents must name the *final* cache path the entry
|
|
374
375
|
* is about to land at. On the cache-hit regeneration path the two coincide.
|
|
375
|
-
* When `skipExisting` is set, a shim already present is left untouched
|
|
376
|
-
* regeneration path must not rewrite
|
|
376
|
+
* When `skipExisting` is set, a shim file already present is left untouched,
|
|
377
|
+
* file by file — the regeneration path must not rewrite what another writer
|
|
378
|
+
* owns, but it does add a sibling a previous version never wrote.
|
|
377
379
|
*/
|
|
378
380
|
const writeShims = (pin, into, finalDirectory, bins, options) => Effect.gen(function* () {
|
|
379
381
|
const shimDir = path.join(into, SHIM_DIR);
|
|
@@ -383,12 +385,12 @@ const make = Effect.gen(function* () {
|
|
|
383
385
|
cause
|
|
384
386
|
});
|
|
385
387
|
yield* fs.makeDirectory(shimDir, { recursive: true }).pipe(Effect.mapError(cacheError(shimDir)));
|
|
386
|
-
for (const [name, relative] of Object.entries(bins)) {
|
|
387
|
-
const shim = path.join(shimDir,
|
|
388
|
+
for (const [name, relative] of Object.entries(bins)) for (const [file, body] of shimFiles(name, path.join(finalDirectory, relative))) {
|
|
389
|
+
const shim = path.join(shimDir, file);
|
|
388
390
|
if (options.skipExisting) {
|
|
389
391
|
if ((yield* typeAt(fs, shim)) === "File") continue;
|
|
390
392
|
}
|
|
391
|
-
yield* fs.writeFileString(shim,
|
|
393
|
+
yield* fs.writeFileString(shim, body).pipe(Effect.mapError(cacheError(shim)));
|
|
392
394
|
if (!windows) yield* fs.chmod(shim, 493).pipe(Effect.mapError(cacheError(shim)));
|
|
393
395
|
}
|
|
394
396
|
});
|
package/index.d.ts
CHANGED
|
@@ -4838,8 +4838,10 @@ declare const CachedPackageManager_base: Schema.Class<CachedPackageManager, Sche
|
|
|
4838
4838
|
* `binDir` is the directory a consumer hands to `ActionOutputs.addPath` to
|
|
4839
4839
|
* make the manager invokable by name in subsequent workflow steps. For the
|
|
4840
4840
|
* npm-registry managers it is the entry's `.bin` directory of executable
|
|
4841
|
-
* shims this installer writes (`#!/bin/sh` exec wrappers
|
|
4842
|
-
*
|
|
4841
|
+
* shims this installer writes (`#!/bin/sh` exec wrappers; on Windows a
|
|
4842
|
+
* `.cmd` wrapper plus an extensionless Git Bash sibling per bin, because
|
|
4843
|
+
* Git Bash does not apply `PATHEXT` and never resolves the `.cmd` by the
|
|
4844
|
+
* bare name); for bun it is the entry directory itself, because the cached
|
|
4843
4845
|
* `bun` binary is directly executable and a shim would add nothing but a
|
|
4844
4846
|
* fork. `bins` still maps each published bin name to the underlying entry —
|
|
4845
4847
|
* a Node script to run with `node` for npm, yarn and pnpm 11 and earlier; an
|
package/internal/shim.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { isNodeScript } from "./pnpmExe.js";
|
|
2
|
+
|
|
3
|
+
//#region src/internal/shim.ts
|
|
4
|
+
/**
|
|
5
|
+
* The POSIX shim body: an `exec` wrapper so the shim's process *becomes* the
|
|
6
|
+
* target, and `"$@"` so arguments survive quoting intact. A Node script
|
|
7
|
+
* (`.js`/`.mjs`/`.cjs`) runs under `node`; anything else — pnpm 12's native
|
|
8
|
+
* binary, its `#!/bin/sh` alias scripts — is exec'd directly, because handing
|
|
9
|
+
* a shell script or a Mach-O to node is exactly the "Invalid or unexpected
|
|
10
|
+
* token" failure this rule exists to prevent.
|
|
11
|
+
*/
|
|
12
|
+
const posixShim = (target) => isNodeScript(target) ? `#!/bin/sh\nexec node "${target}" "$@"\n` : `#!/bin/sh\nexec "${target}" "$@"\n`;
|
|
13
|
+
/** The Windows shim body, CRLF-terminated as cmd expects; same node-vs-direct rule. */
|
|
14
|
+
const cmdShim = (target) => isNodeScript(target) ? `@echo off\r\nnode "${target}" %*\r\n` : `@echo off\r\n"${target}" %*\r\n`;
|
|
15
|
+
/**
|
|
16
|
+
* The Git Bash shim body written beside every Windows `.cmd` shim: the POSIX
|
|
17
|
+
* wrapper's own shape — same shebang, same `exec`, same `"$@"`, same
|
|
18
|
+
* node-vs-direct rule — with the target rendered in forward slashes. Inside
|
|
19
|
+
* double quotes `/bin/sh` consumes a backslash only before `$`, a backtick,
|
|
20
|
+
* `"`, another `\` or a newline, and a trailing backslash would escape the
|
|
21
|
+
* closing quote — enough to mangle a verbatim Windows path (a doubled UNC
|
|
22
|
+
* lead, a segment before `$`), while Git Bash resolves `C:/…` paths as-is.
|
|
23
|
+
* Git Bash does not apply `PATHEXT`, so a bare name never finds the `.cmd`
|
|
24
|
+
* twin on its own; npm's global installs write the same extensionless sibling
|
|
25
|
+
* for the same reason.
|
|
26
|
+
*/
|
|
27
|
+
const gitBashShim = (target) => posixShim(target.replaceAll("\\", "/"));
|
|
28
|
+
|
|
29
|
+
//#endregion
|
|
30
|
+
export { cmdShim, gitBashShim, posixShim };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effected/github-actions",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "The GitHub Actions runtime: env, inputs, outputs, state, logging, cache, artifacts, blob storage, OIDC and the token bridge.",
|
|
6
6
|
"keywords": [
|
|
@@ -39,12 +39,12 @@
|
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@azure/storage-blob": "^12.33.0",
|
|
42
|
-
"@effected/github": "^0.15.
|
|
43
|
-
"@effected/github-commands": "^0.
|
|
42
|
+
"@effected/github": "^0.15.1",
|
|
43
|
+
"@effected/github-commands": "^0.2.0",
|
|
44
44
|
"@effected/glob": "^0.10.0",
|
|
45
|
-
"@effected/markdown": "^0.15.
|
|
45
|
+
"@effected/markdown": "^0.15.1",
|
|
46
46
|
"@effected/npm": "^0.20.0",
|
|
47
|
-
"@effected/sbom": "^0.10.
|
|
47
|
+
"@effected/sbom": "^0.10.1",
|
|
48
48
|
"@effected/semver": "^0.11.0",
|
|
49
49
|
"@effected/templates": "^0.10.0",
|
|
50
50
|
"@effected/walker": "^0.15.0"
|