-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from yuta1024/init
initial version
- Loading branch information
Showing
22 changed files
with
6,254 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
GITHUB_REPOSITORY= | ||
INPUT_REPO_TOKEN= | ||
INPUT_PROJECT= | ||
INPUT_FROM_COLUMN= | ||
INPUT_TO_COLUMN= | ||
INPUT_EXPIRATION_DAYS= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
dotenv |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
dist/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
env: | ||
es2017: true | ||
jest: true | ||
node: true | ||
extends: eslint:recommended |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
name: Test | ||
on: | ||
pull_request: | ||
push: | ||
branches: | ||
- main | ||
|
||
jobs: | ||
test: | ||
runs-on: ubuntu-20.04 | ||
strategy: | ||
matrix: | ||
node-version: [12.x, 14.x] | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Use Node.js ${{ matrix.node-version }} | ||
uses: actions/setup-node@v1 | ||
with: | ||
node-version: ${{ matrix.node-version }} | ||
- run: npm install | ||
- run: npm run lint | ||
- run: npm test | ||
- run: npm run build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
.env | ||
.idea/ | ||
coverage/ | ||
node_modules/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Change log | ||
|
||
## [1.0.0] - 2020-09-01 | ||
### Added | ||
- initial version |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,59 @@ | ||
# cards-moving-automation | ||
Automate that cards of GitHub Project move to any column with expiration | ||
![Test](https://github.com/yuta1024/cards-moving-automation/workflows/Test/badge.svg) | ||
|
||
Automate that cards of GitHub Project move to any column with expiration. | ||
|
||
**Now, support only `issue`.** | ||
|
||
## Building and testing | ||
Install the dependencies | ||
```bash | ||
$ npm install | ||
``` | ||
|
||
Run the tests | ||
```bash | ||
$ npm test | ||
``` | ||
|
||
## Usage | ||
See [action.yml](./action.yml) For comprehensive list of options. | ||
|
||
Basic: | ||
```yaml | ||
name: 'Move expired cards' | ||
on: | ||
schedule: | ||
- cron: "0 0 * * *" | ||
|
||
jobs: | ||
automation: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: yuta1024/cards-moving-automation@v1 | ||
with: | ||
repo_token: ${{ secrets.GITHUB_TOKEN }} | ||
project: 'The name of the GitHub Project' | ||
from_column: 'The name of the columns which contains cards to move' | ||
to_column: 'The name of the column to move it into' | ||
``` | ||
Configure `expiration_days`: | ||
```yaml | ||
name: 'Move expired cards' | ||
on: | ||
schedule: | ||
- cron: "0 0 * * *" | ||
jobs: | ||
automation: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: yuta1024/cards-moving-automation@v1 | ||
with: | ||
repo_token: ${{ secrets.GITHUB_TOKEN }} | ||
project: 'The name of the GitHub Project' | ||
from_column: 'The name of the columns which contains cards to move' | ||
to_column: 'The name of the column to move it into' | ||
expiration_days: 30 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
name: Cards Moving Automation | ||
description: Automate that cards of GitHub Project move to any column with expiration | ||
inputs: | ||
repo_token: | ||
description: The token for the repository can be passed in using {{ secrets.GITHUB_TOKEN }} | ||
required: true | ||
project: | ||
description: The name of the GitHub Project | ||
required: true | ||
from_column: | ||
description: The name of the columns which contains cards to move | ||
required: true | ||
to_column: | ||
description: The name of the column to move it into | ||
required: true | ||
expiration_days: | ||
description: The minimum days of moving cards with no activity | ||
default: '90' | ||
required: false | ||
runs: | ||
using: node12 | ||
main: dist/index.js |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
const core = require('@actions/core'); | ||
const main = require('./lib/main'); | ||
|
||
(async () => { | ||
try { | ||
await main(); | ||
} catch (err) { | ||
core.setFailed(err.message); | ||
} | ||
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
const core = require('@actions/core'); | ||
const github = require('@actions/github'); | ||
const moment = require('moment-timezone'); | ||
const project = require('./project'); | ||
const validator = require('./validator'); | ||
|
||
module.exports = async() => { | ||
const now = moment(); | ||
const args = await validator.getArgs(); | ||
const { owner, repo } = github.context.repo; | ||
const octokit = github.getOctokit(args.token); | ||
|
||
const targetProject = (await project.getAllProjects(octokit, owner, repo)) | ||
.find(project => project.name === args.project); | ||
if (targetProject === undefined) { | ||
throw new Error(`${args.project} is not found in ${owner}/${repo}`); | ||
} | ||
|
||
const targetColumn = (await project.getAllColumns(octokit, owner, repo, targetProject.number)) | ||
.find(column => column.name === args.toColumn); | ||
if (targetColumn === undefined) { | ||
throw new Error(`${args.toColumn} is not found in ${args.project}`); | ||
} | ||
|
||
const targetIssues = (await project.getAllOpenedIssues(octokit, owner, repo)) | ||
.filter(issue => | ||
issue.projectCards.nodes.length > 0 && | ||
issue.projectCards.nodes[0].column.name === args.fromColumn && | ||
issue.projectCards.nodes[0].project.name === args.project && | ||
moment(issue.updatedAt).add(args.expirationDays, 'd').isBefore(now) && | ||
moment(issue.projectCards.nodes[0].updatedAt).add(args.expirationDays, 'd').isBefore(now) | ||
); | ||
|
||
for (const issue of targetIssues) { | ||
core.info(`move "${issue.title}" from "${args.fromColumn}" to "${args.toColumn}".`) | ||
await project.moveCard(octokit, issue.projectCards.nodes[0].id, targetColumn.id); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
const getAllProjects = async (octokit, owner, repo, cursor = null) => { | ||
const res = await octokit.graphql(` | ||
query($owner: String!, $repo: String!, $cursor: String) { | ||
repository(owner: $owner, name: $repo) { | ||
projects(after: $cursor, first:100) { | ||
pageInfo { | ||
endCursor | ||
hasNextPage | ||
} | ||
nodes { | ||
name | ||
number | ||
} | ||
} | ||
} | ||
}`, {owner, repo, cursor}); | ||
|
||
const pageInfo = res.repository.projects.pageInfo; | ||
if (pageInfo.hasNextPage) { | ||
return [ | ||
...res.repository.projects.nodes, | ||
...await getAllProjects(octokit, owner, repo, pageInfo.endCursor) | ||
]; | ||
} else { | ||
return res.repository.projects.nodes; | ||
} | ||
}; | ||
|
||
const getAllColumns = async (octokit, owner, repo, projectNumber, cursor = null) => { | ||
const res = await octokit.graphql(` | ||
query($owner: String!, $repo: String!, $projectNumber: Int!, $cursor: String) { | ||
repository(owner: $owner, name: $repo) { | ||
project(number: $projectNumber) { | ||
columns(after: $cursor, first:100) { | ||
pageInfo { | ||
endCursor | ||
hasNextPage | ||
} | ||
nodes { | ||
id | ||
name | ||
} | ||
} | ||
} | ||
} | ||
}`, {owner, repo, projectNumber, cursor}); | ||
|
||
const pageInfo = res.repository.project.columns.pageInfo; | ||
if (pageInfo.hasNextPage) { | ||
return [ | ||
...res.repository.project.columns.nodes, | ||
...await getAllColumns(octokit, owner, repo, projectNumber, pageInfo.endCursor) | ||
]; | ||
} else { | ||
return res.repository.project.columns.nodes; | ||
} | ||
} | ||
|
||
const getAllOpenedIssues = async (octokit, owner, repo, cursor = null) => { | ||
const res = await octokit.graphql(` | ||
query($owner: String!, $repo: String!, $cursor: String) { | ||
repository(owner: $owner, name: $repo) { | ||
issues(after: $cursor, first: 100, filterBy: {states: [OPEN]}) { | ||
pageInfo { | ||
endCursor, | ||
hasNextPage | ||
} | ||
nodes { | ||
title | ||
updatedAt | ||
projectCards(first: 1) { | ||
nodes { | ||
id | ||
column { | ||
name | ||
} | ||
project { | ||
name | ||
} | ||
updatedAt | ||
} | ||
} | ||
} | ||
} | ||
} | ||
}`, {owner, repo, cursor}); | ||
|
||
const pageInfo = res.repository.issues.pageInfo; | ||
if (pageInfo.hasNextPage) { | ||
return [ | ||
...res.repository.issues.nodes, | ||
...await getAllOpenedIssues(octokit, owner, repo, pageInfo.endCursor) | ||
]; | ||
} else { | ||
return res.repository.issues.nodes; | ||
} | ||
} | ||
|
||
// https://docs.github.com/en/graphql/reference/mutations#moveprojectcard | ||
const moveCard = async (octokit, cardId, columnId) => { | ||
return await octokit.graphql(` | ||
mutation($cardId: ID!, $columnId: ID!) { | ||
moveProjectCard(input: {cardId: $cardId, columnId: $columnId}) { | ||
clientMutationId | ||
} | ||
} | ||
`, {cardId, columnId}); | ||
} | ||
|
||
module.exports = { | ||
getAllProjects, | ||
getAllColumns, | ||
getAllOpenedIssues, | ||
moveCard | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
const core = require('@actions/core'); | ||
|
||
module.exports.getArgs = async () => { | ||
const args = { | ||
token: core.getInput('repo_token', {required: true}), | ||
project: core.getInput('project', {required: true}), | ||
fromColumn: core.getInput('from_column', {required: true}), | ||
toColumn: core.getInput('to_column', {required: true}), | ||
expirationDays: core.getInput('expiration_days') | ||
} | ||
|
||
if (isNaN(parseInt(core.getInput('expiration_days')))) { | ||
throw Error('`expiration-days` must be integer') | ||
} | ||
|
||
return args; | ||
}; |
Oops, something went wrong.