@acalcutt/node-pre-gyp-github 1.4.9 → 2.0.1-pre.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/node-pre-gyp-github.js +20 -21
- package/index.js +124 -128
- package/package.json +16 -14
|
@@ -1,26 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import NodePreGypGithub from '../index.js';
|
|
4
|
+
import { program } from "commander";
|
|
5
5
|
|
|
6
6
|
program
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
});
|
|
7
|
+
.command("publish")
|
|
8
|
+
.description("publishes the contents of ./build/stage/{version} to the current version's GitHub release")
|
|
9
|
+
.option("-r, --release", "publish immediately, do not create draft")
|
|
10
|
+
.option("-s, --silent", "turns verbose messages off")
|
|
11
|
+
.action(async (options) => {
|
|
12
|
+
const opts = {
|
|
13
|
+
draft: !options.release,
|
|
14
|
+
verbose: !options.silent,
|
|
15
|
+
};
|
|
16
|
+
try {
|
|
17
|
+
const nodePreGypGithub = new NodePreGypGithub();
|
|
18
|
+
await nodePreGypGithub.publish(opts);
|
|
19
|
+
} catch (err) {
|
|
20
|
+
console.error(`An error occurred whilst publishing:`, err);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
25
24
|
|
|
26
|
-
program.parseAsync(process.argv);
|
|
25
|
+
await program.parseAsync(process.argv);
|
package/index.js
CHANGED
|
@@ -1,153 +1,149 @@
|
|
|
1
|
-
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import { Octokit } from '@octokit/rest';
|
|
2
4
|
|
|
3
|
-
const path = require('path');
|
|
4
|
-
const fs = require('fs');
|
|
5
5
|
const cwd = process.cwd();
|
|
6
6
|
|
|
7
|
-
const {Octokit} = require('@octokit/rest');
|
|
8
|
-
|
|
9
7
|
let verbose;
|
|
10
8
|
|
|
11
9
|
function consoleLog(x) {
|
|
12
|
-
|
|
10
|
+
return (verbose) ? console.log(x) : false;
|
|
13
11
|
}
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
init() {
|
|
21
|
-
const token = process.env.NODE_PRE_GYP_GITHUB_TOKEN;
|
|
22
|
-
if (!token) {
|
|
23
|
-
throw new Error('NODE_PRE_GYP_GITHUB_TOKEN environment variable not found');
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
this.package_json = JSON.parse(fs.readFileSync(path.join(cwd, 'package.json'), 'utf-8'));
|
|
13
|
+
export default class NodePreGypGithub {
|
|
14
|
+
constructor() {
|
|
15
|
+
this.stage_dir = path.join(cwd, 'build', 'stage');
|
|
16
|
+
}
|
|
27
17
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
throw new Error('A correctly formatted GitHub repository.url was not found within package.json');
|
|
34
|
-
}
|
|
18
|
+
init() {
|
|
19
|
+
const token = process.env.NODE_PRE_GYP_GITHUB_TOKEN;
|
|
20
|
+
if (!token) {
|
|
21
|
+
throw new Error('NODE_PRE_GYP_GITHUB_TOKEN environment variable not found');
|
|
22
|
+
}
|
|
35
23
|
|
|
36
|
-
|
|
37
|
-
const [owner, repo] = ownerRepo[2].split('/');
|
|
38
|
-
this.owner = owner;
|
|
39
|
-
this.repo = repo;
|
|
40
|
-
}
|
|
24
|
+
this.package_json = JSON.parse(fs.readFileSync(path.join(cwd, 'package.json'), 'utf-8'));
|
|
41
25
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
26
|
+
if (!this.package_json.repository || !this.package_json.repository.url) {
|
|
27
|
+
throw new Error('Missing repository.url in package.json');
|
|
28
|
+
} else {
|
|
29
|
+
const ownerRepo = this.package_json.repository.url.match(/https?:\/\/([^\/]+)\/(.*)(?=\.git)/i);
|
|
30
|
+
if (!ownerRepo) {
|
|
31
|
+
throw new Error('A correctly formatted GitHub repository.url was not found within package.json');
|
|
32
|
+
}
|
|
49
33
|
|
|
50
|
-
|
|
34
|
+
this.host = 'api.' + ownerRepo[1];
|
|
35
|
+
const [owner, repo] = ownerRepo[2].split('/');
|
|
36
|
+
this.owner = owner;
|
|
37
|
+
this.repo = repo;
|
|
51
38
|
}
|
|
52
39
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
auth: token,
|
|
57
|
-
headers: {
|
|
58
|
-
"user-agent": (this.package_json.name) ? this.package_json.name : "node-pre-gyp-github"
|
|
59
|
-
}
|
|
60
|
-
});
|
|
40
|
+
const hostPrefix = 'https://' + this.host + '/' + this.owner + '/' + this.repo + '/releases/download/';
|
|
41
|
+
if (!this.package_json.binary || typeof this.package_json.binary !== 'object' || typeof this.package_json.binary.host !== 'string') {
|
|
42
|
+
throw new Error('Missing binary.host in package.json');
|
|
61
43
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const prerelease = this.package_json.version.includes('pre');
|
|
65
|
-
|
|
66
|
-
const options = {
|
|
67
|
-
host: this.host,
|
|
68
|
-
owner: this.owner,
|
|
69
|
-
repo: this.repo,
|
|
70
|
-
tag_name: this.package_json.version,
|
|
71
|
-
target_commitish: 'main',
|
|
72
|
-
name: 'node-v' + this.package_json.version,
|
|
73
|
-
body: this.package_json.name + ' ' + this.package_json.version,
|
|
74
|
-
draft: true,
|
|
75
|
-
prerelease: prerelease
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
Object.keys(args).forEach(function(key) {
|
|
79
|
-
if(args.hasOwnProperty(key) && options.hasOwnProperty(key)) {
|
|
80
|
-
options[key] = args[key];
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
const release = await this.octokit.rest.repos.createRelease(options);
|
|
85
|
-
return release;
|
|
44
|
+
else if (this.package_json.binary.host.replace('https://', 'https://api.').substring(0, hostPrefix.length) !== hostPrefix) {
|
|
45
|
+
throw new Error('binary.host in package.json should begin with: "' + hostPrefix + '"');
|
|
86
46
|
}
|
|
87
47
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
48
|
+
this.octokit = this.createOctokitInstance(token);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
createOctokitInstance(token) {
|
|
52
|
+
return new Octokit({
|
|
53
|
+
baseUrl: "https://" + this.host,
|
|
54
|
+
auth: token,
|
|
55
|
+
userAgent: this.package_json.name ? this.package_json.name : "node-pre-gyp-github",
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async createRelease(args) {
|
|
60
|
+
const prerelease = this.package_json.version.includes('pre');
|
|
61
|
+
|
|
62
|
+
const options = {
|
|
63
|
+
host: this.host,
|
|
64
|
+
owner: this.owner,
|
|
65
|
+
repo: this.repo,
|
|
66
|
+
tag_name: this.package_json.version,
|
|
67
|
+
target_commitish: 'main',
|
|
68
|
+
name: 'node-v' + this.package_json.version,
|
|
69
|
+
body: this.package_json.name + ' ' + this.package_json.version,
|
|
70
|
+
draft: true,
|
|
71
|
+
prerelease: prerelease
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
Object.keys(args).forEach(function (key) {
|
|
75
|
+
if (args.hasOwnProperty(key) && options.hasOwnProperty(key)) {
|
|
76
|
+
options[key] = args[key];
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
const release = await this.octokit.rest.repos.createRelease(options);
|
|
81
|
+
return release;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async uploadAssets() {
|
|
85
|
+
consoleLog("Stage directory path: " + path.join(this.stage_dir));
|
|
86
|
+
|
|
87
|
+
const files = fs.readdirSync(path.join(this.stage_dir));
|
|
88
|
+
if (!files.length) throw new Error('No files found within the stage directory: ' + this.stage_dir);
|
|
89
|
+
|
|
90
|
+
for (const file of files) {
|
|
91
|
+
if (this.release && this.release.assets) {
|
|
92
|
+
const asset = this.release.assets.filter(element => element.name === file);
|
|
93
|
+
if (asset.length) {
|
|
94
|
+
throw new Error("Staged file " + file + " found but it already exists in release " + this.release.tag_name + ". If you would like to replace it, you must first manually delete it within GitHub.");
|
|
115
95
|
}
|
|
116
|
-
|
|
96
|
+
}
|
|
117
97
|
|
|
118
|
-
|
|
119
|
-
verbose = (typeof options.verbose === 'undefined' || options.verbose) ? true : false;
|
|
98
|
+
consoleLog(`Staged file ${file} found - proceeding to upload`);
|
|
120
99
|
|
|
121
|
-
|
|
100
|
+
const filePath = path.join(this.stage_dir, file);
|
|
101
|
+
const fileContents = fs.readFileSync(filePath);
|
|
122
102
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
103
|
+
await this.octokit.rest.repos.uploadReleaseAsset({
|
|
104
|
+
owner: this.owner,
|
|
105
|
+
repo: this.repo,
|
|
106
|
+
release_id: this.release.id,
|
|
107
|
+
name: file,
|
|
108
|
+
data: fileContents
|
|
109
|
+
});
|
|
110
|
+
consoleLog('Staged file ' + file + ' saved to ' + this.owner + '/' + this.repo + ' release ' + this.release.tag_name + ' successfully.');
|
|
111
|
+
}
|
|
112
|
+
}
|
|
127
113
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
options.tag_name = this.package_json.binary.remote_path.replace(/\{version\}/g, this.package_json.version);
|
|
131
|
-
this.stage_dir = path.join(this.stage_dir, options.tag_name);
|
|
132
|
-
} else {
|
|
133
|
-
// This is here for backwards compatibility for before binary.remote_path support was added in version 1.2.0.
|
|
134
|
-
options.tag_name = this.package_json.version;
|
|
135
|
-
}
|
|
114
|
+
async publish(options = {}) {
|
|
115
|
+
verbose = (typeof options.verbose === 'undefined' || options.verbose) ? true : false;
|
|
136
116
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
consoleLog(`Release ${this.release.tag_name} not found, so a draft release was created. YOU MUST MANUALLY PUBLISH THIS DRAFT WITHIN GITHUB FOR IT TO BE ACCESSIBLE.`);
|
|
144
|
-
} else {
|
|
145
|
-
consoleLog(`Release ${this.release.tag_name} not found, so a new release was created and published.`);
|
|
146
|
-
}
|
|
147
|
-
} else {
|
|
148
|
-
this.release = release[0];
|
|
149
|
-
}
|
|
117
|
+
await this.init();
|
|
118
|
+
|
|
119
|
+
const { data } = await this.octokit.rest.repos.listReleases({
|
|
120
|
+
owner: this.owner,
|
|
121
|
+
repo: this.repo
|
|
122
|
+
});
|
|
150
123
|
|
|
151
|
-
|
|
124
|
+
// when remote_path is set expect files to be in stage_dir / remote_path after substitution
|
|
125
|
+
if (this.package_json.binary.remote_path) {
|
|
126
|
+
options.tag_name = this.package_json.binary.remote_path.replace(/\{version\}/g, this.package_json.version);
|
|
127
|
+
this.stage_dir = path.join(this.stage_dir, options.tag_name);
|
|
128
|
+
} else {
|
|
129
|
+
// This is here for backwards compatibility for before binary.remote_path support was added in version 1.2.0.
|
|
130
|
+
options.tag_name = this.package_json.version;
|
|
152
131
|
}
|
|
153
|
-
|
|
132
|
+
|
|
133
|
+
const release = data.filter(element => element.tag_name === options.tag_name);
|
|
134
|
+
|
|
135
|
+
if (release.length === 0) {
|
|
136
|
+
const release = await this.createRelease(options);
|
|
137
|
+
this.release = release.data;
|
|
138
|
+
if (this.release.draft) {
|
|
139
|
+
consoleLog(`Release ${this.release.tag_name} not found, so a draft release was created. YOU MUST MANUALLY PUBLISH THIS DRAFT WITHIN GITHUB FOR IT TO BE ACCESSIBLE.`);
|
|
140
|
+
} else {
|
|
141
|
+
consoleLog(`Release ${this.release.tag_name} not found, so a new release was created and published.`);
|
|
142
|
+
}
|
|
143
|
+
} else {
|
|
144
|
+
this.release = release[0];
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
await this.uploadAssets();
|
|
148
|
+
}
|
|
149
|
+
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@acalcutt/node-pre-gyp-github",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "2.0.1-pre.1",
|
|
4
4
|
"description": "A node-pre-gyp module which provides the ability to publish to GitHub releases.",
|
|
5
5
|
"bin": "./bin/node-pre-gyp-github.js",
|
|
6
6
|
"main": "index.js",
|
|
7
|
+
"type": "module",
|
|
7
8
|
"scripts": {
|
|
8
|
-
"test": "
|
|
9
|
-
"coverage": "
|
|
10
|
-
"ship": "STATUS=$(git status --porcelain); echo $STATUS; if [ -z \"$STATUS\" ]; then
|
|
9
|
+
"test": "c8 --reporter=lcov --reporter=text mocha",
|
|
10
|
+
"coverage": "c8 --reporter=text-lcov mocha | coveralls",
|
|
11
|
+
"ship": "STATUS=$(git status --porcelain); echo $STATUS; if [ -z \"$STATUS\" ]; then npm publish && git push --follow-tags; fi"
|
|
11
12
|
},
|
|
12
13
|
"repository": {
|
|
13
14
|
"type": "git",
|
|
@@ -30,21 +31,22 @@
|
|
|
30
31
|
"releases"
|
|
31
32
|
],
|
|
32
33
|
"dependencies": {
|
|
33
|
-
"@octokit/rest": "
|
|
34
|
-
"commander": "
|
|
34
|
+
"@octokit/rest": "21.1.1",
|
|
35
|
+
"commander": "13.1.0",
|
|
36
|
+
"semver": "^7.6.3"
|
|
35
37
|
},
|
|
36
38
|
"devDependencies": {
|
|
37
|
-
"
|
|
38
|
-
"chai
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"sinon": "
|
|
39
|
+
"c8": "^10.1.3",
|
|
40
|
+
"chai": "5.2.0",
|
|
41
|
+
"chai-as-promised": "8.0.1",
|
|
42
|
+
"coveralls-next": "^4.2.1",
|
|
43
|
+
"mocha": "11.1.0",
|
|
44
|
+
"sinon": "20.0.0"
|
|
43
45
|
},
|
|
44
46
|
"author": "Bill Christo",
|
|
45
47
|
"license": "MIT",
|
|
46
48
|
"bugs": {
|
|
47
|
-
"url": "https://github.com/
|
|
49
|
+
"url": "https://github.com/acalcutt/node-pre-gyp-github/issues"
|
|
48
50
|
},
|
|
49
|
-
"homepage": "https://github.com/
|
|
51
|
+
"homepage": "https://github.com/acalcutt/node-pre-gyp-github#readme"
|
|
50
52
|
}
|