diff --git a/action.yml b/action.yml
index f29a1a2a..887f9425 100644
--- a/action.yml
+++ b/action.yml
@@ -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:
diff --git a/dist/index.js b/dist/index.js
index 54d57014..4de3cea6 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -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) {
@@ -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) {
@@ -91,6 +125,11 @@ function getCommitters() {
id
databaseId
login
+ organizations(first: 100) {
+ nodes {
+ login
+ }
+ }
}
}
committer {
@@ -99,6 +138,11 @@ function getCommitters() {
id
databaseId
login
+ organizations(first: 100) {
+ nodes {
+ login
+ }
+ }
}
}
}
@@ -119,11 +163,15 @@ 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;
@@ -131,10 +179,29 @@ function getCommitters() {
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}`);
@@ -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') {
@@ -715,7 +783,7 @@ function cla(signed, committerMap) {
let lineOne = (input.getCustomNotSignedPrComment() || `
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.
`).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) {
@@ -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:
diff --git a/src/checkAllowList.ts b/src/checkAllowList.ts
index 9bfe77b0..01e72b06 100644
--- a/src/checkAllowList.ts
+++ b/src/checkAllowList.ts
@@ -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(',')
@@ -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
-}
\ No newline at end of file
+}
diff --git a/src/graphql.ts b/src/graphql.ts
index 21b8f253..fad326b5 100644
--- a/src/graphql.ts
+++ b/src/graphql.ts
@@ -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 {
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) {
@@ -24,6 +33,11 @@ export default async function getCommitters(): Promise {
id
databaseId
login
+ organizations(first: 100) {
+ nodes {
+ login
+ }
+ }
}
}
committer {
@@ -32,6 +46,11 @@ export default async function getCommitters(): Promise {
id
databaseId
login
+ organizations(first: 100) {
+ nodes {
+ login
+ }
+ }
}
}
}
@@ -52,11 +71,15 @@ export default async function getCommitters(): Promise {
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
@@ -64,14 +87,33 @@ export default async function getCommitters(): Promise {
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
\ No newline at end of file
+const extractUserFromCommit = (commit) => commit.author.user || commit.committer.user || commit.author || commit.committer
diff --git a/src/interfaces.ts b/src/interfaces.ts
index 07da19de..f4bb3eb2 100644
--- a/src/interfaces.ts
+++ b/src/interfaces.ts
@@ -22,6 +22,7 @@ export interface CommittersDetails {
comment_id?: number,
body?: string,
repoId?: string
+ orgLogins?: string[]
}
export interface LabelName {
current_name: string,
@@ -38,4 +39,4 @@ export interface CommittersCommentDetails {
export interface ClafileContentAndSha {
claFileContent: any,
sha: string
-}
\ No newline at end of file
+}