diff --git a/README.md b/README.md index db72fb2..c4cffd9 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,17 @@ JIRA_URL=unicode-org.atlassian.net JIRA_USERNAME=foo@example.com JIRA_PASSWORD=bar +# List of issue statuses that would be accepted +JIRA_STATUS_CHECK=TRUE +JIRA_APPROVED_STATUSES="Approved, Progress" + +# Search for the Jira Issue ID in commit message +SEARCH_JIRA_ISSUE_IN_COMMIT=TRUE + +# Optional variable to allow multiple commits in the same PR +ALLOW_MANY_COMMITS=TRUE + + # URL prefix used for hyperlinks. URL_PREFIX=http://localhost:3000 @@ -64,6 +75,10 @@ COMMITTER_EMAIL=foo@example.com # Secret for the cookie session, used to store the user's GitHub access token in a cookie. COOKIE_SECRET=xxxxxxxxxx + +# Hostname of your GitHub instance +GITHUB_URL=https://github.mycompany.com/api/v3 + # Optional list of repos to disable status updates (only enable force-push checking) DO_NOT_TOUCH_REPOS=org/repo1,org/repo2 diff --git a/app.js b/app.js index 1fbef16..53618b1 100644 --- a/app.js +++ b/app.js @@ -74,11 +74,11 @@ async function getJiraInfo(pullRequest) { const isMaintMerge = (pullRequest.base.ref === "master" && pullRequest.head.ref.match(/^maint\//) && pullRequest.base.repo.full_name == pullRequest.head.repo.full_name); + let jiraApprovedStatuses = process.env.JIRA_APPROVED_STATUSES || "Accepted, Reviewing, Review Feedback" + const jiraApprovedStatusesArray = jiraApprovedStatuses.split(",").map(status => status.trim()) // Check Jira ticket for validity - if (jiraStatus !== "Accepted" && - jiraStatus !== "Reviewing" && - jiraStatus !== "Review Feedback") { + if (!jiraApprovedStatuses.includes(jiraStatus) && process.env.JIRA_STATUS_CHECK === "TRUE") { return { issueKey, jiraStatus, @@ -93,35 +93,38 @@ async function getJiraInfo(pullRequest) { } // Check for consistency with the commit messages - for (const commitInfo of commits) { - const commitIssueKey = parseMessage(commitInfo.commit.message); - if (commitIssueKey === null) { - return { - issueKey, - jiraStatus, - numCommits, - isMaintMerge, - prFlags, - pass: false, - description: "Commit message for " + commitInfo.sha.substr(0, 7) + " fails validation", - badCommit: commitInfo - }; - } else if (commitIssueKey !== issueKey && !prFlags["DISABLE_JIRA_ISSUE_MATCH"] && !isMaintMerge) { - return { - issueKey, - jiraStatus, - numCommits, - isMaintMerge, - prFlags, - pass: false, - description: "Commit " + commitInfo.sha.substr(0, 7) + " is for " + commitIssueKey + ", but the PR is for " + issueKey, - extendedDescription: "Please fix your commit message to have the same ticket number as the pull request. If the inconsistency is intentional, you can disable this warning with DISABLE_JIRA_ISSUE_MATCH=true in the PR description.", - badCommit: commitInfo - }; + if(process.env.SEARCH_JIRA_ISSUE_IN_COMMIT === "TRUE") { + for (const commitInfo of commits) { + const commitIssueKey = parseMessage(commitInfo.commit.message); + if (commitIssueKey === null) { + return { + issueKey, + jiraStatus, + numCommits, + isMaintMerge, + prFlags, + pass: false, + description: "Commit message for " + commitInfo.sha.substr(0, 7) + " fails validation", + badCommit: commitInfo + }; + } else if (commitIssueKey !== issueKey && !prFlags["DISABLE_JIRA_ISSUE_MATCH"] && !isMaintMerge) { + return { + issueKey, + jiraStatus, + numCommits, + isMaintMerge, + prFlags, + pass: false, + description: "Commit " + commitInfo.sha.substr(0, 7) + " is for " + commitIssueKey + ", but the PR is for " + issueKey, + extendedDescription: "Please fix your commit message to have the same ticket number as the pull request. If the inconsistency is intentional, you can disable this warning with DISABLE_JIRA_ISSUE_MATCH=true in the PR description.", + badCommit: commitInfo + }; + } } } - // Since we can't easilly check more than 100 commits, reject PRs with more than 100 commits + + // Since we can't easily check more than 100 commits, reject PRs with more than 100 commits if (commits.length === 100) { return { issueKey, @@ -228,8 +231,12 @@ async function touch(pullRequest, jiraInfo) { const multiCommitMessage = (jiraInfo.numCommits === 0) ? "No commits found on PR" : (jiraInfo.numCommits === 1) ? "This PR includes exactly 1 commit!" : "This PR has " + jiraInfo.numCommits + " commits" + (multiCommitPass ? "" : "; consider squashing:"); const promises = [ github.createStatus("jira-ticket", pullRequest, jiraInfo.pass, url, jiraInfo.description), - github.createStatus("single-commit", pullRequest, multiCommitPass, url, multiCommitMessage) ]; + + if (!(process.env.ALLOW_MANY_COMMITS === "TRUE")) { + promises.push(github.createStatus("single-commit", pullRequest, multiCommitPass, undefined, multiCommitMessage)) + } + if (jiraInfo.isMaintMerge) { promises.push(github.createStatus("maint-merge", pullRequest, false, undefined, "Reminder: use a MERGE COMMIT and new ticket in the message.")); } diff --git a/src/github-status.js b/src/github-status.js index f0de679..fbd28a9 100644 --- a/src/github-status.js +++ b/src/github-status.js @@ -15,8 +15,17 @@ async function getAuthenticatedOctokitClient(token) { throw new Error("Need either GITHUB_TOKEN or GITHUB_APP_ID"); } } + + let github_url; + if (process.env.GITHUB_URL) { + github_url = process.env.GITHUB_URL; + } else { + github_url = "https://api.github.com"; + } + return new Octokit({ - auth: token + auth: token, + baseUrl: github_url }); }