Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ inputs:
allowlist:
description: "users in the allow list don't have to sign the CLA document"
default: ""
exemptRepoOrgMembers:
description: "if `true`, members of the organization to which the repository belongs are automatically allowlisted"
default: false
remote-repository-name:
description: "provide the remote repository name where all the signatures should be stored"
remote-organization-name:
Expand Down
123 changes: 115 additions & 8 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,29 @@ exports.checkAllowList = checkAllowList;

"use strict";

var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
Expand All @@ -68,15 +91,26 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
const octokit_1 = __nccwpck_require__(3258);
const octokit = __importStar(__nccwpck_require__(3258));
const github_1 = __nccwpck_require__(5438);
const core = __importStar(__nccwpck_require__(2186));
function getCommitters() {
return __awaiter(this, void 0, void 0, function* () {
try {
let client = (octokit.isPersonalAccessTokenPresent()) ? octokit.getPATOctokit() : octokit.octokit;
let committers = [];
let filteredCommitters = [];
let response = yield octokit_1.octokit.graphql(`
let desiredSignatories = [];
let response = yield client.graphql(`
query($owner:String! $name:String! $number:Int! $cursor:String!){
organization(login: $owner) {
membersWithRole(first: 100) {
edges {
node {
login
}
}
}
}
repository(owner: $owner, name: $name) {
pullRequest(number: $number) {
commits(first: 100, after: $cursor) {
Expand All @@ -91,6 +125,11 @@ function getCommitters() {
id
databaseId
login
organizations(first: 100) {
nodes {
login
}
}
}
}
committer {
Expand All @@ -99,6 +138,11 @@ function getCommitters() {
id
databaseId
login
organizations(first: 100) {
nodes {
login
}
}
}
}
}
Expand All @@ -119,22 +163,45 @@ function getCommitters() {
cursor: ''
});
response.repository.pullRequest.commits.edges.forEach(edge => {
core.debug(JSON.stringify(response.organization, undefined, 2));
const committer = extractUserFromCommit(edge.node.commit);
let user = {
name: committer.login || committer.name,
id: committer.databaseId || '',
pullRequestNo: github_1.context.issue.number
pullRequestNo: github_1.context.issue.number,
orgLogins: committer.organizations.nodes.map(org => {
return org.login;
})
};
if (committers.length === 0 || committers.map((c) => {
return c.name;
}).indexOf(user.name) < 0) {
committers.push(user);
}
});
filteredCommitters = committers.filter((committer) => {
return committer.id !== 41898282;
desiredSignatories = committers.filter((committer) => {
if (committer.id === 41898282) { // Filter this one out.
return false;
}
if (core.getInput('exemptRepoOrgMembers')) {
// The `exemptRepoOrgMembers` input determines whether
// we automatically "allowlist" the members of the org
// owning the repository we are working in. If so, we
// can filter those committers here, thus allowing them
// to bypass the check informing them they need to sign
// the CLA.
let members = response.organization.membersWithRole.edges.map(edge => {
return edge.node.login;
});
core.debug("Filtering based on these members:");
core.debug(JSON.stringify(members, undefined, 2));
core.debug("Current committer name to check for filtering:");
return !members.includes(committer.name); // Negate so `includes()` filters out, not in.
}
return true;
});
return filteredCommitters;
core.debug(JSON.stringify(desiredSignatories, undefined, 2));
return desiredSignatories;
}
catch (e) {
throw new Error(`graphql call to get the committers details failed: ${e}`);
Expand Down Expand Up @@ -657,6 +724,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.commentContent = void 0;
const input = __importStar(__nccwpck_require__(3611));
const pr_sign_comment_1 = __nccwpck_require__(6718);
function commentContent(signed, committerMap) {
// using a `string` true or false purposely as github action input cannot have a boolean value
if (input.getUseDcoFlag() == 'true') {
Expand Down Expand Up @@ -715,7 +783,7 @@ function cla(signed, committerMap) {
let lineOne = (input.getCustomNotSignedPrComment() || `<br/>Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that $you sign our [Contributor License Agreement](${input.getPathToDocument()}) before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.<br/>`).replace('$you', you);
let text = `${lineOne}
- - -
${input.getCustomPrSignComment() || "I have read the CLA Document and I hereby sign the CLA"}
${(0, pr_sign_comment_1.getPrSignComment)()}
- - -
`;
if (committersCount > 1 && committerMap && committerMap.signed && committerMap.notSigned) {
Expand Down Expand Up @@ -1089,6 +1157,45 @@ const lockPullRequestAfterMerge = () => core.getInput('lock-pullrequest-aftermer
exports.lockPullRequestAfterMerge = lockPullRequestAfterMerge;


/***/ }),

/***/ 6718:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {

"use strict";

var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getPrSignComment = void 0;
const input = __importStar(__nccwpck_require__(3611));
function getPrSignComment() {
return input.getCustomPrSignComment() || "I have read the CLA Document and I hereby sign the CLA";
}
exports.getPrSignComment = getPrSignComment;


/***/ }),

/***/ 7351:
Expand Down
5 changes: 2 additions & 3 deletions src/checkAllowList.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import * as core from '@actions/core'
import { CommittersDetails } from './interfaces'

import * as _ from 'lodash'
import * as input from './shared/getInputs'



function isUserNotInAllowList(committer) {

const allowListPatterns: string[] = input.getAllowListItem().split(',')
Expand All @@ -23,4 +22,4 @@ function isUserNotInAllowList(committer) {
export function checkAllowList(committers: CommittersDetails[]): CommittersDetails[] {
const committersAfterAllowListCheck: CommittersDetails[] = committers.filter(committer => committer && !(isUserNotInAllowList !== undefined && isUserNotInAllowList(committer.name)))
return committersAfterAllowListCheck
}
}
66 changes: 54 additions & 12 deletions src/graphql.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
import { octokit } from './octokit'
import * as octokit from './octokit'
import { context } from '@actions/github'
import { CommittersDetails } from './interfaces'


import * as core from '@actions/core'

export default async function getCommitters(): Promise<CommittersDetails[]> {
try {
let client = (octokit.isPersonalAccessTokenPresent()) ? octokit.getPATOctokit() : octokit.octokit
let committers: CommittersDetails[] = []
let filteredCommitters: CommittersDetails[] = []
let response: any = await octokit.graphql(`
let desiredSignatories: CommittersDetails[] = []
let response: any = await client.graphql(`
query($owner:String! $name:String! $number:Int! $cursor:String!){
organization(login: $owner) {
membersWithRole(first: 100) {
edges {
node {
login
}
}
}
}
repository(owner: $owner, name: $name) {
pullRequest(number: $number) {
commits(first: 100, after: $cursor) {
Expand All @@ -24,6 +33,11 @@ export default async function getCommitters(): Promise<CommittersDetails[]> {
id
databaseId
login
organizations(first: 100) {
nodes {
login
}
}
}
}
committer {
Expand All @@ -32,6 +46,11 @@ export default async function getCommitters(): Promise<CommittersDetails[]> {
id
databaseId
login
organizations(first: 100) {
nodes {
login
}
}
}
}
}
Expand All @@ -52,26 +71,49 @@ export default async function getCommitters(): Promise<CommittersDetails[]> {
cursor: ''
})
response.repository.pullRequest.commits.edges.forEach(edge => {
core.debug(JSON.stringify(response.organization, undefined, 2))
const committer = extractUserFromCommit(edge.node.commit)
let user = {
name: committer.login || committer.name,
id: committer.databaseId || '',
pullRequestNo: context.issue.number
pullRequestNo: context.issue.number,
orgLogins: committer.organizations.nodes.map(org => {
return org.login
})
}
if (committers.length === 0 || committers.map((c) => {
return c.name
}).indexOf(user.name) < 0) {
committers.push(user)
}
})
filteredCommitters = committers.filter((committer) => {
return committer.id !== 41898282
})
return filteredCommitters
desiredSignatories = committers.filter((committer) => {
if (committer.id === 41898282) { // Filter this one out.
return false
}

if (core.getInput('exemptRepoOrgMembers')) {
// The `exemptRepoOrgMembers` input determines whether
// we automatically "allowlist" the members of the org
// owning the repository we are working in. If so, we
// can filter those committers here, thus allowing them
// to bypass the check informing them they need to sign
// the CLA.
let members = response.organization.membersWithRole.edges.map(edge => {
return edge.node.login
})
core.debug("Filtering based on these members:")
core.debug(JSON.stringify(members, undefined, 2))
core.debug("Current committer name to check for filtering:")
return ! members.includes(committer.name) // Negate so `includes()` filters out, not in.
}

return true
})
core.debug(JSON.stringify(desiredSignatories, undefined, 2))
return desiredSignatories
} catch (e) {
throw new Error(`graphql call to get the committers details failed: ${e}`)
}

}
const extractUserFromCommit = (commit) => commit.author.user || commit.committer.user || commit.author || commit.committer
const extractUserFromCommit = (commit) => commit.author.user || commit.committer.user || commit.author || commit.committer
3 changes: 2 additions & 1 deletion src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export interface CommittersDetails {
comment_id?: number,
body?: string,
repoId?: string
orgLogins?: string[]
}
export interface LabelName {
current_name: string,
Expand All @@ -38,4 +39,4 @@ export interface CommittersCommentDetails {
export interface ClafileContentAndSha {
claFileContent: any,
sha: string
}
}