Skip to content

Commit

Permalink
Merge branch 'allenluce-ghe'
Browse files Browse the repository at this point in the history
  • Loading branch information
bchr02 committed Aug 4, 2018
2 parents c239d3f + 52e9af0 commit a902fab
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 93 deletions.
112 changes: 46 additions & 66 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

var path = require("path");
var fs = require('fs');
var GitHubApi = require("github");
var mime = require("mime-types");
var cwd = process.cwd();

var verbose;
Expand All @@ -11,25 +11,8 @@ var consoleLog = function(x){
};

function NodePreGypGithub() {}

NodePreGypGithub.prototype.github = new GitHubApi({ // set defaults
// required
version: "3.0.0",
// optional
debug: false,
protocol: "https",
host: "api.github.com",
pathPrefix: "", // for some GHEs; none for GitHub
timeout: 5000,
headers: {}
});

NodePreGypGithub.prototype.owner = "";
NodePreGypGithub.prototype.repo = "";
NodePreGypGithub.prototype.package_json = {};
NodePreGypGithub.prototype.release = {};
NodePreGypGithub.prototype.octokit = require("@octokit/rest");
NodePreGypGithub.prototype.stage_dir = path.join(cwd,"build","stage");

NodePreGypGithub.prototype.init = function() {
var ownerRepo, hostPrefix;

Expand All @@ -39,25 +22,30 @@ NodePreGypGithub.prototype.init = function() {
throw new Error('Missing repository.url in package.json');
}
else {
ownerRepo = this.package_json.repository.url.match(/github\.com\/(.*)(?=\.git)/i);
ownerRepo = this.package_json.repository.url.match(/https?:\/\/([^\/]+)\/(.*)(?=\.git)/i);
if(ownerRepo) {
ownerRepo = ownerRepo[1].split('/');
this.host = 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://github.com/' + this.owner + '/' + this.repo + '/releases/download/';
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.substr(0, hostPrefix.length) !== hostPrefix){
throw new Error('binary.host in package.json should begin with: "' + hostPrefix + '"');
}

this.github.headers = {"user-agent": (this.package_json.name) ? this.package_json.name : "node-pre-gyp-github"}; // GitHub is happy with a unique user agent


this.octokit = NodePreGypGithub.prototype.octokit({
baseUrl: 'https://' + this.host + '/api/v3',
headers: {
"user-agent": (this.package_json.name) ? this.package_json.name : "node-pre-gyp-github"
}
});
};

NodePreGypGithub.prototype.authenticate_settings = function(){
Expand All @@ -71,6 +59,7 @@ NodePreGypGithub.prototype.authenticate_settings = function(){

NodePreGypGithub.prototype.createRelease = function(args, callback) {
var options = {
'host': this.host,
'owner': this.owner,
'repo': this.repo,
'tag_name': this.package_json.version,
Expand All @@ -86,19 +75,21 @@ NodePreGypGithub.prototype.createRelease = function(args, callback) {
options[key] = args[key];
}
});

this.github.authenticate(this.authenticate_settings());
this.github.releases.createRelease(options, callback);
this.octokit.authenticate(this.authenticate_settings());
this.octokit.repos.createRelease(options, callback);
};

NodePreGypGithub.prototype.uploadAsset = function(cfg){
this.github.authenticate(this.authenticate_settings());
this.github.releases.uploadAsset({
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,
filePath: cfg.filePath
file: 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.');
Expand All @@ -114,19 +105,19 @@ NodePreGypGithub.prototype.uploadAssets = function(){
if(!files.length) throw new Error('No files found within the stage directory: ' + this.stage_dir);

files.forEach(function(file){
asset = this.release.assets.filter(function(element, index, array){
return element.name === 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)
});
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.");
}
else {
consoleLog("Staged file " + file + " found. Proceeding to upload it.");
this.uploadAsset({
fileName: file,
filePath: path.join(this.stage_dir, file)
});
}
}.bind(this));
}.bind(this));
};
Expand All @@ -135,13 +126,12 @@ NodePreGypGithub.prototype.publish = function(options) {
options = (typeof options === 'undefined') ? {} : options;
verbose = (typeof options.verbose === 'undefined' || options.verbose) ? true : false;
this.init();
this.github.authenticate(this.authenticate_settings());
this.github.releases.listReleases({
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
Expand All @@ -152,37 +142,27 @@ NodePreGypGithub.prototype.publish = function(options) {
// 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 = (function(){ // create a new array containing only those who have a matching version.
if(data) {
data = data.filter(function(element, index, array){
return element.tag_name === options.tag_name;
}.bind(this));
return data;
}
else return [];
}.bind(this))();

this.release = release[0];

if(!release.length) {
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;
if (release.draft) {
consoleLog('Release ' + release.tag_name + " not found, so a draft release was created. YOU MUST MANUALLY PUBLISH THIS DRAFT WITHIN GITHUB FOR IT TO BE ACCESSIBLE.");
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.uploadAssets(this.release.upload_url);
}.bind(this));
}
else {
this.release = release[0];
this.uploadAssets();
}
}.bind(this));
};

module.exports = NodePreGypGithub;
module.exports = NodePreGypGithub;
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@
"releases"
],
"dependencies": {
"github": "^0.2.4",
"commander": "^2.9.0"
"@octokit/rest": "^15.9.5",
"commander": "^2.9.0",
"mime-types": "^2.1.19",
"sinon": "^6.1.4"
},
"devDependencies": {
"chai": "^3.5.0",
Expand Down
60 changes: 35 additions & 25 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,31 @@ var fs = require("fs");
var Index = require('../index.js');
var index = new Index();
var stage_dir = index.stage_dir;
var Octokit = require("@octokit/rest");
var octokit = Octokit();
var sinon = require('sinon')
var reset_index = function(index_string_ref) {
delete require.cache[require.resolve(index_string_ref)];
return require(index_string_ref);
};

var sandbox = sinon.createSandbox();

var reset_mocks = function() {
sandbox.restore();
process.env.NODE_PRE_GYP_GITHUB_TOKEN = "secret";
fs = reset_index('fs');
fs.readFileSync = function(){return '{"name":"test","version":"0.0.1","repository": {"url":"git+https://github.com/test/test.git"},"binary":{"host":"https://github.com/test/test/releases/download/","remote_path":"{version}"}}';};
index.stage_dir = stage_dir;
index.github.authenticate = function(){};
index.github.releases.listReleases = function(options, cb){
cb(null, [{"tag_name":"0.0.0","assets":[{"name":"filename"}]}]);
};
index.github.releases.createRelease = function(options, cb){
cb(null,{"tag_name":"0.0.1","draft":true,"assets":[{}]});
};
index.github.releases.uploadAsset = function(cfg,cb){cb();};
Index.prototype.octokit = function() {return octokit;};
sandbox.stub(octokit, 'authenticate');
sandbox.stub(octokit.repos, 'getReleases').callsFake(function(options, cb){
cb(null, {data: [{"tag_name":"0.0.0","assets":[{"name":"filename"}]}]});
});
sandbox.stub(octokit.repos, 'createRelease').callsFake(function(options, cb){
cb(null,{data: {"tag_name":"0.0.1","draft":true,"assets":[{}]}});
});
sandbox.stub(octokit.repos, 'uploadAsset').callsFake(function(cfg,cb){cb();});
};

if(!process.env.COVERALLS_SERVICE_NAME) console.log('To post to coveralls.io, be sure to set COVERALLS_SERVICE_NAME environment variable');
Expand All @@ -37,9 +45,8 @@ describe("Publishes packages to GitHub Releases", function() {
fs.readdir = function(filename, cb) {
cb(null,["filename"]);
};
index.github.releases.createRelease = function(options, cb){
cb(null,{"tag_name":"0.0.1","draft":false,"assets":[{}]});
};
fs.statSync = function() {return 0;}
index.publish(options)
expect(function(){ index.publish(options); }).to.not.throw();
});

Expand Down Expand Up @@ -91,22 +98,24 @@ describe("Publishes packages to GitHub Releases", function() {
expect(function(){ index.publish(options); }).to.throw("NODE_PRE_GYP_GITHUB_TOKEN environment variable not found");
});

it("should throw an error when github.releases.listReleases returns an error", function() {
it("should throw an error when octokit.repos.getReleases returns an error", function() {
var options = {'draft': true, 'verbose': false};
reset_mocks();
index.github.releases.listReleases = function(options, cb){
cb(new Error('listReleases error'));
};
expect(function(){ index.publish(options); }).to.throw('listReleases error');

octokit.repos.getReleases.restore();
sandbox.stub(octokit.repos, 'getReleases').callsFake(function(options, cb){
cb(new Error('getReleases error'));
});
expect(function(){ index.publish(options); }).to.throw('getReleases error');
});

it("should throw an error when github.releases.createRelease returns an error", function() {
var options = {'draft': true, 'verbose': false};
reset_mocks();
index.github.releases.listReleases = function(options, cb){
cb(null,null);
octokit.repos.getReleases = function(options, cb){
cb(null,{data: []});
};
index.github.releases.createRelease = function(options, cb){
octokit.repos.createRelease = function(options, cb){
cb(new Error('createRelease error'));
};
expect(function(){ index.publish(options); }).to.throw('createRelease error');
Expand Down Expand Up @@ -136,8 +145,8 @@ describe("Publishes packages to GitHub Releases", function() {
fs.readdir = function(filename, cb) {
cb(null,["filename"]);
};
index.github.releases.listReleases = function(options, cb){
cb(null, [{"tag_name":"0.0.1","assets":[{"name":"filename"}]}]);
octokit.repos.getReleases = function(options, cb){
cb(null, {data: [{"tag_name":"0.0.1","assets":[{"name":"filename"}]}]});
};
expect(function(){ index.publish(options); }).to.throw(/^Staged file .* found but it already exists in release .*. If you would like to replace it, you must first manually delete it within GitHub./i);
});
Expand All @@ -148,7 +157,7 @@ describe("Publishes packages to GitHub Releases", function() {
fs.readdir = function(filename, cb) {
cb(null,["filename"]);
};
index.github.releases.uploadAsset = function(cfg,cb){
octokit.repos.uploadAsset = function(cfg,cb){
cb(new Error('uploadAsset error'));
};
expect(function(){ index.publish(options); }).to.throw("uploadAsset error");
Expand All @@ -165,11 +174,12 @@ describe("Publishes packages to GitHub Releases", function() {
fs.readdir = function(filename, cb) {
cb(null,["filename"]);
};
index.github.releases.createRelease = function(options, cb){
cb(null,{"tag_name":"0.0.1","draft":false,"assets":[{}]});
fs.statSync = function() {return 0;}
octokit.reposcreateRelease = function(options, cb){
cb(null,{data: {"tag_name":"0.0.1","draft":false,"assets":[{}]}});
};
expect(function(){ index.publish(options); }).to.not.throw();
});

});
});
});

0 comments on commit a902fab

Please sign in to comment.