Skip to content

Commit

Permalink
Add 'column-{allow/deny}-list' optional inputs
Browse files Browse the repository at this point in the history
This adds the `column-allow-list` and `column-deny-list` optional
inputs. If neither is set the behavior of the action is identical to
before.

`column-allow-list` may be set to a string or list of strings
(separated by comma or newline character) which specifes columns that
the action may move cards from only. That is, if `column-deny-list` is
set to `todo,wip` then only cards in `todo` and `wip` can be moved by
the job. If unset all cards in all columns may be moved (assuming
`column-deny-list` is also unset).

 `column-deny-list` may also be set to a string or list of strings
(again, separated by a comma or newline character) which specifies
columns that the action may never move cards. That is, if
`column-deny-list` is set to `todo,wip` then cards in `todo` and `wip`
will not be moved by the job. If unset all the cards in all the columns
may be moved (assuming `column-allow-list` is also unset).
from.

This addresses:
alex-page#41.

Tests have been added to verify previous behavior is preserved and
these new inputs function as intended.
  • Loading branch information
BobbyRBruce committed Aug 23, 2023
1 parent 7ffb872 commit f1c2861
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 10 deletions.
10 changes: 10 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@ inputs:
column:
description: 'The name of the column to move the issue or pull request to'
required: true
column-allow-list:
type: string
description: 'Columns which cards are allowed to be moved from. If not specified, all columns are allowed. Multiple columns separated by newline or comma.'
required: false
default: ''
column-deny-list:
type: string
description: 'Columns which cards are not allowed to be moved from. If not specified, no columns are denied. Multiple columns separated by newline or comma.'
required: false
default: ''
action:
description: |
Can be `update`, `delete` or `archive` or `add`. This determines the type of the action
Expand Down
17 changes: 16 additions & 1 deletion src/generate-mutation-query.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
* @param {string} projectName - The user inputted project name
* @param {string} columnName - The user inputted column name
* @param {string} contentId - The id of the issue or pull request
* @param {list} columnAllowList - List of columns allowed to move from. If unset, any.
* @param {list} columnDenyList - List of columns to deny movement from. If unset, none.
* @param {"delete"|"archive"|"update"} action - the action to be performed on the card
*/
// if this is important, we will need to refactor the function
// eslint-disable-next-line max-params
const generateMutationQuery = (data, projectName, columnName, contentId, action) => {
const generateMutationQuery = (data, projectName, columnName, contentId, columnAllowList, columnDenyList, action) => {
// All the projects found in organisation and repositories
const repoProjects = data.repository.projects.nodes || [];
const orgProjects = (data.repository.owner &&
Expand Down Expand Up @@ -50,10 +52,23 @@ const generateMutationQuery = (data, projectName, columnName, contentId, action)
for (const card of currentLocation) {
cardLocations[card.project.id].cardId = card.id;
cardLocations[card.project.id].isArchived = card.isArchived;
cardLocations[card.project.id].curColumnName = (card.column && card.column.name) ? card.column.name : undefined;
}

// If the card already exists in the project move it otherwise add a new card
const mutations = Object.keys(cardLocations).map(mutation => {
// If the column allow list is specified, and this card's current
// column is not in it, skip.
if (cardLocations[mutation].curColumnName && columnAllowList && columnAllowList.length && !columnAllowList.includes(cardLocations[mutation].curColumnName)) {
return undefined;
}

// If the column deny list is specified, and this card's current column
// is in it, skip.
if (cardLocations[mutation].curColumnName && columnDenyList && columnDenyList.length && columnDenyList.includes(cardLocations[mutation].curColumnName)) {
return undefined;
}

if (action === 'update') {
// Othervise keep default procedure
return cardLocations[mutation].cardId ?
Expand Down
4 changes: 3 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const generateMutationQuery = require('./generate-mutation-query');
const token = core.getInput('repo-token');
const project = core.getInput('project');
const column = core.getInput('column');
const columnAllowList = core.getInput('column-allow-list').split("/,|\n/").filter(x => x !== "");
const columnDenyList = core.getInput('column-deny-list').split("/,|\n/").filter(x => x !== "");
const action = core.getInput('action') || 'update';

// Get data from the current action
Expand All @@ -28,7 +30,7 @@ const generateMutationQuery = require('./generate-mutation-query');
core.debug(JSON.stringify(resource));

// A list of columns that line up with the user entered project and column
const mutationQueries = generateMutationQuery(resource, project, column, nodeId, action);
const mutationQueries = generateMutationQuery(resource, project, column, nodeId, columnAllowList, columnDenyList, action);
if ((action === 'delete' || action === 'archive' || action === 'add') && mutationQueries.length === 0) {
console.log('✅ There is nothing to do with card');
return;
Expand Down
83 changes: 75 additions & 8 deletions tests/generate-mutation-query.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ const generateMutationQuery = require('../src/generate-mutation-query');
const project = 'Backlog';
const column = 'To do';
const nodeId = 'MDU6SXNzdWU1ODc4NzU1Mjk=';
const columnAllowList = [];
const columnDenyList = [];

const moveData = {
projectCards: {
Expand All @@ -14,6 +16,9 @@ const moveData = {
project: {
name: project,
id: 'MDc6UHJvamVjdDQwNzU5MDI='
},
column: {
name: 'Hotbox'
}
}
]
Expand All @@ -30,6 +35,10 @@ const moveData = {
id: 'MDEzOlByb2plY3RDb2x1bW44NDU0MzQ6',
name: 'Icebox'
},
{
id: 'MDEzOlByb2plY3RDb2x1bW44NDU0MzQ7',
name: 'Hotbox'
},
{
id: 'MDEzOlByb2plY3RDb2x1bW44NDU0MzQ5',
name: column
Expand All @@ -48,7 +57,7 @@ const moveData = {
};

test('generateMutationQuery move the card when in the correct project and wrong column', t => {
t.deepEqual(generateMutationQuery(moveData, project, column, nodeId, 'update'), [
t.deepEqual(generateMutationQuery(moveData, project, column, nodeId, columnAllowList, columnDenyList, 'update'), [
`mutation {
moveProjectCard( input: {
cardId: "MDExOlByb2plY3RDYXJkMzUxNzI2MjM=",
Expand All @@ -58,7 +67,7 @@ test('generateMutationQuery move the card when in the correct project and wrong
});

test('generateMutationQuery delete the card when it is in the project already', t => {
t.deepEqual(generateMutationQuery(moveData, project, column, nodeId, 'delete'), [
t.deepEqual(generateMutationQuery(moveData, project, column, nodeId, columnAllowList, columnDenyList, 'delete'), [
`mutation {
deleteProjectCard( input: {
cardId: "MDExOlByb2plY3RDYXJkMzUxNzI2MjM="
Expand All @@ -67,7 +76,65 @@ test('generateMutationQuery delete the card when it is in the project already',
});

test('generateMutationQuery skip issue addition when the card already exists in the project', t => {
t.deepEqual(generateMutationQuery(moveData, project, column, nodeId, 'add'), []);
t.deepEqual(generateMutationQuery(moveData, project, column, nodeId, columnAllowList, columnDenyList, 'add'), []);
});

denyListShouldSkip = ["Hotbox"];
test('generateMutationQuery skip move of card when card in column in the deny list', t => {
t.deepEqual(generateMutationQuery(moveData, project, column, nodeId, columnAllowList, denyListShouldSkip, 'update'), []);
});

test('generateMutationQuery skip deletion when the card in column in the deny list', t => {
t.deepEqual(generateMutationQuery(moveData, project, column, nodeId, columnAllowList, denyListShouldSkip, 'delete'), []);
});

denyListShouldntSkip = ["Icebox"];
test('generateMutationQuery move the card when in the correct project, wrong column and other columns denied', t => {
t.deepEqual(generateMutationQuery(moveData, project, column, nodeId, columnAllowList, denyListShouldntSkip, 'update'), [
`mutation {
moveProjectCard( input: {
cardId: "MDExOlByb2plY3RDYXJkMzUxNzI2MjM=",
columnId: "MDEzOlByb2plY3RDb2x1bW44NDU0MzQ5"
}) { clientMutationId } }`
]);
});

test('generateMutationQuery delete the card when it is in the project already and other columns denied', t => {
t.deepEqual(generateMutationQuery(moveData, project, column, nodeId, columnAllowList, denyListShouldntSkip, 'delete'), [
`mutation {
deleteProjectCard( input: {
cardId: "MDExOlByb2plY3RDYXJkMzUxNzI2MjM="
}) { clientMutationId } }`
]);
});

allowListShouldSkip = ["Icebox"]
test('generateMutationQuery skip move of card when card in column not in the allow list', t => {
t.deepEqual(generateMutationQuery(moveData, project, column, nodeId, allowListShouldSkip, columnDenyList, 'update'), []);
});

test('generateMutationQuery skip deletion when the card in column not in the allow list', t => {
t.deepEqual(generateMutationQuery(moveData, project, column, nodeId, allowListShouldSkip, columnDenyList, 'delete'), []);
});

allowListShouldntSkip = ["Hotbox"]
test('generateMutationQuery move the card when in the correct project, wrong column and column allowed', t => {
t.deepEqual(generateMutationQuery(moveData, project, column, nodeId, allowListShouldntSkip, columnDenyList, 'update'), [
`mutation {
moveProjectCard( input: {
cardId: "MDExOlByb2plY3RDYXJkMzUxNzI2MjM=",
columnId: "MDEzOlByb2plY3RDb2x1bW44NDU0MzQ5"
}) { clientMutationId } }`
]);
});

test('generateMutationQuery delete the card when it is in the project already and column allowed', t => {
t.deepEqual(generateMutationQuery(moveData, project, column, nodeId, allowListShouldntSkip, columnDenyList, 'delete'), [
`mutation {
deleteProjectCard( input: {
cardId: "MDExOlByb2plY3RDYXJkMzUxNzI2MjM="
}) { clientMutationId } }`
]);
});

const addData = {
Expand Down Expand Up @@ -104,7 +171,7 @@ const addData = {
};

test('generateMutationQuery add the card when the card does not exist in the project', t => {
t.deepEqual(generateMutationQuery(addData, project, column, nodeId, 'update'), [
t.deepEqual(generateMutationQuery(addData, project, column, nodeId, columnAllowList, columnDenyList, 'update'), [
`mutation {
addProjectCard( input: {
contentId: "MDU6SXNzdWU1ODc4NzU1Mjk=",
Expand All @@ -114,7 +181,7 @@ test('generateMutationQuery add the card when the card does not exist in the pro
});

test('generateMutationQuery skip issue deletion when the card does not exist in the project', t => {
t.deepEqual(generateMutationQuery(addData, project, column, nodeId, 'delete'), []);
t.deepEqual(generateMutationQuery(addData, project, column, nodeId, columnAllowList, columnDenyList, 'delete'), []);
});

const archiveData = {
Expand Down Expand Up @@ -160,7 +227,7 @@ const archiveData = {
};

test('generateMutationQuery skip issue archive when the card is already archived', t => {
t.deepEqual(generateMutationQuery(archiveData, project, column, nodeId, 'archive'), []);
t.deepEqual(generateMutationQuery(archiveData, project, column, nodeId, columnAllowList, columnDenyList, 'archive'), []);
});

const dataNoColumn = {
Expand Down Expand Up @@ -193,7 +260,7 @@ const dataNoColumn = {
};

test('generateMutationQuery should fail if it cannot find a matching column', t => {
const error = t.throws(() => generateMutationQuery(dataNoColumn, project, column, nodeId));
const error = t.throws(() => generateMutationQuery(dataNoColumn, project, column, columnAllowList, columnDenyList, nodeId));

t.is(error.message, `Could not find the column "${column}" or project "${project}"`);
});
Expand Down Expand Up @@ -228,7 +295,7 @@ const dataNoProject = {
};

test('generateMutationQuery should fail if it cannot find a matching project', t => {
const error = t.throws(() => generateMutationQuery(dataNoProject, project, column, nodeId));
const error = t.throws(() => generateMutationQuery(dataNoProject, project, column, nodeId, columnAllowList, columnDenyList));

t.is(error.message, `Could not find the column "${column}" or project "${project}"`);
});

0 comments on commit f1c2861

Please sign in to comment.