Skip to content

Commit

Permalink
Merge pull request #87 from cla-assistant/refactor
Browse files Browse the repository at this point in the history
Refactor
  • Loading branch information
ibakshay authored May 16, 2021
2 parents 17c8033 + ff945e8 commit ba066db
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 80 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Change Log

## [v2.1.3-beta](https://github.com/cla-assistant/github-action/tree/v2.1.3-beta) (2021-05-16)
**Improvements:**
- refactoring [PullRequest#87](https://github.com/cla-assistant/github-action/pull/87)
## [v2.1.2-beta](https://github.com/cla-assistant/github-action/tree/v2.1.2-beta) (2021-03-20)
**New features:**
- Added optional flag for locking pull request [PullRequest#78](https://github.com/cla-assistant/github-action/pull/78) [Issue#77](https://github.com/cla-assistant/github-action/issues/77)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
- name: "CLA Assistant"
if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
# Beta Release
uses: cla-assistant/github-action@v2.1.2-beta
uses: cla-assistant/github-action@v2.1.3-beta
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# the below token should have repo scope and must be manually added by you in the repository's secret
Expand Down
2 changes: 1 addition & 1 deletion lib/main.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions src/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { CommittersDetails } from './interfaces'



export default async function getCommitters() {
export default async function getCommitters(): Promise<CommittersDetails[]> {
try {
let committers: CommittersDetails[] = []
let filteredCommitters: CommittersDetails[] = []
Expand Down Expand Up @@ -52,7 +52,7 @@ export default async function getCommitters() {
cursor: ''
})
response.repository.pullRequest.commits.edges.forEach(edge => {
let committer = extractUserFromCommit(edge.node.commit)
const committer = extractUserFromCommit(edge.node.commit)
let user = {
name: committer.login || committer.name,
id: committer.databaseId || '',
Expand All @@ -70,7 +70,7 @@ export default async function getCommitters() {
return filteredCommitters

} catch (e) {
throw new Error('graphql call to get the committers details failed:' + e)
throw new Error(`graphql call to get the committers details failed: ${e}`)
}

}
Expand Down
6 changes: 0 additions & 6 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,16 @@ export interface CommitterMap {
notSigned: CommittersDetails[],
unknown: CommittersDetails[]
}

export interface ReactedCommitterMap {
newSigned: CommittersDetails[],
onlyCommitters?: CommittersDetails[],
allSignedFlag: boolean
}

export interface CommentedCommitterMap {
newSigned: CommittersDetails[],
onlyCommitters?: CommittersDetails[],
allSignedFlag: boolean
}

export interface CommittersDetails {
name: string,
id: number,
Expand All @@ -26,12 +23,10 @@ export interface CommittersDetails {
body?: string,
repoId?: string
}

export interface LabelName {
current_name: string,
name: string
}

export interface CommittersCommentDetails {
name: string,
id: number,
Expand All @@ -40,7 +35,6 @@ export interface CommittersCommentDetails {
created_at: string,
updated_at: string
}

export interface ClafileContentAndSha {
claFileContent: any,
sha: string
Expand Down
4 changes: 3 additions & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ export async function run() {
try {
core.info(`CLA Assistant GitHub Action bot has started the process`)

// using a `string` true or false purposely as github action input cannot have a boolean value
/*
* using a `string` true or false purposely as github action input cannot have a boolean value
*/
if (context.payload.action === 'closed' && input.lockPullRequestAfterMerge() == 'true') {
return lockPullRequest()
} else {
Expand Down
25 changes: 12 additions & 13 deletions src/pullrequest/pullRequestComment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import signatureWithPRComment from './signatureComment'
import { commentContent } from './pullRequestCommentContent'
import {
CommitterMap,
ReactedCommitterMap,
CommittersDetails
} from '../interfaces'
import { getUseDcoFlag } from '../shared/getInputs'



export default async function prCommentSetup(signed: boolean, committerMap: CommitterMap, committers: CommittersDetails[]) {
export default async function prCommentSetup(committerMap: CommitterMap, committers: CommittersDetails[]) {
const signed = committerMap?.notSigned && committerMap?.notSigned.length === 0

try {
const claBotComment = await getComment()
if (!claBotComment && !signed) {
Expand All @@ -22,11 +23,9 @@ export default async function prCommentSetup(signed: boolean, committerMap: Comm
}

// reacted committers are contributors who have newly signed by posting the Pull Request comment
const reactedCommitters: ReactedCommitterMap = (await signatureWithPRComment(committerMap, committers)) as ReactedCommitterMap
if (reactedCommitters) {
if (reactedCommitters.onlyCommitters) {
const reactedCommitters = await signatureWithPRComment(committerMap, committers)
if (reactedCommitters?.onlyCommitters) {
reactedCommitters.allSignedFlag = prepareAllSignedCommitters(committerMap, reactedCommitters.onlyCommitters, committers)
}
}
committerMap = prepareCommiterMap(committerMap, reactedCommitters)
await updateComment(reactedCommitters.allSignedFlag, committerMap, claBotComment)
Expand All @@ -53,7 +52,7 @@ async function updateComment(signed: boolean, committerMap: CommitterMap, claBot
repo: context.repo.repo,
comment_id: claBotComment.id,
body: commentContent(signed, committerMap)
}).catch(error => { throw new Error(`Error occured when getting all the comments of the pull request: ${error.message}`) })
}).catch(error => { throw new Error(`Error occured when updating the pull request comment: ${error.message}`) })
}

async function getComment() {
Expand All @@ -66,7 +65,6 @@ async function getComment() {
return response.data.find(comment => comment.body.match(/.*DCO Assistant Lite bot.*/))
} else if (getUseDcoFlag() === 'false') {
return response.data.find(comment => comment.body.match(/.*CLA Assistant Lite bot.*/))

}
} catch (error) {
throw new Error(`Error occured when getting all the comments of the pull request: ${error.message}`)
Expand All @@ -88,12 +86,13 @@ function prepareCommiterMap(committerMap: CommitterMap, reactedCommitters) {
function prepareAllSignedCommitters(committerMap: CommitterMap, signedInPrCommitters: CommittersDetails[], committers: CommittersDetails[]): boolean {
let allSignedCommitters = [] as CommittersDetails[]
/*
1) already signed committers in the file 2) signed committers in the PR comment
*/
let ids = new Set(signedInPrCommitters.map(committer => committer.id))
* 1) already signed committers in the file 2) signed committers in the PR comment
*/
const ids = new Set(signedInPrCommitters.map(committer => committer.id))
allSignedCommitters = [...signedInPrCommitters, ...committerMap.signed!.filter(signedCommitter => !ids.has(signedCommitter.id))]

//checking if all the unsigned committers have reacted to the PR comment (this is needed for changing the content of the PR comment to "All committers have signed the CLA")
/*
* checking if all the unsigned committers have reacted to the PR comment (this is needed for changing the content of the PR comment to "All committers have signed the CLA")
*/
let allSignedFlag: boolean = committers.every(committer => allSignedCommitters.some(reactedCommitter => committer.id === reactedCommitter.id))
return allSignedFlag
}
Expand Down
34 changes: 15 additions & 19 deletions src/pullrequest/signatureComment.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { octokit } from '../octokit'
import { context } from '@actions/github'
import { CommitterMap, CommittersDetails, CommentedCommitterMap } from '../interfaces'
import { CommitterMap, CommittersDetails, ReactedCommitterMap } from '../interfaces'
import { getUseDcoFlag, getCustomPrSignComment } from '../shared/getInputs'

import * as core from '@actions/core'

export default async function signatureWithPRComment(committerMap: CommitterMap, committers) {
export default async function signatureWithPRComment(committerMap: CommitterMap, committers): Promise<ReactedCommitterMap> {

let repoId = context.payload.repository!.id
let commentedCommitterMap = {} as CommentedCommitterMap
let prResponse = await octokit.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
Expand Down Expand Up @@ -36,24 +35,21 @@ export default async function signatureWithPRComment(committerMap: CommitterMap,
for (var i = 0; i < filteredListOfPRComments.length; i++) {
delete filteredListOfPRComments[i].body
}
//checking if the reacted committers are not the signed committers(not in the storage file) and filtering only the unsigned committers
commentedCommitterMap.newSigned = filteredListOfPRComments.filter(commentedCommitter => committerMap.notSigned!.some(notSignedCommitter => commentedCommitter.id === notSignedCommitter.id))
// if (context.eventName === 'issue_comment') {
// //Do empty commit only when the contributor signs the CLA with the PR comment and then check if the comment is from the newsigned contributor
// if (input.getEmptyCommitFlag() == 'true') {
// if (commentedCommitterMap.newSigned.some(contributor => contributor.id === context?.payload?.comment?.user.id)) {
// await addEmptyCommit()
// }
// }
// }

// if (blockChainFlag == 'true' && commentedCommitterMap.newSigned) {
// await blockChainWebhook(commentedCommitterMap.newSigned)
// }
/*
*checking if the reacted committers are not the signed committers(not in the storage file) and filtering only the unsigned committers
*/
const newSigned = filteredListOfPRComments.filter(commentedCommitter => committerMap.notSigned!.some(notSignedCommitter => commentedCommitter.id === notSignedCommitter.id))

/*
* checking if the commented users are only the contributors who has committed in the same PR (This is needed for the PR Comment and changing the status to success when all the contributors has reacted to the PR)
*/
const onlyCommitters = committers.filter(committer => filteredListOfPRComments.some(commentedCommitter => committer.id == commentedCommitter.id))
const commentedCommitterMap: ReactedCommitterMap = {
newSigned,
onlyCommitters,
allSignedFlag: false
}

//checking if the commented users are only the contributors who has committed in the same PR (This is needed for the PR Comment and changing the status to success when all the contributors has reacted to the PR)
commentedCommitterMap.onlyCommitters = committers.filter(committer => filteredListOfPRComments.some(commentedCommitter => committer.id == commentedCommitter.id))
return commentedCommitterMap

}
Expand Down
52 changes: 16 additions & 36 deletions src/setupClaCheck.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,72 +17,52 @@ export async function setupClaCheck() {
core.setFailed('Please enter a personal access token as a environment variable in the CLA workflow file as described in the https://github.com/cla-assistant/github-action documentation')
return
}
let signed: boolean = false, response
let committers = await getCommitters() as CommittersDetails[]
committers = checkAllowList(committers) as CommittersDetails[]

try {
response = await getCLAFileContentandSHA(committers, committerMap) as ClafileContentAndSha
} catch (error) {
core.setFailed(error)
return
}
const claFileContent = response?.claFileContent
const sha: string = response?.sha
let committers = await getCommitters()
committers = checkAllowList(committers)

const { claFileContent, sha } = await getCLAFileContentandSHA(committers, committerMap) as ClafileContentAndSha

committerMap = prepareCommiterMap(committers, claFileContent) as CommitterMap

if (committerMap?.notSigned && committerMap?.notSigned.length === 0) {
signed = true
}
try {
const reactedCommitters: ReactedCommitterMap = (await prCommentSetup(signed, committerMap, committers)) as ReactedCommitterMap
const reactedCommitters = await prCommentSetup(committerMap, committers) as ReactedCommitterMap

if (signed) {
core.info(`All committers have signed the CLA`)
return reRunLastWorkFlowIfRequired()
}
if (reactedCommitters?.newSigned.length) {
/* pushing the recently signed contributors to the CLA Json File */
await updateFile(sha, claFileContent, reactedCommitters)
}
if (reactedCommitters?.allSignedFlag) {
core.info(`All contributors have signed the CLA`)
return reRunLastWorkFlowIfRequired()
}

if (committerMap?.notSigned === undefined || committerMap.notSigned.length === 0) {
core.info(`All contributors have signed the CLA`)
if (reactedCommitters?.allSignedFlag || (committerMap?.notSigned === undefined || committerMap.notSigned.length === 0)) {
core.info(`All contributors have signed the CLA 📝 ✅ `)
return reRunLastWorkFlowIfRequired()
} else {
core.setFailed(`committers of Pull Request number ${context.issue.number} have to sign the CLA`)
core.setFailed(`committers of Pull Request number ${context.issue.number} have to sign the CLA 📝`)
}

} catch (err) {
core.setFailed(`Could not update the JSON file: ${err.message}`)
}

}

async function getCLAFileContentandSHA(committers: CommittersDetails[], committerMap: CommitterMap): Promise<any> {
async function getCLAFileContentandSHA(committers: CommittersDetails[], committerMap: CommitterMap): Promise<void | ClafileContentAndSha> {
let result, claFileContentString, claFileContent, sha
try {
result = await getFileContent()
} catch (error) {
if (error.status === 404) {
await createClaFileAndPRComment(committers, committerMap)
return
return createClaFileAndPRComment(committers, committerMap)
} else {
core.setFailed(`Could not retrieve repository contents: ${error.message}. Status: ${error.status || 'unknown'}`)
}
}
sha = result?.data?.sha
claFileContentString = Buffer.from(result.data.content, 'base64').toString()
claFileContent = JSON.parse(claFileContentString)
return { claFileContent: claFileContent, sha: sha } as ClafileContentAndSha
return { claFileContent, sha }
}

async function createClaFileAndPRComment(committers: CommittersDetails[], committerMap: CommitterMap): Promise<any> {
const signed = false
async function createClaFileAndPRComment(committers: CommittersDetails[], committerMap: CommitterMap): Promise<void> {
committerMap.notSigned = committers
committerMap.signed = []
committers.map(committer => {
Expand All @@ -98,7 +78,7 @@ async function createClaFileAndPRComment(committers: CommittersDetails[], commit
await createFile(initialContentBinary).catch(error => core.setFailed(
`Error occurred when creating the signed contributors file: ${error.message || error}. Make sure the branch where signatures are stored is NOT protected.`
))
await prCommentSetup(signed, committerMap, committers)
await prCommentSetup(committerMap, committers)
throw new Error(`Committers of pull request ${context.issue.number} have to sign the CLA`)
}

Expand All @@ -107,10 +87,10 @@ function prepareCommiterMap(committers: CommittersDetails[], claFileContent): Co
let committerMap = getInitialCommittersMap()

committerMap.notSigned = committers.filter(
committer => !claFileContent.signedContributors.some(cla => committer.id === cla.id)
committer => !claFileContent?.signedContributors.some(cla => committer.id === cla.id)
)
committerMap.signed = committers.filter(committer =>
claFileContent.signedContributors.some(cla => committer.id === cla.id)
claFileContent?.signedContributors.some(cla => committer.id === cla.id)
)
committers.map(committer => {
if (!committer.id) {
Expand Down

0 comments on commit ba066db

Please sign in to comment.