Socket
Socket
Sign inDemoInstall

node-pre-gyp-github

Package Overview
Dependencies
Maintainers
3
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

node-pre-gyp-github - npm Package Compare versions

Comparing version 1.4.3 to 1.4.4

47

bin/node-pre-gyp-github.js
#!/usr/bin/env node
var module = require('../index.js');
var program = require('commander');
const NodePreGypGithub = require('../index.js');
const program = require('commander');
program
.command('publish [options]')
.description('publishes the contents of .\\build\\stage\\{version} to the current version\'s GitHub release')
.option("-r, --release", "publish immediately, do not create draft")
.option("-s, --silent", "turns verbose messages off")
.action(function(cmd, options){
var opts = {},
x = new module();
opts.draft = options.release ? false : true;
opts.verbose = options.silent ? false : true;
x.publish(opts);
});
.command('publish')
.description('publishes the contents of .\\build\\stage\\{version} to the current version\'s GitHub release')
.option("-r, --release", "publish immediately, do not create draft")
.option("-s, --silent", "turns verbose messages off")
.action(async function(cmd, options){
const opts = {
draft: options.release ? false : true,
verbose: options.silent ? false : true
};
try {
const nodePreGypGithub = new NodePreGypGithub();
await nodePreGypGithub.publish(opts);
} catch (err) {
console.error(`An error occurred whilst publishing:`, err);
process.exit(1);
}
});
program
.command('help','',{isDefault: true, noHelp: true})
.action(function() {
console.log();
console.log('Usage: node-pre-gyp-github publish');
console.log();
console.log('publishes the contents of .\\build\\stage\\{version} to the current version\'s GitHub release');
});
program.parse(process.argv);
if (!program.args.length) {
program.help();
}
program.parseAsync(process.argv);
"use strict";
var path = require("path");
var fs = require('fs');
var mime = require("mime-types");
var cwd = process.cwd();
const path = require('path');
const fs = require('fs');
const cwd = process.cwd();
var verbose;
var consoleLog = function(x){
return (verbose) ? console.log(x) : false;
};
const {Octokit} = require('@octokit/rest');
function NodePreGypGithub() {}
NodePreGypGithub.prototype.octokit = require("@octokit/rest");
NodePreGypGithub.prototype.stage_dir = path.join(cwd,"build","stage");
NodePreGypGithub.prototype.init = function() {
var ownerRepo, hostPrefix;
this.package_json = JSON.parse(fs.readFileSync(path.join(cwd,'package.json')));
if(!this.package_json.repository || !this.package_json.repository.url){
throw new Error('Missing repository.url in package.json');
}
else {
ownerRepo = this.package_json.repository.url.match(/https?:\/\/([^\/]+)\/(.*)(?=\.git)/i);
if(ownerRepo) {
this.host = 'api.' + ownerRepo[1];
ownerRepo = ownerRepo[2].split('/');
this.owner = ownerRepo[0];
this.repo = ownerRepo[1];
}
else throw new Error('A correctly formatted GitHub repository.url was not found within package.json');
}
hostPrefix = 'https://' + this.host + '/' + this.owner + '/' + this.repo + '/releases/download/';
if(!this.package_json.binary || 'object' !== typeof this.package_json.binary || 'string' !== typeof this.package_json.binary.host){
throw new Error('Missing binary.host in package.json');
}
else if (this.package_json.binary.host.replace('https://','https://api.').substr(0, hostPrefix.length) !== hostPrefix){
throw new Error('binary.host in package.json should begin with: "' + hostPrefix + '"');
}
let verbose;
this.octokit = NodePreGypGithub.prototype.octokit({
baseUrl: 'https://' + this.host,
headers: {
"user-agent": (this.package_json.name) ? this.package_json.name : "node-pre-gyp-github"
function consoleLog(x) {
return (verbose) ? console.log(x) : false;
}
module.exports = class NodePreGypGithub {
constructor() {
this.stage_dir = path.join(cwd, 'build', 'stage');
}
});
};
NodePreGypGithub.prototype.authenticate_settings = function(){
var token = process.env.NODE_PRE_GYP_GITHUB_TOKEN;
if(!token) throw new Error('NODE_PRE_GYP_GITHUB_TOKEN environment variable not found');
return {
"type": "oauth",
"token": token
};
};
init() {
const token = process.env.NODE_PRE_GYP_GITHUB_TOKEN;
if (!token) {
throw new Error('NODE_PRE_GYP_GITHUB_TOKEN environment variable not found');
}
NodePreGypGithub.prototype.createRelease = function(args, callback) {
var options = {
'host': this.host,
'owner': this.owner,
'repo': this.repo,
'tag_name': this.package_json.version,
'target_commitish': 'master',
'name': 'v' + this.package_json.version,
'body': this.package_json.name + ' ' + this.package_json.version,
'draft': true,
'prerelease': false
};
Object.keys(args).forEach(function(key) {
if(args.hasOwnProperty(key) && options.hasOwnProperty(key)) {
options[key] = args[key];
}
});
this.octokit.authenticate(this.authenticate_settings());
this.octokit.repos.createRelease(options, callback);
};
this.package_json = JSON.parse(fs.readFileSync(path.join(cwd, 'package.json'), 'utf-8'));
NodePreGypGithub.prototype.uploadAsset = function(cfg){
this.octokit.authenticate(this.authenticate_settings());
this.octokit.repos.uploadAsset({
url: this.release.upload_url,
owner: this.owner,
id: this.release.id,
repo: this.repo,
name: cfg.fileName,
file: fs.createReadStream(cfg.filePath),
contentType: mime.contentType(cfg.fileName) || 'application/octet-stream',
contentLength: fs.statSync(cfg.filePath).size
}, function(err){
if(err) throw err;
consoleLog('Staged file ' + cfg.fileName + ' saved to ' + this.owner + '/' + this.repo + ' release ' + this.release.tag_name + ' successfully.');
}.bind(this));
};
if (!this.package_json.repository || !this.package_json.repository.url) {
throw new Error('Missing repository.url in package.json');
} else {
const ownerRepo = this.package_json.repository.url.match(/https?:\/\/([^\/]+)\/(.*)(?=\.git)/i);
if (!ownerRepo) {
throw new Error('A correctly formatted GitHub repository.url was not found within package.json');
}
NodePreGypGithub.prototype.uploadAssets = function(){
var asset;
consoleLog("Stage directory path: " + path.join(this.stage_dir));
fs.readdir(path.join(this.stage_dir), function(err, files){
if(err) throw err;
if(!files.length) throw new Error('No files found within the stage directory: ' + this.stage_dir);
files.forEach(function(file){
if(this.release && this.release.assets) {
asset = this.release.assets.filter(function(element, index, array){
return element.name === file;
});
if(asset.length) {
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.");
}
}
consoleLog("Staged file " + file + " found. Proceeding to upload it.");
this.uploadAsset({
fileName: file,
filePath: path.join(this.stage_dir, file)
});
}.bind(this));
}.bind(this));
};
this.host = 'api.' + ownerRepo[1];
const [owner, repo] = ownerRepo[2].split('/');
this.owner = owner;
this.repo = repo;
}
NodePreGypGithub.prototype.publish = function(options) {
options = (typeof options === 'undefined') ? {} : options;
verbose = (typeof options.verbose === 'undefined' || options.verbose) ? true : false;
this.init();
this.octokit.authenticate(this.authenticate_settings());
this.octokit.repos.getReleases({
'owner': this.owner,
'repo': this.repo
}, function(err, data){
var release;
if(err) throw err;
// when remote_path is set expect files to be in stage_dir / remote_path after substitution
if (this.package_json.binary.remote_path) {
options.tag_name = this.package_json.binary.remote_path.replace(/\{version\}/g, this.package_json.version);
this.stage_dir = path.join(this.stage_dir, options.tag_name);
} else {
// This is here for backwards compatibility for before binary.remote_path support was added in version 1.2.0.
options.tag_name = this.package_json.version;
}
release = data.data.filter(function(element, index, array){
return element.tag_name === options.tag_name;
});
if(release.length === 0) {
this.createRelease(options, function(err, release) {
if(err) throw err;
this.release = release.data;
if (this.release.draft) {
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.");
}
else {
consoleLog('Release ' + release.tag_name + " not found, so a new release was created and published.");
}
this.uploadAssets(this.release.upload_url);
}.bind(this));
}
else {
this.release = release[0];
this.uploadAssets();
}
}.bind(this));
const hostPrefix = 'https://' + this.host + '/' + this.owner + '/' + this.repo + '/releases/download/';
if(!this.package_json.binary || 'object' !== typeof this.package_json.binary || 'string' !== typeof this.package_json.binary.host){
throw new Error('Missing binary.host in package.json');
}
else if (this.package_json.binary.host.replace('https://','https://api.').substr(0, hostPrefix.length) !== hostPrefix){
throw new Error('binary.host in package.json should begin with: "' + hostPrefix + '"');
}
this.octokit = this.createOctokitInstance(token);
}
createOctokitInstance(token) {
return new Octokit({
baseUrl: 'https://' + this.host,
auth: token,
headers: {
"user-agent": (this.package_json.name) ? this.package_json.name : "node-pre-gyp-github"
}
});
}
async createRelease(args) {
const options = {
host: this.host,
owner: this.owner,
repo: this.repo,
tag_name: this.package_json.version,
target_commitish: 'master',
name: 'v' + this.package_json.version,
body: this.package_json.name + ' ' + this.package_json.version,
draft: true,
prerelease: false
};
Object.keys(args).forEach(function(key) {
if(args.hasOwnProperty(key) && options.hasOwnProperty(key)) {
options[key] = args[key];
}
});
const release = await this.octokit.rest.repos.createRelease(options);
return release;
}
async uploadAssets() {
consoleLog("Stage directory path: " + path.join(this.stage_dir));
const files = fs.readdirSync(path.join(this.stage_dir));
if(!files.length) throw new Error('No files found within the stage directory: ' + this.stage_dir);
for (const file of files) {
if (this.release && this.release.assets) {
const asset = this.release.assets.filter(element => element.name === file);
if (asset.length) {
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.");
}
}
consoleLog(`Staged file ${file} found - proceeding to upload`);
const filePath = path.join(this.stage_dir, file);
const fileContents = fs.readFileSync(filePath);
await this.octokit.rest.repos.uploadReleaseAsset({
owner: this.owner,
repo: this.repo,
release_id: this.release.id,
name: file,
data: fileContents
});
consoleLog('Staged file ' + file + ' saved to ' + this.owner + '/' + this.repo + ' release ' + this.release.tag_name + ' successfully.');
}
}
async publish(options = {}) {
verbose = (typeof options.verbose === 'undefined' || options.verbose) ? true : false;
await this.init();
const {data} = await this.octokit.rest.repos.listReleases({
owner: this.owner,
repo: this.repo
});
// when remote_path is set expect files to be in stage_dir / remote_path after substitution
if (this.package_json.binary.remote_path) {
options.tag_name = this.package_json.binary.remote_path.replace(/\{version\}/g, this.package_json.version);
this.stage_dir = path.join(this.stage_dir, options.tag_name);
} else {
// This is here for backwards compatibility for before binary.remote_path support was added in version 1.2.0.
options.tag_name = this.package_json.version;
}
const release = data.filter(element => element.tag_name === options.tag_name);
if (release.length === 0) {
const release = await this.createRelease(options);
this.release = release.data;
if (this.release.draft) {
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.`);
} else {
consoleLog(`Release ${this.release.tag_name} not found, so a new release was created and published.`);
}
} else {
this.release = release[0];
}
await this.uploadAssets();
}
};
module.exports = NodePreGypGithub;
{
"name": "node-pre-gyp-github",
"version": "1.4.3",
"version": "1.4.4",
"description": "A node-pre-gyp module which provides the ability to publish to GitHub releases.",

@@ -9,3 +9,4 @@ "bin": "./bin/node-pre-gyp-github.js",

"test": "nyc --reporter=html --reporter=text mocha",
"coverage": "nyc report --reporter=text-lcov | coveralls"
"coverage": "nyc report --reporter=text-lcov | coveralls",
"ship": "STATUS=$(git status --porcelain); echo $STATUS; if [ -z \"$STATUS\" ]; then yarn publish && git push --follow-tags; fi"
},

@@ -16,2 +17,6 @@ "repository": {

},
"files": [
"bin",
"index.js"
],
"keywords": [

@@ -30,12 +35,12 @@ "node-pre-gyp",

"dependencies": {
"@octokit/rest": "^15.9.5",
"commander": "^2.17.0",
"mime-types": "^2.1.19"
"@octokit/rest": "18.12.0",
"commander": "7.2.0"
},
"devDependencies": {
"chai": "^3.5.0",
"coveralls": "^3.0.2",
"mocha": "^5.2.0",
"nyc": "^12.0.2",
"sinon": "^6.1.4"
"chai": "4.3.6",
"chai-as-promised": "7.1.1",
"coveralls": "3.0.2",
"mocha": "7.2.0",
"nyc": "15.1.0",
"sinon": "13.0.1"
},

@@ -42,0 +47,0 @@ "author": "Bill Christo",

# node-pre-gyp-github
##### A node-pre-gyp module which provides the ability to publish to GitHub releases.

@@ -8,5 +9,7 @@

## Usage
Instead of ```node-pre-gyp publish``` use **```node-pre-gyp-github publish```**
## Options for publish command
* --silent : Turns verbose messages off.

@@ -18,10 +21,15 @@ * --release : Publish the GitHub Release immediately instead of creating a Draft.

## Install
```javascript
```bash
npm install -g node-pre-gyp-github
# or
yarn global add node-pre-gyp-github
```
## Configuration
This module is intended to be used with node-pre-gyp. Therefore, be sure to configure and install node-pre-gyp first. After having done that, within **```package.json```** update the ```binary``` properties ```host``` and ```remote_path``` so it matches the following format:
```
```json
"host": "https://github.com/[owner]/[repo]/releases/download/",

@@ -38,8 +46,8 @@ "remote_path": "{version}"

1. go to Settings
2. click Personal access tokens
3. click Generate new token
4. Select "public_repo" and "repo_deployment"
1. go to `Settings` -> `Developer settings`
2. click [`Personal access tokens`](https://github.com/settings/tokens)
3. click `Generate new token`
4. Select `public_repo` and `repo_deployment`
5. Generate Token
6. copy the key that's generated and set NODE_PRE_GYP_GITHUB_TOKEN environment variable to it. Within your command prompt:
6. copy the key that's generated and set `NODE_PRE_GYP_GITHUB_TOKEN` environment variable to it. Within your command prompt:

@@ -51,2 +59,3 @@ ```

## Example (Publish to GitHub as a Draft Release)
1. node-pre-gyp configure

@@ -58,2 +67,3 @@ 2. node-pre-gyp build

## Example (Publish to GitHub as a Release)
1. node-pre-gyp configure

@@ -60,0 +70,0 @@ 2. node-pre-gyp build

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc