Skip to content

Commit 32654fb

Browse files
authoredMay 22, 2020
fix: skip permission verification exception when Github Apps (#272)
1 parent 543f40b commit 32654fb

File tree

2 files changed

+50
-15
lines changed

2 files changed

+50
-15
lines changed
 

‎lib/verify.js

+8
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,14 @@ module.exports = async (pluginConfig, context) => {
6969
},
7070
} = await github.repos.get({repo, owner});
7171
if (!push) {
72+
// If authenticated as GitHub App installation, `push` will always be false.
73+
// We send another request to check if current authentication is an installation.
74+
// Note: we cannot check if the installation has all required permissions, it's
75+
// up to the user to make sure it has
76+
if (await github.request('HEAD /installation/repositories', {per_page: 1}).catch(() => false)) {
77+
return;
78+
}
79+
7280
errors.push(getError('EGHNOPERMISSION', {owner, repo}));
7381
}
7482
} catch (error) {

‎test/verify.test.js

+42-15
Original file line numberDiff line numberDiff line change
@@ -401,23 +401,50 @@ test('Throw SemanticReleaseError for invalid repositoryUrl', async (t) => {
401401
t.is(error.code, 'EINVALIDGITHUBURL');
402402
});
403403

404-
test.serial("Throw SemanticReleaseError if token doesn't have the push permission on the repository", async (t) => {
405-
const owner = 'test_user';
406-
const repo = 'test_repo';
407-
const env = {GH_TOKEN: 'github_token'};
408-
const github = authenticate(env)
409-
.get(`/repos/${owner}/${repo}`)
410-
.reply(200, {permissions: {push: false}});
404+
test.serial(
405+
"Throw SemanticReleaseError if token doesn't have the push permission on the repository and it's not a Github installation token",
406+
async (t) => {
407+
const owner = 'test_user';
408+
const repo = 'test_repo';
409+
const env = {GH_TOKEN: 'github_token'};
410+
const github = authenticate(env)
411+
.get(`/repos/${owner}/${repo}`)
412+
.reply(200, {permissions: {push: false}})
413+
.head('/installation/repositories')
414+
.query({per_page: 1})
415+
.reply(403);
411416

412-
const [error, ...errors] = await t.throwsAsync(
413-
verify({}, {env, options: {repositoryUrl: `https://github.com/${owner}/${repo}.git`}, logger: t.context.logger})
414-
);
417+
const [error, ...errors] = await t.throwsAsync(
418+
verify({}, {env, options: {repositoryUrl: `https://github.com/${owner}/${repo}.git`}, logger: t.context.logger})
419+
);
415420

416-
t.is(errors.length, 0);
417-
t.is(error.name, 'SemanticReleaseError');
418-
t.is(error.code, 'EGHNOPERMISSION');
419-
t.true(github.isDone());
420-
});
421+
t.is(errors.length, 0);
422+
t.is(error.name, 'SemanticReleaseError');
423+
t.is(error.code, 'EGHNOPERMISSION');
424+
t.true(github.isDone());
425+
}
426+
);
427+
428+
test.serial(
429+
"Do not throw SemanticReleaseError if token doesn't have the push permission but it is a Github installation token",
430+
async (t) => {
431+
const owner = 'test_user';
432+
const repo = 'test_repo';
433+
const env = {GH_TOKEN: 'github_token'};
434+
const github = authenticate(env)
435+
.get(`/repos/${owner}/${repo}`)
436+
.reply(200, {permissions: {push: false}})
437+
.head('/installation/repositories')
438+
.query({per_page: 1})
439+
.reply(200);
440+
441+
await t.notThrowsAsync(
442+
verify({}, {env, options: {repositoryUrl: `https://github.com/${owner}/${repo}.git`}, logger: t.context.logger})
443+
);
444+
445+
t.true(github.isDone());
446+
}
447+
);
421448

422449
test.serial("Throw SemanticReleaseError if the repository doesn't exist", async (t) => {
423450
const owner = 'test_user';

0 commit comments

Comments
 (0)
Please sign in to comment.