Skip to content

Commit 16102c7

Browse files
committed
feature: add unlableled action
1 parent 14a0a99 commit 16102c7

15 files changed

Lines changed: 223 additions & 120 deletions

README.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
[![Deploy to now](https://deploy.now.sh/static/button.svg)](https://deploy.now.sh/?repo=https://github.com/pauldariye/kanbanize&env=TOKEN&env=WEBHOOK_SECRET&env=OWNER&env=RESPOSITORY)
2-
[![Remix on Glitch](https://cdn.glitch.com/2703baf2-b643-4da7-ab91-7ee2a2d00b5b%2Fremix-button.svg)](https://glitch.com/edit/#!/remix/https://glitch.com/edit/#!/remix/kanbanize)
2+
[![Remix on Glitch](https://cdn.glitch.com/2703baf2-b643-4da7-ab91-7ee2a2d00b5b%2Fremix-button.svg)](https://glitch.com/edit/#!/remix/kanbanize/ca1589ea-ae22-4483-a2ee-c0b4c426e43f)
33
# Kanbanize
44

5-
This is a simple issues triager for github project boards. Github projects are
6-
great but have limited functionality, and chief among them is moving project
7-
cards automatically. This is easily solved with properly creating a taxonomy for
8-
your issue labels.
5+
This is a fairly simple and extensible kanban power-up for GitHub Projects that automates the triaging of new issues to project boards and to track issue statuses automatically
6+
7+
## Features
8+
9+
- Move a project card along the board automatically.
10+
- Triage issues to different project boards automatically.
911

1012
[Read more about it in this blog post](https://medium.com/the-andela-way/https-medium-com-the-andela-way-how-to-build-a-power-up-for-your-github-project-board-for-project-344d5b380a68).
1113

@@ -21,6 +23,8 @@ yarn dev
2123

2224
Visit [https://localhost:3000](https://localhost:3000) or `https://[NGROK_SUBDOMAIN].ngrok.io`
2325

26+
## Deploy
27+
2428
Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download))
2529
```bash
2630
now

actions/index.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
module.exports = { labeled: require ('./labeled') }
1+
module.exports = {
2+
labeled: require ('./labeled'),
3+
unlabeled: require('./unlabeled')
4+
}

actions/labeled.js

Lines changed: 26 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,34 @@
1-
const async = require('async')
2-
const config = require('../config')
3-
const { graphqlClient } = require('../lib/github')
4-
const { query, mutation } = require('../graphql')
1+
const { query } = require('../graphql')
2+
const {
3+
graphqlClient,
4+
addProjectCard,
5+
moveProjectCard,
6+
baseVariables
7+
} = require('../lib/github')
58

6-
const { owner, repo } = config.github
7-
const baseVariables = { owner, name: repo }
8-
9-
const addToProject = async (project, issue, variables) => {
10-
if (!project || project.repository.projects.edges.length === 0) return
11-
if (!issue) return
12-
if (!variables) return
13-
14-
const { repository: { issue: { id: contentId } } } = issue
15-
const projectColumnId = project.repository.projects.edges[0].node.columns.edges[0].node.id || null
16-
if (contentId && projectColumnId) {
17-
const projectCardMutationVariables = Object.assign({}, variables, {
18-
"issue": { contentId, projectColumnId }
19-
})
20-
await graphqlClient.request(mutation.AddProjectCard, projectCardMutationVariables)
21-
}
22-
}
23-
24-
const moveProjectCard = async (destinationColumnName, issue, variables) => {
25-
if (!destinationColumnName) return
26-
if (!issue) return
27-
if (!variables) return
28-
const { repository: { issue: { projectCards } } } = issue
29-
async.each(projectCards.edges, async ({ node: {
30-
id: cardId,
31-
project: { name: projectName },
32-
column: { id: currentColumnId, name: currentColumnName } } }) => {
33-
const project = await graphqlClient.request(query.FindProjectColumns,
34-
Object.assign({}, variables, { projectName })
35-
)
36-
const { repository: { projects: { edges } } } = project
37-
async.each(edges, async ({ node: { columns: { edges } } }) => {
38-
async.each(edges, async ({ node: { id: columnId, name: columnName } }) => {
39-
if (columnId === currentColumnId) return
40-
if (columnName.toLowerCase() === currentColumnName.toLowerCase()) return
41-
if (columnName.toLowerCase() !== destinationColumnName.toLowerCase()) return
42-
const projectCardMutationVariables = Object.assign({}, variables, {
43-
"card": { cardId, columnId }
44-
})
45-
await graphqlClient.request(mutation.MoveProjectCard, projectCardMutationVariables)
46-
})
47-
})
48-
})
49-
}
50-
51-
async function labeled (payload) {
52-
const { issue: { number, state, labels }, label: { name } } = payload
9+
module.exports = async (payload) => {
10+
const { issue: { number }, label: { name } } = payload
5311
const variables = Object.assign({}, baseVariables, {
5412
number, projectName: name
5513
})
14+
5615
const [issue, project] = await Promise.all([
57-
graphqlClient.request(query.FindIssue, variables),
58-
graphqlClient.request(query.FindProject, variables)
16+
graphqlClient.request(query.findIssue, variables),
17+
graphqlClient.request(query.findProject, variables)
5918
])
60-
const issueLabels = issue.repository.issue.labels.edges
61-
.filter((label) => label.node.name === name)
6219

63-
async.each(issueLabels, async (label) => {
64-
const { node: { name, description } } = label
65-
switch(description) {
66-
case 'project':
67-
await addToProject(project, issue, variables)
68-
break
69-
case 'status':
70-
await moveProjectCard(name, issue, variables)
71-
break
72-
default:
73-
}
74-
})
75-
}
20+
const label = issue.repository.issue.labels.edges
21+
.find(label => label.node.name === name)
7622

77-
module.exports = labeled
23+
const { description } = label.node
24+
25+
switch(description) {
26+
case 'project':
27+
await addProjectCard({ label, project, issue, variables })
28+
break
29+
case 'status':
30+
await moveProjectCard({ label, issue, variables })
31+
break
32+
default:
33+
}
34+
}

actions/unlabeled.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const { query } = require('../graphql')
2+
const {
3+
graphqlClient,
4+
deleteProjectCard,
5+
baseVariables
6+
} = require('../lib/github')
7+
8+
module.exports = async (payload) => {
9+
const { issue: { number }, label: { name } } = payload
10+
const variables = Object.assign({}, baseVariables, {
11+
number, projectName: name
12+
})
13+
14+
const issue = await graphqlClient.request(query.findIssue, variables)
15+
if (issue.repository.issue.projectCards.edges.length === 0) return
16+
17+
const card = issue.repository.issue.projectCards.edges[0].node
18+
if (card.project.name === name) {
19+
await deleteProjectCard({ card })
20+
}
21+
}

bin/start-dev.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
node_modules/.bin/concurrently \
44
--kill-others-on-fail \
5-
"sleep 10 && nodemon ./app" \
5+
"sleep 10 && micro-dev" \
66
"npm run ngrok"

graphql/mutation/addProjectCard.js

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
1-
const addProjectCard = `
1+
module.exports = `
22
mutation AddProjectCard($issue: AddProjectCardInput!) {
3-
addProjectCard(input: $issue) {
4-
cardEdge {
5-
node {
6-
id
7-
}
8-
}
9-
projectColumn {
3+
addProjectCard(input: $issue) {
4+
cardEdge {
5+
node {
106
id
11-
},
12-
clientMutationId
7+
}
8+
}
9+
projectColumn {
10+
id
1311
}
12+
clientMutationId
1413
}
15-
`
16-
module.exports = addProjectCard
14+
}
15+
`
1716

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module.exports = `
2+
mutation DeleteProjectCard($card: DeleteProjectCardInput!) {
3+
deleteProjectCard(input: $card) {
4+
deletedCardId
5+
}
6+
}
7+
`

graphql/mutation/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module.exports = {
22
addProjectCard: require('./addProjectCard'),
3+
deleteProjectCard: require('./deleteProjectCard'),
34
moveProjectCard: require('./moveProjectCard')
45
}
56

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
const moveProjectCard = `
2-
mutation MoveProjectCard($card: MoveProjectCardInput!) {
3-
moveProjectCard(input: $card) {
4-
cardEdge {
5-
node {
6-
id
7-
}
1+
module.exports = `
2+
mutation MoveProjectCard($card: MoveProjectCardInput!) {
3+
moveProjectCard(input: $card) {
4+
cardEdge {
5+
node {
6+
id
87
}
9-
clientMutationId
108
}
9+
clientMutationId
1110
}
12-
`
13-
module.exports = moveProjectCard
11+
}
12+
`

graphql/query/findIssue.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
const findIssue = `
1+
module.exports = `
22
query FindIssue($owner: String!, $name: String!, $number: Int!) {
33
repository(owner: $owner, name: $name) {
44
issue(number: $number) {
55
id
6+
number
67
title
7-
projectCards(first: 20) {
8+
projectCards(first: 100) {
89
edges {
910
node {
1011
id
@@ -32,4 +33,3 @@ const findIssue = `
3233
}
3334
}
3435
`
35-
module.exports = findIssue

0 commit comments

Comments
 (0)