Skip to content
This repository has been archived by the owner on Dec 1, 2023. It is now read-only.

Commit

Permalink
Merge pull request #5 from delivered/muliple-card-urls
Browse files Browse the repository at this point in the history
Muliple card urls
  • Loading branch information
Brian Henry authored Mar 16, 2020
2 parents 68a19e5 + 04621d9 commit 7720730
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 35 deletions.
25 changes: 22 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
# Attach to Trello Card action

The purpose of this action is to enable attaching a pull request to a Trello card, from within the PR body. This is best used with the Trello [Github Power-Up](https://trello.com/power-ups/55a5d916446f517774210004) added to your Trello Boards. With that enabled, this effectively enables the "Attach Pull Request" action of the Power-Up, but from the Github side (and via a quick URL copy-paste instead of clicking through menus).
The purpose of this action is to enable attaching a pull request to Trello cards, from within the PR body. This is best used with the Trello [Github Power-Up](https://trello.com/power-ups/55a5d916446f517774210004) added to your Trello Boards. With that enabled, this effectively enables the "Attach Pull Request" action of the Power-Up, but from the Github side (and via a quick URL copy-paste instead of clicking through menus).

The action looks for a Trello card URL at the start of a Pull Request description. If found, it will add the PR URL as an attachment to Trello.
The action looks for Trello card URLs at the start of a Pull Request description. If found, it will add the PR URL as an attachment to each specified card in Trello.

Optionally, this can be configured to also attach a (redundant) PR comment with link/name, similar to what the Trello Power-up will do, for use cases requiring that.
Optionally, this can be configured to also attach (redundant) PR comments with card links/names, similar to what the Trello Power-up will do, for use cases requiring that.

## Link-Finding
URLs need to each be on own line (leading/trailing whitespace and extra blank lines don't matter), and be at top of PR body. URLs embedded in other text are ignored, as are URLs after descriptive (i.e., non-link) text starts.

So, for :
```text
https://trello.com/c/aaaaaaaa
https://trello.com/c/bbbbbbbbb
This PR impl's the above 2 features. These work similarly to feature https://trello.com/c/ccccccccc.
The below is a random trello url put in this body, for some reason:
https://trello.com/c/dddddddd
```
only cards `aaaaaaaa` and `bbbbbbbbb` will have the PR attached.


## Events
Expand Down Expand Up @@ -46,3 +60,8 @@ jobs:
# repo-token: ${{ secrets.GITHUB_TOKEN }}
```

## Development Notes
# Incrementing version
1. Update version in package.json (format should be `X.X.X`, per semver)
1. Commit/push changes
1. Create release (and publish to marketplace) - use 'v'-prepended format for new tag and release name
83 changes: 52 additions & 31 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,33 @@ const addPrComment = async (body) => {
};


const extractTrelloCardId = (prBody) => {
core.debug(`pr body: ${prBody}`);
// to stop looking when we get to what looks like pr description, use stopOnNonLink true. to allow interspersed lines of
// yada yada yada b/w Trello links, use false.
const extractTrelloCardIds = (prBody, stopOnNonLink = true) => {
core.debug(`prBody: ${util.inspect(prBody)}`);

//find 1st instance of trello card url - must be 1st thing in PR
const matches = /^\s*https\:\/\/trello\.com\/c\/(\w+)/.exec(prBody);
const cardId = matches && matches[1];
core.debug(`card id = ${cardId}`);

return cardId;
// browsers submit textareas with \r\n line breaks on all platforms
const browserEol = '\r\n';
// requires that link be alone own line, and allows leading/trailing whitespace
const linkRegex = /^\s*(https\:\/\/trello\.com\/c\/(\w+)\/\S+)?\s*$/;

const cardIds = [];
const lines = prBody.split(browserEol);

//loop and gather up cardIds, skipping blank lines. stopOnNonLink == true will bust out when we're out of link-only territory.
for(const line of lines) {
const matches = linkRegex.exec(line);
if(matches) {
if(matches[2]) {
core.debug(`found id ${matches[2]}`);
cardIds.push(matches[2]);
}
} else if(stopOnNonLink) {
core.debug('matched something non-blank/link. stopping search');
break;
}
};
return cardIds;
}

const commentsContainsTrelloLink = async (cardId) => {
Expand All @@ -111,36 +129,39 @@ const buildTrelloLinkComment = async (cardId) => {
return;
}

const cardId = extractTrelloCardId(evthookPayload.pull_request.body);
const prUrl = evthookPayload.pull_request.html_url;
const cardIds = extractTrelloCardIds(evthookPayload.pull_request.body);

if(cardId) {
let extantAttachments;
if(cardIds && cardIds.length > 0) {
for(const cardId of cardIds) {
let extantAttachments;

core.debug(`card url for ${cardId} specified in pr comment.`);
extantAttachments = await getCardAttachments(cardId);

//make sure not already attached
if(extantAttachments == null || !extantAttachments.some(it => it.url === prUrl)) {
const createdAttachment = await createCardAttachment(cardId, prUrl);
core.info(`created trello attachment.`);
core.debug(util.inspect(createdAttachment));
core.info(`card url for ${cardId} specified in pr.`);
extantAttachments = await getCardAttachments(cardId);

//make sure not already attached
if(extantAttachments == null || !extantAttachments.some(it => it.url === prUrl)) {
const createdAttachment = await createCardAttachment(cardId, prUrl);
core.info(`created trello attachment for card ${cardId}.`);
core.debug(util.inspect(createdAttachment));

// BRH NOTE actually, the power-up doesn't check if it previously added comment, so check is maybe superfluous
if(shouldAddPrComment && !await commentsContainsTrelloLink(cardId)) {
core.debug('adding pr comment');
const newComment = await buildTrelloLinkComment(cardId)

//comments as 'github actions' bot, at least when using token automatically generated for GH workflows
await addPrComment(newComment);
// BRH NOTE actually, the power-up doesn't check if it previously added comment, so this doesn't exactly match
// its fxnality.
if(shouldAddPrComment && !await commentsContainsTrelloLink(cardId)) {
core.debug(`adding pr comment for card ${cardId}.`);
const newComment = await buildTrelloLinkComment(cardId)

//comments as 'github actions' bot, at least when using token automatically generated for GH workflows
await addPrComment(newComment);
} else {
core.info(`pr comment already present or unwanted for card ${cardId} - skipped comment add.`);
}
} else {
core.info('pr comment already present or unwanted - skipped comment add.');
core.info(`trello attachment for card ${cardId} already exists - skipped attachment create.`);
}
} else {
core.info('trello attachement already exists - skipped create.');
}
};
} else {
core.info(`no card url in pr comment. nothing to do.`);
core.info(`no card urls in pr comment. nothing to do.`);
}
} catch (error) {
core.error(util.inspect(error));
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "attach-to-trello-card-action",
"version": "1.0.0",
"version": "2.0.0",
"description": "Github Action: Add attachment to a given Trello card URL (e.g., pull request)",
"main": "index.js",
"scripts": {
Expand Down

0 comments on commit 7720730

Please sign in to comment.