@railway/cli 5.30.3 → 5.31.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/bin/railway.js +33 -4
- package/npm-install/postinstall.js +102 -36
- package/package.json +1 -2
package/bin/railway.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { execFileSync } from "child_process";
|
|
3
|
+
import { constants } from "os";
|
|
3
4
|
import path from "path";
|
|
4
5
|
import { exit } from "process";
|
|
5
6
|
import { fileURLToPath } from "url";
|
|
@@ -7,10 +8,38 @@ import { fileURLToPath } from "url";
|
|
|
7
8
|
const __filename = fileURLToPath(import.meta.url);
|
|
8
9
|
const __dirname = path.dirname(__filename);
|
|
9
10
|
const binName = process.platform === "win32" ? "railway.exe" : "railway";
|
|
11
|
+
const binPath = path.resolve(__dirname, binName);
|
|
12
|
+
|
|
10
13
|
try {
|
|
11
|
-
|
|
12
|
-
stdio: "inherit",
|
|
13
|
-
});
|
|
14
|
+
execFileSync(binPath, process.argv.slice(2), { stdio: "inherit" });
|
|
14
15
|
} catch (e) {
|
|
15
|
-
|
|
16
|
+
// The binary is downloaded by npm-install/postinstall.js. If that step was
|
|
17
|
+
// skipped (--ignore-scripts) or failed (unsupported platform, network), the
|
|
18
|
+
// spawn fails with ENOENT — say so instead of exiting 1 with no output.
|
|
19
|
+
if (e.code === "ENOENT") {
|
|
20
|
+
console.error(
|
|
21
|
+
`railway: could not find the CLI binary at ${binPath}\n` +
|
|
22
|
+
`The @railway/cli install step did not complete. Try:\n` +
|
|
23
|
+
` npm install -g @railway/cli --foreground-scripts\n` +
|
|
24
|
+
`or install the CLI directly:\n` +
|
|
25
|
+
` curl -fsSL https://railway.com/install.sh | sh`,
|
|
26
|
+
);
|
|
27
|
+
exit(127);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Propagate the real exit status. Without this every failure collapses to 1,
|
|
31
|
+
// which hides usage errors (clap exits 2), breaks `set -e` callers that
|
|
32
|
+
// inspect the code, and masks crashes as ordinary failures.
|
|
33
|
+
if (typeof e.status === "number") {
|
|
34
|
+
exit(e.status);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Killed by a signal: report it the way a shell does (128 + signal number)
|
|
38
|
+
// so a segfault surfaces as 139 rather than a generic 1.
|
|
39
|
+
if (e.signal) {
|
|
40
|
+
const signum = constants.signals[e.signal];
|
|
41
|
+
exit(signum ? 128 + signum : 1);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
exit(1);
|
|
16
45
|
}
|
|
@@ -1,48 +1,114 @@
|
|
|
1
|
-
import triples from "@napi-rs/triples";
|
|
2
1
|
import { createWriteStream } from "fs";
|
|
3
2
|
import * as fs from "fs/promises";
|
|
4
3
|
import fetch from "node-fetch";
|
|
4
|
+
import path from "path";
|
|
5
5
|
import { pipeline } from "stream/promises";
|
|
6
|
+
import { fileURLToPath } from "url";
|
|
6
7
|
import tar from "tar";
|
|
7
8
|
|
|
8
9
|
import { CONFIG } from "./config.js";
|
|
9
10
|
|
|
11
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
12
|
+
const PACKAGE_ROOT = path.resolve(__dirname, "..");
|
|
13
|
+
|
|
14
|
+
// process.platform/arch -> release target triple.
|
|
15
|
+
//
|
|
16
|
+
// This is deliberately hand-maintained rather than derived from a generic table
|
|
17
|
+
// (we previously used @napi-rs/triples): the generic answer for Linux is always
|
|
18
|
+
// `*-unknown-linux-gnu`, and we do not publish gnu builds for any Linux arch
|
|
19
|
+
// except x86_64. That silently broke `npm i -g @railway/cli` on arm64/arm/ia32
|
|
20
|
+
// Linux with "Failed fetching the binary: Not Found".
|
|
21
|
+
//
|
|
22
|
+
// Every entry below must correspond to an asset produced by
|
|
23
|
+
// .github/workflows/release.yml. Linux uses the statically linked musl builds
|
|
24
|
+
// for the same reason install.sh does: one binary that runs regardless of the
|
|
25
|
+
// host's libc.
|
|
26
|
+
const TARGETS = {
|
|
27
|
+
linux: {
|
|
28
|
+
x64: "x86_64-unknown-linux-musl",
|
|
29
|
+
arm64: "aarch64-unknown-linux-musl",
|
|
30
|
+
ia32: "i686-unknown-linux-musl",
|
|
31
|
+
arm: "arm-unknown-linux-musleabihf",
|
|
32
|
+
},
|
|
33
|
+
darwin: {
|
|
34
|
+
x64: "x86_64-apple-darwin",
|
|
35
|
+
arm64: "aarch64-apple-darwin",
|
|
36
|
+
},
|
|
37
|
+
win32: {
|
|
38
|
+
x64: "x86_64-pc-windows-gnu",
|
|
39
|
+
ia32: "i686-pc-windows-gnu",
|
|
40
|
+
arm64: "aarch64-pc-windows-msvc",
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
function resolveTarget() {
|
|
45
|
+
const { platform, arch } = process;
|
|
46
|
+
const triple = TARGETS[platform]?.[arch];
|
|
47
|
+
|
|
48
|
+
if (!triple) {
|
|
49
|
+
const supported = Object.entries(TARGETS)
|
|
50
|
+
.flatMap(([p, arches]) => Object.keys(arches).map((a) => `${p}-${a}`))
|
|
51
|
+
.join(", ");
|
|
52
|
+
throw new Error(
|
|
53
|
+
`Railway CLI does not ship a prebuilt binary for ${platform}-${arch}.\n` +
|
|
54
|
+
`Supported: ${supported}\n` +
|
|
55
|
+
`Request a build at https://github.com/railwayapp/cli/issues/new, ` +
|
|
56
|
+
`or build from source with \`cargo install railwayapp\`.`,
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return triple;
|
|
61
|
+
}
|
|
62
|
+
|
|
10
63
|
async function install() {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
64
|
+
const packageJson = await fs
|
|
65
|
+
.readFile(path.join(PACKAGE_ROOT, "package.json"), "utf8")
|
|
66
|
+
.then(JSON.parse);
|
|
67
|
+
let version = packageJson.version;
|
|
68
|
+
|
|
69
|
+
if (typeof version !== "string") {
|
|
70
|
+
throw new Error("Missing version in package.json");
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (version[0] === "v") version = version.slice(1);
|
|
74
|
+
|
|
75
|
+
const { name: binName, path: binPath, url } = CONFIG;
|
|
76
|
+
const triple = resolveTarget();
|
|
77
|
+
|
|
78
|
+
const downloadUrl = url
|
|
79
|
+
.replace(/{{triple}}/g, triple)
|
|
80
|
+
.replace(/{{version}}/g, version)
|
|
81
|
+
.replace(/{{bin_name}}/g, binName);
|
|
82
|
+
|
|
83
|
+
console.log(downloadUrl);
|
|
84
|
+
const response = await fetch(downloadUrl);
|
|
85
|
+
if (!response.ok) {
|
|
86
|
+
throw new Error(
|
|
87
|
+
`Failed fetching the binary (${response.status} ${response.statusText}): ${downloadUrl}`,
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const destDir = path.resolve(PACKAGE_ROOT, binPath);
|
|
92
|
+
const tarFile = path.join(PACKAGE_ROOT, "downloaded.tar.gz");
|
|
93
|
+
|
|
94
|
+
await fs.mkdir(destDir, { recursive: true });
|
|
95
|
+
await pipeline(response.body, createWriteStream(tarFile));
|
|
96
|
+
await tar.x({ file: tarFile, cwd: destDir });
|
|
97
|
+
await fs.rm(tarFile);
|
|
98
|
+
|
|
99
|
+
// Fail loudly here rather than leaving a package whose `railway` shim exits
|
|
100
|
+
// with a confusing ENOENT on first use.
|
|
101
|
+
const expected = path.join(destDir, process.platform === "win32" ? "railway.exe" : "railway");
|
|
102
|
+
await fs.access(expected).catch(() => {
|
|
103
|
+
throw new Error(`Archive did not contain the expected binary at ${expected}`);
|
|
104
|
+
});
|
|
39
105
|
}
|
|
40
106
|
|
|
41
107
|
install()
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
108
|
+
.then(async () => {
|
|
109
|
+
process.exit(0);
|
|
110
|
+
})
|
|
111
|
+
.catch(async (err) => {
|
|
112
|
+
console.error(err.message ?? err);
|
|
113
|
+
process.exit(1);
|
|
114
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@railway/cli",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.31.1",
|
|
4
4
|
"description": "Develop and deploy code with zero configuration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Jake Runzer",
|
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
"README.md"
|
|
25
25
|
],
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@napi-rs/triples": "^1.1.0",
|
|
28
27
|
"node-fetch": "^3.1.0",
|
|
29
28
|
"tar": "^6.1.11"
|
|
30
29
|
}
|