diff --git a/action.yml b/action.yml index 8d8b5d8..1556431 100644 --- a/action.yml +++ b/action.yml @@ -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 diff --git a/src/generate-mutation-query.js b/src/generate-mutation-query.js index 05987dd..ef797cf 100644 --- a/src/generate-mutation-query.js +++ b/src/generate-mutation-query.js @@ -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 && @@ -50,10 +52,24 @@ 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)) { + console.log("HERE REACHED 3") + return undefined; + } + if (action === 'update') { // Othervise keep default procedure return cardLocations[mutation].cardId ? diff --git a/src/index.js b/src/index.js index 2bc736c..2c26a02 100644 --- a/src/index.js +++ b/src/index.js @@ -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 @@ -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; diff --git a/tests/generate-mutation-query.js b/tests/generate-mutation-query.js index db04fe7..112c51f 100644 --- a/tests/generate-mutation-query.js +++ b/tests/generate-mutation-query.js @@ -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: { @@ -14,6 +16,9 @@ const moveData = { project: { name: project, id: 'MDc6UHJvamVjdDQwNzU5MDI=' + }, + column: { + name: 'Hotbox' } } ] @@ -30,6 +35,10 @@ const moveData = { id: 'MDEzOlByb2plY3RDb2x1bW44NDU0MzQ6', name: 'Icebox' }, + { + id: 'MDEzOlByb2plY3RDb2x1bW44NDU0MzQ7', + name: 'Hotbox' + }, { id: 'MDEzOlByb2plY3RDb2x1bW44NDU0MzQ5', name: column @@ -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=", @@ -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=" @@ -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 = { @@ -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=", @@ -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 = { @@ -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 = { @@ -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}"`); }); @@ -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}"`); });