Skip to content

Commit

Permalink
Find linked issues across repos
Browse files Browse the repository at this point in the history
  • Loading branch information
celloward committed Feb 5, 2021
1 parent a1a1f98 commit 8ef8d85
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 17 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/move_from_comment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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/[email protected]
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 }}
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,27 @@ jobs:
uses: kin/[email protected]
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/[email protected]
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: { <payload> } }`

## 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.
29 changes: 19 additions & 10 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
});
}
Expand All @@ -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) {
Expand Down

0 comments on commit 8ef8d85

Please sign in to comment.