diff --git a/.github/workflows/trello.yml b/.github/workflows/trello.yml deleted file mode 100644 index 2339069..0000000 --- a/.github/workflows/trello.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: trello -on: - pull_request: - types: - [ - opened, - edited, - closed, - reopened, - ready_for_review, - converted_to_draft, - review_requested, - review_request_removed, - ] - pull_request_review: - issue_comment: - types: [created, edited] -jobs: - test: - runs-on: ubuntu-latest - steps: - - uses: rematocorp/trello-integration-action@main - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - trello-api-key: ${{ secrets.TRELLO_API_KEY }} - trello-auth-token: ${{ secrets.TRELLO_AUTH_TOKEN }} - trello-list-id-pr-draft: 6092503e9a89e4752911fce7 - trello-list-id-pr-open: 60b4ca9140982c5b39c314a7 - trello-list-id-pr-closed: 60925045a40b6a17a17293de - trello-switch-members-in-review: true diff --git a/src/actions/api/trello.ts b/src/actions/api/trello.ts index 4077d67..58aae51 100644 --- a/src/actions/api/trello.ts +++ b/src/actions/api/trello.ts @@ -1,6 +1,6 @@ import axios from 'axios' import * as core from '@actions/core' -import { BoardLabel, Card } from '../../types' +import { BoardLabel, Card, CardActions } from '../../types' import logger from '../utils/logger' const trelloApiKey = core.getInput('trello-api-key', { required: true }) @@ -26,6 +26,12 @@ export async function getCardInfo(cardId: string): Promise { return response?.data } +export async function getCardActions(cardId: string): Promise { + const response = await makeRequest('get', `https://api.trello.com/1/cards/${cardId}/actions`) + + return response?.data +} + export async function getMemberInfo(username?: string): Promise<{ id: string; organizations: { name: string }[] }> { const response = await makeRequest('get', `https://api.trello.com/1/members/${username}`, { organizations: 'all', diff --git a/src/actions/getCardIds.test.ts b/src/actions/getCardIds.test.ts index 168931b..a480e16 100644 --- a/src/actions/getCardIds.test.ts +++ b/src/actions/getCardIds.test.ts @@ -1,6 +1,6 @@ import { setFailed } from '@actions/core' import { getBranchName, getPullRequest, getPullRequestComments, updatePullRequestBody, getCommits } from './api/github' -import { createCard, moveCardToList, searchTrelloCards, getCardInfo } from './api/trello' +import { createCard, moveCardToList, searchTrelloCards, getCardInfo, getCardActions } from './api/trello' import getCardIds from './getCardIds' jest.mock('@actions/core') @@ -15,9 +15,14 @@ const getBranchNameMock = getBranchName as jest.Mock const searchTrelloCardsMock = searchTrelloCards as jest.Mock const createCardMock = createCard as jest.Mock const getCardInfoMock = getCardInfo as jest.Mock +const getCardActionsMock = getCardActions as jest.Mock const pr = { number: 0, state: 'open', title: 'Title' } +beforeEach(() => { + getCardActionsMock.mockResolvedValue([]) +}) + it('fails the job when no cards found and githubRequireTrelloCard is enabled', async () => { await getCardIds({ githubRequireTrelloCard: true }, pr) @@ -155,12 +160,21 @@ describe('Finding cards', () => { ]) getCardInfoMock.mockImplementation((cardId) => { if (cardId === '0') { - return { idShort: 4, shortLink: 'card-0', actions: [] } + return { idShort: 4, shortLink: 'card-0' } } else if (cardId === '1') { - return { idShort: 3, shortLink: 'card-1', actions: [{ data: { card: { idShort: 1 } } }] } + return { idShort: 3, shortLink: 'card-1' } + } else if (cardId === '2') { + return { idShort: 2, shortLink: 'card-2' } + } + }) + getCardActionsMock.mockImplementation((cardId) => { + if (cardId === '1') { + return [{ data: { card: { idShort: 1 } } }] } else if (cardId === '2') { - return { idShort: 2, shortLink: 'card-2', actions: [{ data: { card: { idShort: 2 } } }] } + return [{ data: { card: { idShort: 2 } } }] } + + return [] }) const cardIds = await getCardIds({ ...conf, githubIncludePrBranchName: true }, pr) @@ -218,19 +232,11 @@ describe('Finding cards', () => { searchTrelloCardsMock .mockResolvedValueOnce([]) .mockResolvedValueOnce([{ id: 'incorrect-card', shortLink: '1-incorrect-card', idShort: 1 }]) - getCardInfoMock.mockImplementation((id) => { + getCardActionsMock.mockImplementation((id) => { if (id === 'card') { - return { - idShort: 2, - shortLink: 'card', - actions: [{ data: { card: { idShort: 1 } } }], - } + return [{ data: { card: { idShort: 1 } } }] } else if (id === 'incorrect-card') { - return { - idShort: 1, - shortLink: '1-incorrect-card', - actions: [], - } + return [] } }) @@ -242,8 +248,18 @@ describe('Finding cards', () => { expect(cardIds).toEqual(['card']) }) - it('ignores closed cards', async () => { - // TODO + it('ignores closed card when looking card with short ID', async () => { + getBranchNameMock.mockResolvedValueOnce('1-nan') + searchTrelloCardsMock + .mockResolvedValueOnce([]) + .mockResolvedValueOnce([]) + .mockResolvedValueOnce([ + { shortLink: 'card-1', idShort: 1, dateLastActivity: '2023-01-01', closed: true }, + ]) + + const cardIds = await getCardIds({ ...conf, githubIncludePrBranchName: true }, pr) + + expect(cardIds).toEqual([]) }) it('ignores branch names that looks similar to Trello card name', async () => { diff --git a/src/actions/getCardIds.ts b/src/actions/getCardIds.ts index e014be5..aba069e 100644 --- a/src/actions/getCardIds.ts +++ b/src/actions/getCardIds.ts @@ -1,7 +1,7 @@ import { setFailed } from '@actions/core' import { Conf, PR, PRHead } from '../types' import { getBranchName, getCommits, getPullRequest, getPullRequestComments, updatePullRequestBody } from './api/github' -import { createCard, getCardInfo, searchTrelloCards } from './api/trello' +import { createCard, getCardActions, getCardInfo, searchTrelloCards } from './api/trello' import matchCardIds from './utils/matchCardIds' import isPullRequestInDraft from './utils/isPullRequestInDraft' import logger from './utils/logger' @@ -137,11 +137,11 @@ async function getMultipleCardIdsFromBranchName(conf: Conf, branchName: string) } } -async function isCardAlreadyLinked(cardIds: string[], shortId: string): Promise { +async function isCardAlreadyLinked(cardIds: string[], shortId: string) { return cardIds.some(async (cardId) => { - const card = await getCardInfo(cardId) + const cardActions = await getCardActions(cardId) - return card.actions?.some((action) => action.data.card.idShort === parseInt(shortId)) ?? false + return cardActions.some((action) => action.data.card.idShort === parseInt(shortId)) }) } @@ -168,13 +168,18 @@ async function getTrelloCardByTitle(title: string, shortId: string) { results ?.filter((card) => !card.closed) .sort((a, b) => new Date(b.dateLastActivity).getTime() - new Date(a.dateLastActivity).getTime()) - .map((card) => getCardInfo(card.id)), + .map(async (card) => { + const cardInfo = await getCardInfo(card.id) + const cardActions = await getCardActions(card.id) + + return { ...cardInfo, actions: cardActions } + }), ) return cards.find( (card) => card.idShort === parseInt(shortId) || - (card.actions?.some((action) => action.data.card.idShort === parseInt(shortId)) ?? false), + card.actions.some((action) => action.data.card.idShort === parseInt(shortId)), )?.shortLink } diff --git a/src/types.ts b/src/types.ts index d2fe509..392d7b2 100644 --- a/src/types.ts +++ b/src/types.ts @@ -44,11 +44,12 @@ export type Card = { url: string shortUrl: string shortLink: string - actions?: { - data: { - card: { - idShort: number - } - } - }[] } + +export type CardActions = { + data: { + card: { + idShort: number + } + } +}[]