Skip to content

Commit fe7942c

Browse files
committed
port to @octokit/rest
1 parent d5b5adc commit fe7942c

2 files changed

Lines changed: 85 additions & 150 deletions

File tree

package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
"scripts": {
1111
"prepublish": "npm run build",
1212
"build": "babel --out-dir ./lib ./src",
13-
"test": "tap test/*.js --no-timeout --node-arg=--require --node-arg=babel-register --node-arg=--require --node-arg=babel-polyfill"
13+
"_test": "tap test/*.js --no-timeout --node-arg=--require --node-arg=babel-register --node-arg=--require --node-arg=babel-polyfill",
14+
"test": "npm run build && node lib/index.js --owner cheton --repo github-release-cli list"
1415
},
1516
"files": [
1617
"bin",
@@ -31,7 +32,10 @@
3132
"@octokit/rest": "^16.9.0",
3233
"babel-runtime": "^6.26.0",
3334
"commander": "^2.19.0",
34-
"minimatch": "^3.0.4"
35+
"http-link-header": "^1.0.2",
36+
"mime-types": "^2.1.21",
37+
"minimatch": "^3.0.4",
38+
"url-parse": "^1.4.4"
3539
},
3640
"devDependencies": {
3741
"babel-cli": "^6.26.0",

src/index.js

Lines changed: 79 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
/* eslint no-console: 0 */
22
/* eslint max-len: 0 */
33
import path from 'path';
4-
import GitHubApi from 'github';
4+
55
import program from 'commander';
66
import minimatch from 'minimatch';
77
import pkg from '../package.json';
8+
import * as LinkHeader from 'http-link-header';
9+
const URL = require('url-parse');
10+
import * as mime from 'mime-types';
11+
12+
import Octokit from '@octokit/rest';
13+
const octokit = new Octokit();
814

915
program
1016
.version(pkg.version)
@@ -32,115 +38,20 @@ program.parse(process.argv);
3238

3339
const [command, ...args] = program.args;
3440

35-
const github = new GitHubApi({
36-
version: '3.0.0',
37-
timeout: 5000,
38-
headers: {
39-
'user-agent': 'GitHub-Release-App'
40-
}
41-
});
42-
43-
github.authenticate({
41+
octokit.authenticate({
4442
type: 'oauth',
4543
token: program.token || process.env.GITHUB_TOKEN
4644
});
4745

48-
const getReleaseByTag = (options) => {
49-
return new Promise(async (resolve, reject) => {
50-
try {
51-
let page = 1;
52-
let lastPage = 1;
53-
let foundRelease = false;
46+
function next(response) {
47+
if (!response.headers || !response.headers.link) return false;
5448

55-
do {
56-
const releases = await getReleases({
57-
owner: options.owner,
58-
repo: options.repo,
59-
page: page,
60-
per_page: 30
61-
});
62-
63-
const searchedReleases = releases.filter(r => (r.tag_name === options.tag) || (r.name === options.tag));
64-
if (searchedReleases.length) {
65-
resolve(releases[0]);
66-
foundRelease = true;
67-
break;
68-
}
69-
70-
const pagination = (releases.meta.link || '').split(',')
71-
.reduce((acc, link) => {
72-
const r = link.match(/\?page=(\d)+.*rel="(\w+)"/);
73-
if (r && r[1] && r[2]) {
74-
const key = r[2];
75-
const value = Number(r[1]) || 0;
76-
acc[key] = value;
77-
}
78-
return acc;
79-
}, {});
80-
81-
if (pagination.last > 0) {
82-
lastPage = pagination.last;
83-
}
84-
85-
++page;
86-
} while (page <= lastPage);
87-
88-
if (!foundRelease) {
89-
reject('Cannot find release');
90-
}
91-
} catch (err) {
92-
reject(err);
93-
}
94-
});
95-
};
96-
97-
const getReleases = (options) => {
98-
return new Promise((resolve, reject) => {
99-
github.repos.getReleases(options, (err, res) => {
100-
err ? reject(err) : resolve(res);
101-
});
102-
});
103-
};
104-
105-
const createRelease = (options) => {
106-
return new Promise((resolve, reject) => {
107-
github.repos.createRelease(options, (err, res) => {
108-
err ? reject(err) : resolve(res);
109-
});
110-
});
111-
};
112-
113-
const editRelease = (options) => {
114-
return new Promise((resolve, reject) => {
115-
github.repos.editRelease(options, (err, res) => {
116-
err ? reject(err) : resolve(res);
117-
});
118-
});
119-
};
120-
121-
const getAssets = (options) => {
122-
return new Promise((resolve, reject) => {
123-
github.repos.getAssets(options, (err, res) => {
124-
err ? reject(err) : resolve(res);
125-
});
126-
});
127-
};
128-
129-
const deleteAsset = (options) => {
130-
return new Promise((resolve, reject) => {
131-
github.repos.deleteAsset(options, (err, res) => {
132-
err ? reject(err) : resolve(res);
133-
});
134-
});
135-
};
136-
137-
const uploadAsset = (options) => {
138-
return new Promise((resolve, reject) => {
139-
github.repos.uploadAsset(options, (err, res) => {
140-
err ? reject(err) : resolve(res);
141-
});
142-
});
143-
};
49+
let link = LinkHeader.parse(response.headers.link).rel('next');
50+
if (!link) return false;
51+
link = URL(link[0].uri, null, true).query
52+
if (!link) return false;
53+
return parseInt(link.page);
54+
}
14455

14556
const fn = {
14657
'upload': async () => {
@@ -150,7 +61,7 @@ const fn = {
15061

15162
try {
15263
console.log('> releases#getReleaseByTag');
153-
release = await getReleaseByTag({
64+
release = await octokit.repos.getReleaseByTag({
15465
owner: owner,
15566
repo: repo,
15667
tag: tag
@@ -162,47 +73,43 @@ const fn = {
16273
try {
16374
if (!release) {
16475
console.log('> releases#createRelease');
165-
release = await createRelease({
166-
owner: owner,
167-
repo: repo,
76+
result = await octokit.repos.createRelease({
77+
owner,
78+
repo,
16879
tag_name: tag,
16980
name: name || tag,
17081
body: body || '',
17182
draft: !!draft,
17283
prerelease: !!prerelease
173-
});
84+
})
17485
} else {
175-
console.log('> releases#editRelease');
176-
let releaseOptions = {
177-
owner: owner,
178-
repo: repo,
179-
id: release.id,
86+
console.log('> releases#updateRelease');
87+
release = await octokit.repos.updateRelease({
88+
owner,
89+
repo,
90+
release_id: release.id,
18091
tag_name: tag,
18192
name: name || tag,
182-
body: (body === undefined)
183-
? release.body || ''
184-
: body || '',
185-
draft: (draft === undefined)
186-
? !!release.draft
187-
: false,
188-
prerelease: (prerelease === undefined)
189-
? !!release.prerelease
190-
: false
191-
};
192-
release = await editRelease(releaseOptions);
93+
body: (body === undefined) ? release.body || '' : body || '',
94+
draft: (draft === undefined) ? !!release.draft : false,
95+
prerelease: (prerelease === undefined) ? !!release.prerelease : false,
96+
})
19397
}
19498

19599
if (files.length > 0) {
196-
console.log('> releases#uploadAsset');
100+
console.log('> releases#uploadReleaseAsset');
197101
for (let i = 0; i < files.length; ++i) {
198102
const file = files[i];
199103
console.log('#%d name="%s" filePath="%s"', i + 1, path.basename(file), file);
200-
await uploadAsset({
201-
owner: owner,
202-
repo: repo,
203-
id: release.id,
204-
filePath: file,
205-
name: path.basename(file)
104+
105+
await octokit.repos.uploadReleaseAsset({
106+
url: release.data.upload_url,
107+
file: fs.createReadStream(file),
108+
headers: {
109+
'content-type': mime.lookup('file') || 'application/octet-stream',
110+
'content-length': fs.statSync(file).size,
111+
},
112+
name: path.basename(asset),
206113
});
207114
}
208115
}
@@ -217,7 +124,7 @@ const fn = {
217124

218125
try {
219126
console.log('> releases#getReleaseByTag');
220-
release = await getReleaseByTag({
127+
release = await octokit.repos.getReleaseByTag({
221128
owner: owner,
222129
repo: repo,
223130
tag: tag
@@ -228,19 +135,24 @@ const fn = {
228135
}
229136

230137
try {
231-
console.log('> releases#getAssets');
232-
const assets = await getAssets({
233-
owner: owner,
234-
repo: repo,
235-
id: release.id
236-
});
138+
console.log('> releases#listAssetsForRelease');
139+
140+
let assets = [];
141+
let _assets = null;
142+
let page = 1;
143+
do {
144+
let _assets = await octokit.repos.listAssetsForRelease({owner, repo, release_id, per_page, page})
145+
assets = assets.concat(_assets.data)
146+
page = next(_assets)
147+
} while (page)
148+
237149
const deleteAssets = assets.filter(asset => {
238150
return patterns.some(pattern => minimatch(asset.name, pattern));
239151
});
240152
console.log('assets=%d, deleteAssets=%d', assets.length, deleteAssets.length);
241153

242154
if (deleteAssets.length > 0) {
243-
console.log('> releases#deleteAsset');
155+
console.log('> releases#deleteReleaseAsset');
244156
for (let i = 0; i < deleteAssets.length; ++i) {
245157
const asset = deleteAssets[i];
246158
console.log('#%d', i + 1, {
@@ -253,17 +165,36 @@ const fn = {
253165
created_at: asset.created_at,
254166
updated_at: asset.updated_at
255167
});
256-
await deleteAsset({
257-
owner: owner,
258-
repo: repo,
259-
id: asset.id
260-
});
168+
await octokit.repos.deleteReleaseAsset({owner, repo, asset_id: asset.id })
261169
}
262170
}
263171
} catch (err) {
264172
console.error(err);
265173
}
266-
}
174+
},
175+
'list': async () => {
176+
let releases = null;
177+
let page = 1;
178+
do {
179+
releases = await octokit.repos.listReleases({ owner: program.owner, repo: program.repo, page });
180+
for (const release of releases.data) {
181+
console.log(`${release.name} (${release.tag_name})`);
182+
}
183+
184+
page = next(releases)
185+
} while (page)
186+
},
267187
}[command];
268188

269-
typeof fn === 'function' && fn();
189+
async function main() {
190+
try {
191+
typeof fn === 'function' && await fn();
192+
} catch (err) {
193+
// message has token in the response
194+
const message = err.message.replace(/https?:[^\s]*/g, (match) => match.replace(/\?.*/, ''))
195+
console.log(message);
196+
process.exit(1);
197+
}
198+
}
199+
200+
main()

0 commit comments

Comments
 (0)