Skip to content

Commit eb6c8c4

Browse files
jurijzahn8019Alex Page
andauthored
feat(action): add possibility to delete a card from project (#56)
Co-authored-by: Alex Page <[email protected]>
1 parent 10f3bf1 commit eb6c8c4

File tree

10 files changed

+134
-31
lines changed

10 files changed

+134
-31
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ Change these options in the workflow `.yml` file to meet your GitHub project nee
6969
| `project` | The name of the project | `Backlog` |
7070
| `column` | The column to create or move the card to | `Triage` |
7171
| `repo-token` | The personal access token | `${{ secrets.GITHUB_TOKEN }}` |
72+
| `action` | This determines the type of the action to be performed on the card, Default: `update` | `update`, `delete`, `archive` |
7273

7374
## Personal access token (secrets.GITHUB_TOKEN)
7475

@@ -127,6 +128,7 @@ To set up the action for local development and testing:
127128
128129
## Release History
129130
131+
- v0.5.0 - Add option to `delete` card
130132
- v0.4.0 - Add `issue_comment` event
131133
- v0.3.0 - Add `pull_request_target` event
132134
- v0.2.4 - Update dependencies

__tests__/generate-mutation-query.js

Lines changed: 69 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,21 @@ const moveData = {
4848
};
4949

5050
test('generateMutationQuery move the card when in the correct project and wrong column', t => {
51-
t.deepEqual(generateMutationQuery(moveData, project, column, nodeId), [
51+
t.deepEqual(generateMutationQuery(moveData, project, column, nodeId, 'update'), [
5252
`mutation {
53-
moveProjectCard( input: {
54-
cardId: "MDExOlByb2plY3RDYXJkMzUxNzI2MjM=",
55-
columnId: "MDEzOlByb2plY3RDb2x1bW44NDU0MzQ5"
56-
}) { clientMutationId } }`
53+
moveProjectCard( input: {
54+
cardId: "MDExOlByb2plY3RDYXJkMzUxNzI2MjM=",
55+
columnId: "MDEzOlByb2plY3RDb2x1bW44NDU0MzQ5"
56+
}) { clientMutationId } }`
57+
]);
58+
});
59+
60+
test('generateMutationQuery delete the card when it is in the project already', t => {
61+
t.deepEqual(generateMutationQuery(moveData, project, column, nodeId, 'delete'), [
62+
`mutation {
63+
deleteProjectCard( input: {
64+
cardId: "MDExOlByb2plY3RDYXJkMzUxNzI2MjM="
65+
}) { clientMutationId } }`
5766
]);
5867
});
5968

@@ -91,15 +100,65 @@ const addData = {
91100
};
92101

93102
test('generateMutationQuery add the card when the card does not exist in the project', t => {
94-
t.deepEqual(generateMutationQuery(addData, project, column, nodeId), [
103+
t.deepEqual(generateMutationQuery(addData, project, column, nodeId, 'update'), [
95104
`mutation {
96-
addProjectCard( input: {
97-
contentId: "MDU6SXNzdWU1ODc4NzU1Mjk=",
98-
projectColumnId: "MDEzOlByb2plY3RDb2x1bW44NDU0MzQ5"
99-
}) { clientMutationId } }`
105+
addProjectCard( input: {
106+
contentId: "MDU6SXNzdWU1ODc4NzU1Mjk=",
107+
projectColumnId: "MDEzOlByb2plY3RDb2x1bW44NDU0MzQ5"
108+
}) { clientMutationId } }`
100109
]);
101110
});
102111

112+
test('generateMutationQuery skip issue deletion when the card does not exist in the project', t => {
113+
t.deepEqual(generateMutationQuery(addData, project, column, nodeId, 'delete'), []);
114+
});
115+
116+
const archiveData = {
117+
projectCards: {
118+
nodes: [
119+
{
120+
id: 'MDExOlByb2plY3RDYXJkMzUxNzI2MjM=',
121+
isArchived: true,
122+
project: {
123+
name: project,
124+
id: 'MDc6UHJvamVjdDQwNzU5MDI='
125+
}
126+
}
127+
]
128+
},
129+
repository: {
130+
projects: {
131+
nodes: [
132+
{
133+
name: project,
134+
id: 'MDc6UHJvamVjdDQwNzU5MDI=',
135+
columns: {
136+
nodes: [
137+
{
138+
id: 'MDEzOlByb2plY3RDb2x1bW44NDU0MzQ5',
139+
name: column
140+
},
141+
{
142+
id: 'MDEzOlByb2plY3RDb2x1bW44MjUxOTAz',
143+
name: 'In progress'
144+
}
145+
]
146+
}
147+
}
148+
]
149+
},
150+
owner: {
151+
projects: {
152+
nodes: []
153+
}
154+
}
155+
}
156+
};
157+
158+
test('generateMutationQuery skip issue archive when the card is already archived', t => {
159+
t.deepEqual(generateMutationQuery(archiveData, project, column, nodeId, 'archive'), []);
160+
});
161+
103162
const dataNoColumn = {
104163
projectCards: {
105164
nodes: []

__tests__/generate-project-query.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const issueQuery = `query {
88
projectCards {
99
nodes {
1010
id
11+
isArchived
1112
project {
1213
name
1314
id
@@ -54,6 +55,7 @@ const pullrequestQuery = `query {
5455
projectCards {
5556
nodes {
5657
id
58+
isArchived
5759
project {
5860
name
5961
id

action.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ inputs:
1111
column:
1212
description: 'The name of the column to move the issue or pull request to'
1313
required: true
14+
action:
15+
description: |
16+
Can be `update`, `delete` or `archive`. This determines the type of the action
17+
to be performed on the card
18+
required: false
19+
default: "update"
1420
runs:
1521
using: 'node12'
1622
main: 'dist/index.js'

dist/index.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "github-project-automation-plus",
3-
"version": "0.3.0",
3+
"version": "0.5.0",
44
"description": "🤖 Automate GitHub Project cards with any webhook event",
55
"private": true,
66
"main": "dist/index.js",
@@ -11,7 +11,7 @@
1111
},
1212
"repository": {
1313
"type": "git",
14-
"url": "git+https://github.com/alex-page/automate-project-columns.git"
14+
"url": "git+https://github.com/alex-page/github-project-automation-plus.git"
1515
},
1616
"keywords": [
1717
"github-actions",
@@ -24,9 +24,9 @@
2424
"author": "Alex Page <[email protected]>",
2525
"license": "MIT",
2626
"bugs": {
27-
"url": "https://github.com/alex-page/automate-project-columns/issues"
27+
"url": "https://github.com/alex-page/github-project-automation-plus/issues"
2828
},
29-
"homepage": "https://github.com/alex-page/automate-project-columns#readme",
29+
"homepage": "https://github.com/alex-page/github-project-automation-plus#readme",
3030
"dependencies": {
3131
"@actions/core": "^1.2.3",
3232
"@actions/github": "^2.1.1"

src/generate-mutation-query.js

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@
55
* @param {string} projectName - The user inputted project name
66
* @param {string} columnName - The user inputted column name
77
* @param {string} contentId - The id of the issue or pull request
8+
* @param {"delete"|"archive"|"update"} action - the action to be performed on the card
89
*/
9-
const generateMutationQuery = (data, projectName, columnName, contentId) => {
10+
// if this is important, we will need to refactor the function
11+
// eslint-disable-next-line max-params
12+
const generateMutationQuery = (data, projectName, columnName, contentId, action) => {
1013
// All the projects found in organisation and repositories
1114
const repoProjects = data.repository.projects.nodes || [];
1215
const orgProjects = (data.repository.owner &&
@@ -46,24 +49,49 @@ const generateMutationQuery = (data, projectName, columnName, contentId) => {
4649

4750
currentLocation.forEach(card => {
4851
cardLocations[card.project.id].cardId = card.id;
52+
cardLocations[card.project.id].isArchived = card.isArchived;
4953
});
5054

5155
// If the card already exists in the project move it otherwise add a new card
52-
const mutations = Object.keys(cardLocations).map(mutation => cardLocations[mutation].cardId ?
53-
`mutation {
54-
moveProjectCard( input: {
55-
cardId: "${cardLocations[mutation].cardId}",
56-
columnId: "${cardLocations[mutation].columnId}"
57-
}) { clientMutationId } }` :
56+
const mutations = Object.keys(cardLocations).map(mutation => {
57+
if (action === 'update') {
58+
// Othervise keep default procedure
59+
return cardLocations[mutation].cardId ?
60+
`mutation {
61+
moveProjectCard( input: {
62+
cardId: "${cardLocations[mutation].cardId}",
63+
columnId: "${cardLocations[mutation].columnId}"
64+
}) { clientMutationId } }` :
5865

59-
`mutation {
60-
addProjectCard( input: {
61-
contentId: "${contentId}",
62-
projectColumnId: "${cardLocations[mutation].columnId}"
63-
}) { clientMutationId } }`
64-
);
66+
`mutation {
67+
addProjectCard( input: {
68+
contentId: "${contentId}",
69+
projectColumnId: "${cardLocations[mutation].columnId}"
70+
}) { clientMutationId } }`;
71+
}
6572

66-
return mutations;
73+
if (action === 'delete' && cardLocations[mutation].cardId) {
74+
// Delete issue from all boards, this if block
75+
// prevents adding issue in case it has no card yet
76+
return `mutation {
77+
deleteProjectCard( input: {
78+
cardId: "${cardLocations[mutation].cardId}"
79+
}) { clientMutationId } }`;
80+
}
81+
82+
if (action === 'archive' && !cardLocations[mutation].isArchived) {
83+
// Archive issue if not already archived
84+
return `mutation {
85+
updateProjectCard(input: {
86+
projectCardId: "${cardLocations[mutation].cardId}",
87+
isArchived: true
88+
}) { clientMutationId } }`;
89+
}
90+
91+
return undefined;
92+
});
93+
94+
return mutations.filter(m => m !== undefined);
6795
};
6896

6997
module.exports = generateMutationQuery;

src/generate-project-query.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const projectQuery = (url, eventName, project) => (
1212
projectCards {
1313
nodes {
1414
id
15+
isArchived
1516
project {
1617
name
1718
id

src/index.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const generateMutationQuery = require('./generate-mutation-query');
1010
const token = core.getInput('repo-token');
1111
const project = core.getInput('project');
1212
const column = core.getInput('column');
13+
const action = core.getInput('action') || 'update';
1314

1415
// Get data from the current action
1516
const {eventName, nodeId, url} = getActionData(github.context);
@@ -27,7 +28,11 @@ const generateMutationQuery = require('./generate-mutation-query');
2728
core.debug(JSON.stringify(resource));
2829

2930
// A list of columns that line up with the user entered project and column
30-
const mutationQueries = generateMutationQuery(resource, project, column, nodeId);
31+
const mutationQueries = generateMutationQuery(resource, project, column, nodeId, action);
32+
if ((action === 'delete' || action === 'archive') && mutationQueries.length < 1) {
33+
console.log('✅ There is nothing to do with card');
34+
return;
35+
}
3136

3237
core.debug(mutationQueries.join('\n'));
3338

0 commit comments

Comments
 (0)