diff --git a/.github/workflows/move_from_comment.yml b/.github/workflows/move_from_comment.yml index 9801473..2dcccd8 100644 --- a/.github/workflows/move_from_comment.yml +++ b/.github/workflows/move_from_comment.yml @@ -16,11 +16,11 @@ jobs: uses: ./ id: linked-issues with: - access-token: "${{ secrets.GITHUB_TOKEN }}" + access-token: "${{ secrets.CROSS_REPO_TOKEN }}" - name: Move to Ready for QA uses: kin/gh-action-move-issues-to-column@v1.0 with: - access-token: "${{ secrets.GITHUB_TOKEN }}" + access-token: "${{ secrets.CROSS_REPO_TOKEN }}" project-name: "My Project" target-column: "In progress" issues: ${{ steps.linked-issues.outputs.issues }} diff --git a/README.md b/README.md index cf25aec..3a6fb07 100644 --- a/README.md +++ b/README.md @@ -25,27 +25,27 @@ jobs: uses: kin/gh-action-get-linked-issues@v1.0 id: linked-issues with: - # Required: personal access token with permissions to archive cards - access-token: "${{ secrets.GITHUB_TOKEN }}" + # Required: personal access token with permissions to archive cards. This needs to be set in Settings -> Secrets with a token that has permissions for all repos the issues are linked in for cross-repo functionality + access-token: "${{ secrets.CROSS_REPO_TOKEN }}" - name: Move Issues to Ready for Review Column uses: kin/gh-action-move-issue-to-column@1.0 with: - access-token: "${{ secrets.GITHUB_TOKEN }}" + access-token: "${{ secrets.CROSS_REPO_TOKEN }}" target-column: "Ready for Review" issues: ${{ steps.linked-issues.outputs.issues }} ``` ## Inputs -- `access-token`: Access token for repository. Use `"{{ secrets.GITHUB_TOKEN }}"` to prevent leaking secrets. +- `access-token`: Access token for repository. Using `"{{ secrets.GITHUB_TOKEN }}"` will work for same-repo use. For multi-repo use, this needs to be set in Settings -> Secrets with a token that has permissions for all repos the issues are linked to. Set it to a different variable name and use this variable instead of `GITHUB_TOKEN` (e.g. `${{ secrets.CROSS_REPO_TOKEN }}` - It is important to note that this action requires that the workflow trigger event is of the `pull_request` or `pull_request_target` type. ## Outputs - `issues`: A stringified array of [issue payloads](https://docs.github.com/en/free-pro-team@latest/rest/reference/issues#get-an-issue) with each issue payload formatted as `{ issue: { } }` ## Known Issues -This will not find issues that are linked through the UI, nor will it find issues linked in repos outside of the one the PR is in. There is a planned fix for both of these issues. +This will not find issues that are linked through the UI. A future release is planned to find these too. ## Contribution To cotnribute, please open an Issue on the action repo: https://github.com/kin/gh-action-autoarchive-issues-for-column to discuss bugs/modifications. diff --git a/index.js b/index.js index 6e8511d..e624709 100644 --- a/index.js +++ b/index.js @@ -12,19 +12,25 @@ try { const ownerName = repo.owner.login; const pullRequest = payload.pull_request; const targetIssue = typeof pullRequest === 'undefined' ? payload.issue : pullRequest; - - function linkedIssueNumbersFor(targetIssue) { + const linkingKeywords = ["close", "closes", "closed", "resolve", "resolves", "resolved", "fix", "fixes", "fixed"]; + const linkGroup = `(?:(${linkingKeywords.join('|')}))`; + + function parseLinkedIssues(matchingStrings) { + return matchingStrings.map(item => item.split(/\s|#/)).map(thing => thing.filter(item => item.match(new RegExp(`[^${linkGroup}]`, 'i'))).flatMap(item => item.split('/')).reverse()); + } + + function linkedIssueDataFor(targetIssue) { const body = targetIssue.body; - const linkRegexp = /(?:(close|closes|closed|resolve|resolves|resolved|fix|fixes|fixed)) #\d+/gi; + const linkRegexp = new RegExp(`${linkGroup} (?:(\\S+\/\\S+))?#(\\d+)`, "gi"); const linkMatches = body.match(linkRegexp); - const linkedIssueNumbers = linkMatches ? linkMatches.map(item => parseInt(item.replace(/[^0-9]/g, ""))) : []; - return linkedIssueNumbers; + const linkedIssueData = linkMatches ? parseLinkedIssues(linkMatches): []; + return linkedIssueData; } - async function getIssue(number) { + async function getIssue(number, repo = repoName, owner = ownerName) { return octokit.issues.get({ - owner: ownerName, - repo: repoName, + owner: owner, + repo: repo, issue_number: number, }); } @@ -36,14 +42,17 @@ try { return; } - const linkedIssueNumbers = linkedIssueNumbersFor(targetIssue); - const issuesRaw = await Promise.all(linkedIssueNumbers.map(getIssue)); + const linkedIssueData = linkedIssueDataFor(targetIssue); + const issuesRaw = await Promise.all(linkedIssueData.map(issueData => getIssue(...issueData))); const issueData = issuesRaw.map(i => i.data); const issues = issueData.map(data => { var issueObject = { issue: data }; return issueObject; }); core.info(`Returning ${issues.length} issues`); + console.log('Linked issue data: ', linkedIssueData); + console.log('Issue Data: ', issueData); + console.log('Returned issues', issues); core.setOutput("issues", JSON.stringify(issues), undefined, 2); } catch (error) {