Skip to content

Commit dd9000a

Browse files
authored
Make src-cli installable via npm. (#760)
* Make src-cli installable via npm. Fixes #759. Previously, the recommended way to install src-cli on Linux was to download a static binary via `curl`. This PR makes it possible to install src-cli via `npm install -g @sourcegraph/src`. The new npm distribution will be particuarly helpful for users of our new scip-typescript and scip-python indexers that are also distributed via npm. * Make the npm release flow depend on goreleaser
1 parent e6f55b9 commit dd9000a

10 files changed

Lines changed: 232 additions & 5 deletions

File tree

.github/workflows/goreleaser.yml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,15 @@ jobs:
3333
env:
3434
# Use separate access token, because we need a scope:repo token to publish the brew formula.
3535
GITHUB_TOKEN: ${{ secrets.GH_PAT }}
36-
36+
npm:
37+
runs-on: ubuntu-latest
38+
needs: goreleaser
39+
steps:
40+
- name: Checkout
41+
uses: actions/checkout@v3
42+
with:
43+
fetch-depth: 0
44+
- run: npm publish --access public
45+
working-directory: npm-distribution
46+
env:
47+
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}

.vscode/settings.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
{
22
"go.lintTool": "golangci-lint",
33
"shellformat.flag": "-i 2 -ci",
4-
"editor.formatOnSave": true,
4+
"editor.formatOnSave": false,
5+
"[go]": {
6+
"editor.formatOnSave": true
7+
},
58
"go.useLanguageServer": true,
69
"gopls": {
710
"local": "github.com/sourcegraph/src-cli"

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ All notable changes to `src-cli` are documented in this file.
1919

2020
### Removed
2121

22+
## 3.40.3
23+
24+
### Added
25+
26+
- It's now possible to install src-cli via `npm install -g @sourcegraph/src`. [sourcegraph/src-cli#760](https://github.com/sourcegraph/src-cli/pull/760)
27+
2228
## 3.40.2
2329

2430
### Changed

DEVELOPMENT.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,13 @@ We adhere to the [general Sourcegraph principles for testing](https://docs.sourc
5858

5959
1. If this is a non-patch release, update the changelog. Add a new section `## $MAJOR.MINOR` to [`CHANGELOG.md`](https://github.com/sourcegraph/src-cli/blob/main/CHANGELOG.md#unreleased) immediately under `## Unreleased changes`. Add new empty `Added`, `Changed`, `Fixed`, and `Removed` sections under `## Unreleased changes`.
6060
2. Find the latest version (either via the releases tab on GitHub or via git tags) to determine which version you are releasing.
61-
3. `VERSION=9.9.9 ./release.sh` (replace `9.9.9` with the version you are releasing)
62-
4. GitHub will automatically perform the release via the [goreleaser action](https://github.com/sourcegraph/src-cli/actions?query=workflow%3AGoreleaser). Once it has finished, **you need to confirm**:
61+
3. Update the `"version"` field in the file `npm-distribution/package.json` to match the version you are releasing.
62+
4. Open a pull request with the new changelog and updated `npm-distribution/package.json` version. Get the pull request merged before completing the next step.
63+
5. `VERSION=9.9.9 ./release.sh` (replace `9.9.9` with the version you are releasing)
64+
6. GitHub will automatically perform the release via the [goreleaser action](https://github.com/sourcegraph/src-cli/actions?query=workflow%3AGoreleaser). Once it has finished, **you need to confirm**:
6365
1. The [curl commands in the README](README.markdown#installation) fetch the latest version above.
6466
2. The [releases section of the repo sidebar](https://github.com/sourcegraph/src-cli) shows the correct version.
65-
5. Make the necessary updates to the main Sourcegraph repo:
67+
7. Make the necessary updates to the main Sourcegraph repo:
6668
1. Update the `MinimumVersion` constant in the [src-cli package](https://github.com/sourcegraph/sourcegraph/tree/main/internal/src-cli/consts.go).
6769
2. Update the reference documentation by running `go generate ./doc/cli/references`.
6870
3. Commit the changes, and open a PR.

npm-distribution/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules/
2+
src
3+
LICENSE

npm-distribution/install.js

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#!/usr/bin/env node
2+
3+
const fs = require("fs");
4+
const tar = require("tar");
5+
const zlib = require("zlib");
6+
const http = require("http");
7+
const https = require("https");
8+
const packageJSON = require("./package.json");
9+
10+
// Determine the URL of the file.
11+
const platformName = {
12+
darwin: "darwin",
13+
linux: "linux",
14+
win32: "windows",
15+
}[process.platform];
16+
17+
let archName = {
18+
x64: "amd64",
19+
x86: "amd64",
20+
ia32: "amd64",
21+
amd64: "amd64",
22+
arm64: "arm64",
23+
}[process.arch];
24+
25+
if (!platformName || !archName) {
26+
console.error(
27+
`Cannot install src for platform ${process.platform}, architecture ${process.arch}`
28+
);
29+
process.exit(1);
30+
}
31+
32+
const version = packageJSON.version;
33+
const assetURL = `https://github.com/sourcegraph/src-cli/releases/download/${version}/src-cli_${version}_${platformName}_${archName}.tar.gz`;
34+
35+
// Remove previously-downloaded files.
36+
const executableName = process.platform === "win32" ? "src.exe" : "src";
37+
if (fs.existsSync(executableName)) {
38+
fs.unlinkSync(executableName);
39+
}
40+
41+
// Download the compressed file.
42+
console.log(`Downloading ${assetURL}`);
43+
get(assetURL, (response) => {
44+
if (response.statusCode > 299) {
45+
console.error(
46+
[
47+
"Download failed",
48+
"",
49+
`url: ${assetURL}`,
50+
`status: ${response.statusCode}`,
51+
`headers: ${JSON.stringify(response.headers, null, 2)}`,
52+
"",
53+
].join("\n")
54+
);
55+
process.exit(1);
56+
}
57+
response
58+
.pipe(zlib.createGunzip())
59+
.pipe(tar.x({ filter: (x) => x === "src" }))
60+
.addListener("close", () => fs.chmodSync(executableName, "755"));
61+
});
62+
63+
// Follow redirects.
64+
function get(url, callback) {
65+
const requestUrl = new URL(url);
66+
let request = https;
67+
let requestConfig = requestUrl;
68+
const proxyEnv = process.env["HTTPS_PROXY"] || process.env["https_proxy"];
69+
70+
if (proxyEnv) {
71+
const proxyUrl = new URL(proxyEnv);
72+
request = proxyUrl.protocol === "https:" ? https : http;
73+
requestConfig = {
74+
hostname: proxyUrl.hostname,
75+
port: proxyUrl.port,
76+
path: requestUrl.toString(),
77+
headers: {
78+
Host: requestUrl.hostname,
79+
},
80+
};
81+
}
82+
83+
request.get(requestConfig, (response) => {
84+
if (response.statusCode === 301 || response.statusCode === 302) {
85+
get(response.headers.location, callback);
86+
} else {
87+
callback(response);
88+
}
89+
});
90+
}

npm-distribution/package.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "@sourcegraph/src",
3+
"version": "3.40.3",
4+
"description": "Sourcegraph CLI",
5+
"repository": "git@github.com:sourcegraph/src-cli.git",
6+
"author": "Code Intelligence at Sourcegraph",
7+
"license": "Apache-2.0",
8+
"scripts": {
9+
"install": "node install.js",
10+
"prepack": "cp ../LICENSE ."
11+
},
12+
"main": "src.js",
13+
"bin": {
14+
"src": "src.js"
15+
},
16+
"keywords": [
17+
"sourcegraph"
18+
],
19+
"dependencies": {
20+
"tar": "^6.1.11"
21+
},
22+
"devDependencies": {
23+
"@types/tar": "^6.1.1"
24+
},
25+
"private": false
26+
}

npm-distribution/src.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/usr/bin/env node
2+
3+
const path = require('path');
4+
const spawn = require("child_process").spawn;
5+
const executable = process.platform === 'win32' ? 'src.exe' : 'src';
6+
spawn(
7+
path.join(__dirname, executable),
8+
process.argv.slice(2),
9+
{stdio: 'inherit'}
10+
).on('close', process.exit)

npm-distribution/yarn.lock

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2+
# yarn lockfile v1
3+
4+
5+
"@types/minipass@*":
6+
version "3.1.2"
7+
resolved "https://registry.yarnpkg.com/@types/minipass/-/minipass-3.1.2.tgz#e2d7f9df0698aff421dcf145b4fc05b8183b9030"
8+
integrity sha512-foLGjgrJkUjLG/o2t2ymlZGEoBNBa/TfoUZ7oCTkOjP1T43UGBJspovJou/l3ZuHvye2ewR5cZNtp2zyWgILMA==
9+
dependencies:
10+
"@types/node" "*"
11+
12+
"@types/node@*":
13+
version "17.0.36"
14+
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.36.tgz#c0d5f2fe76b47b63e0e0efc3d2049a9970d68794"
15+
integrity sha512-V3orv+ggDsWVHP99K3JlwtH20R7J4IhI1Kksgc+64q5VxgfRkQG8Ws3MFm/FZOKDYGy9feGFlZ70/HpCNe9QaA==
16+
17+
"@types/tar@^6.1.1":
18+
version "6.1.1"
19+
resolved "https://registry.yarnpkg.com/@types/tar/-/tar-6.1.1.tgz#ab341ec1f149d7eb2a4f4ded56ff85f0d4fe7cb5"
20+
integrity sha512-8mto3YZfVpqB1CHMaYz1TUYIQfZFbh/QbEq5Hsn6D0ilCfqRVCdalmc89B7vi3jhl9UYIk+dWDABShNfOkv5HA==
21+
dependencies:
22+
"@types/minipass" "*"
23+
"@types/node" "*"
24+
25+
chownr@^2.0.0:
26+
version "2.0.0"
27+
resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece"
28+
integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==
29+
30+
fs-minipass@^2.0.0:
31+
version "2.1.0"
32+
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb"
33+
integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==
34+
dependencies:
35+
minipass "^3.0.0"
36+
37+
minipass@^3.0.0:
38+
version "3.1.6"
39+
resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.6.tgz#3b8150aa688a711a1521af5e8779c1d3bb4f45ee"
40+
integrity sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==
41+
dependencies:
42+
yallist "^4.0.0"
43+
44+
minizlib@^2.1.1:
45+
version "2.1.2"
46+
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931"
47+
integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==
48+
dependencies:
49+
minipass "^3.0.0"
50+
yallist "^4.0.0"
51+
52+
mkdirp@^1.0.3:
53+
version "1.0.4"
54+
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
55+
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
56+
57+
tar@^6.1.11:
58+
version "6.1.11"
59+
resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621"
60+
integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==
61+
dependencies:
62+
chownr "^2.0.0"
63+
fs-minipass "^2.0.0"
64+
minipass "^3.0.0"
65+
minizlib "^2.1.1"
66+
mkdirp "^1.0.3"
67+
yallist "^4.0.0"
68+
69+
yallist@^4.0.0:
70+
version "4.0.0"
71+
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
72+
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==

release.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ if ! echo "$VERSION" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$'; then
1717
exit 1
1818
fi
1919

20+
echo "Verifying that npm-distribution/package.json has the correct version"
21+
yarn --cwd="$PWD/npm-distribution" version --no-git-tag-version --new-version "$VERSION"
22+
git diff --exit-code
23+
2024
# Create a new tag and push it, this will trigger the goreleaser workflow in .github/workflows/goreleaser.yml
2125
git tag "${VERSION}" -a -m "release v${VERSION}"
2226
# We use `--atomic` so that we push the tag and the commit if the commit was or wasn't pushed before

0 commit comments

Comments
 (0)