Skip to content

Commit

Permalink
feat: check user belongs to pix
Browse files Browse the repository at this point in the history
  • Loading branch information
lionelB authored Dec 17, 2024
1 parent 3b1b25c commit 47036e9
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 6 deletions.
5 changes: 5 additions & 0 deletions build/controllers/github.js
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ async function processWebhook(
handleCloseRA = _handleCloseRA,
pullRequestRepository = _pullRequestRepository,
mergeQueue = _mergeQueue,
githubService = commonGithubService,
} = {},
) {
const eventName = request.headers['x-github-event'];
Expand All @@ -271,6 +272,10 @@ async function processWebhook(
await handleCloseRA(request);
}
if (request.payload.action === 'labeled' && request.payload.label.name === ':rocket: Ready to Merge') {
const belongsToPix = await githubService.checkUserBelongsToPix(request.payload.sender.login);
if (!belongsToPix) {
return `Ignoring ${request.payload.sender.login} label action`;
}
const repositoryName = request.payload.repository.full_name;
const isAllowedRepository = config.github.automerge.allowedRepositories.includes(repositoryName);
if (isAllowedRepository) {
Expand Down
9 changes: 9 additions & 0 deletions common/services/github.js
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,15 @@ const github = {
},
commentPullRequest,
addRADeploymentCheck,

async checkUserBelongsToPix(username) {
const octokit = _createOctokit();
const response = await octokit.request('GET /orgs/{org}/members/{username}', {
org: '1024pix',
username,
});
return response.status === 204;
},
};

export default github;
56 changes: 50 additions & 6 deletions test/unit/build/controllers/github_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,34 @@ Les variables d'environnement seront accessibles sur scalingo https://dashboard.
});

describe('when action is `labeled`', function () {
describe('when user is not allowed to trigger an action from a label', function () {
it('should do nothing', async function () {
sinon.stub(config.github, 'automerge').value({
allowedRepositories: ['1024pix/pix-sample-repo'],
});
sinon.stub(request, 'payload').value({
action: 'labeled',
number: 123,
label: { name: ':rocket: Ready to Merge' },
repository: { full_name: '1024pix/pix-sample-repo' },
sender: {
login: 'bob',
},
});
const mergeQueue = sinon.stub();
const githubService = { checkUserBelongsToPix: sinon.stub() };
githubService.checkUserBelongsToPix.resolves(false);
const pullRequestRepository = { save: sinon.stub() };

// when
await githubController.processWebhook(request, { mergeQueue, pullRequestRepository, githubService });

// then
expect(pullRequestRepository.save).to.have.not.been.called;
expect(mergeQueue).to.have.not.be.called;
});
});

describe('when label is Ready-to-merge', function () {
describe('when repo is allowed', function () {
it('should call pullRequestRepository.save() method', async function () {
Expand All @@ -161,13 +189,18 @@ Les variables d'environnement seront accessibles sur scalingo https://dashboard.
number: 123,
label: { name: ':rocket: Ready to Merge' },
repository: { full_name: '1024pix/pix-sample-repo' },
sender: {
login: 'ouiiiii',
},
});

const mergeQueue = sinon.stub();
const pullRequestRepository = { save: sinon.stub() };
const githubService = { checkUserBelongsToPix: sinon.stub() };
githubService.checkUserBelongsToPix.resolves(true);

// when
await githubController.processWebhook(request, { pullRequestRepository, mergeQueue });
await githubController.processWebhook(request, { githubService, pullRequestRepository, mergeQueue });

// then
expect(pullRequestRepository.save).to.be.calledOnceWithExactly({
Expand All @@ -190,13 +223,17 @@ Les variables d'environnement seront accessibles sur scalingo https://dashboard.
number: 123,
label: { name: ':rocket: Ready to Merge' },
repository: { full_name: '1024pix/pix-sample-repo' },
sender: {
login: 'Yolo',
},
});

const mergeQueue = sinon.stub();
const pullRequestRepository = { save: sinon.stub() };

const githubService = { checkUserBelongsToPix: sinon.stub() };
githubService.checkUserBelongsToPix.resolves(true);
// when
await githubController.processWebhook(request, { pullRequestRepository, mergeQueue });
await githubController.processWebhook(request, { githubService, pullRequestRepository, mergeQueue });

// then
expect(pullRequestRepository.save).to.have.not.been.called;
Expand Down Expand Up @@ -476,7 +513,6 @@ Les variables d'environnement seront accessibles sur scalingo https://dashboard.
it('should not create a Review App', async function () {
// given
sinon.stub(request.payload.pull_request, 'state').value('closed');

// when
const response = await githubController.handleRA(request);

Expand All @@ -494,7 +530,9 @@ Les variables d'environnement seront accessibles sur scalingo https://dashboard.
const deployReviewAppStub = sinon.stub();
const disableAutoDeployStub = sinon.stub();
const reviewAppExistsStub = sinon.stub().resolves(false);

const reviewAppRepositoryStub = {
create: sinon.stub(),
};
scalingoClientStub.getInstance = sinon.stub().returns({
deployUsingSCM: deployUsingSCMStub,
deployReviewApp: deployReviewAppStub,
Expand All @@ -508,7 +546,13 @@ Les variables d'environnement seront accessibles sur scalingo https://dashboard.
};

// when
await githubController.handleRA(request, scalingoClientStub, addMessageToPullRequestStub, githubServiceStub);
await githubController.handleRA(
request,
scalingoClientStub,
addMessageToPullRequestStub,
githubServiceStub,
reviewAppRepositoryStub,
);

// then

Expand Down
34 changes: 34 additions & 0 deletions test/unit/build/services/github_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -636,4 +636,38 @@ describe('Unit | Build | github-test', function () {
});
});
});

describe('#checkUserBelongsToPix', function () {
describe('when user belongs to Pix organization', function () {
it('returns true', async function () {
// given
const username = 'Gerrome';

const checkNock = nock('https://api.github.com').get(`/orgs/1024pix/members/${username}`).reply(204);

// when
const belongsToPix = await githubService.checkUserBelongsToPix(username);

// then
expect(belongsToPix).to.be.true;
expect(checkNock.isDone()).to.be.true;
});
});

describe('when user does not belong to Pix organization', function () {
it('returns false', async function () {
// given
const username = 'Gerrome';

const checkNock = nock('https://api.github.com').get(`/orgs/1024pix/members/${username}`).reply(404);

// when
const belongsToPix = await githubService.checkUserBelongsToPix(username);

// then
expect(belongsToPix).to.be.false;
expect(checkNock.isDone()).to.be.true;
});
});
});
});

0 comments on commit 47036e9

Please sign in to comment.