Skip to content
This repository was archived by the owner on May 15, 2021. It is now read-only.

Commit b2eb1a7

Browse files
feat: build for release
1 parent 2c2c3ed commit b2eb1a7

File tree

412 files changed

+91860
-1
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

412 files changed

+91860
-1
lines changed

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2020 Technote
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

README.ja.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Auto Cancel Redundant Job
2+
3+
[![CI Status](https://github.com/technote-space/auto-cancel-redundant-job/workflows/CI/badge.svg)](https://github.com/technote-space/auto-cancel-redundant-job/actions)
4+
[![codecov](https://codecov.io/gh/technote-space/auto-cancel-redundant-job/branch/master/graph/badge.svg)](https://codecov.io/gh/technote-space/auto-cancel-redundant-job)
5+
[![CodeFactor](https://www.codefactor.io/repository/github/technote-space/auto-cancel-redundant-job/badge)](https://www.codefactor.io/repository/github/technote-space/auto-cancel-redundant-job)
6+
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/technote-space/auto-cancel-redundant-job/blob/master/LICENSE)
7+
8+
*Read this in other languages: [English](README.md), [日本語](README.ja.md).*
9+
10+
冗長ビルドを自動キャンセルする `GitHub Actions` です。
11+
12+
## Table of Contents
13+
14+
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
15+
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
16+
<details>
17+
<summary>Details</summary>
18+
19+
- [使用方法](#%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95)
20+
- [スクリーンショット](#%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88)
21+
- [キャンセル中](#%E3%82%AD%E3%83%A3%E3%83%B3%E3%82%BB%E3%83%AB%E4%B8%AD)
22+
- [キャンセルされたジョブ](#%E3%82%AD%E3%83%A3%E3%83%B3%E3%82%BB%E3%83%AB%E3%81%95%E3%82%8C%E3%81%9F%E3%82%B8%E3%83%A7%E3%83%96)
23+
- [結果](#%E7%B5%90%E6%9E%9C)
24+
- [Outputs](#outputs)
25+
- [Author](#author)
26+
27+
</details>
28+
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
29+
30+
## 使用方法
31+
```yaml
32+
on:
33+
repository_dispatch:
34+
types: [test]
35+
# push:
36+
# ...
37+
38+
name: Example
39+
jobs:
40+
firstJob:
41+
name: First Job
42+
runs-on: ubuntu-latest
43+
steps:
44+
# この GitHub Actions をこの workflow の中でできるだけ早く少なくとも一度は使用してください。
45+
- uses: technote-space/auto-cancel-redundant-job@v1
46+
# Run any steps
47+
- name: any steps
48+
run: echo test
49+
# ...
50+
51+
# Run any jobs
52+
secondJob:
53+
name: Second Job
54+
needs: firstJob
55+
runs-on: ubuntu-latest
56+
steps:
57+
- run: echo test
58+
59+
# ...
60+
```
61+
62+
e.g.
63+
- [ci.yml](https://github.com/technote-space/toc-generator/blob/master/.github/workflows/ci.yml)
64+
- [update-dependencies.yml](https://github.com/technote-space/toc-generator/blob/master/.github/workflows/update-dependencies.yml)
65+
66+
## スクリーンショット
67+
### キャンセル中
68+
![cancelling](https://raw.githubusercontent.com/technote-space/auto-cancel-redundant-job/images/cancelling.png)
69+
70+
### キャンセルされたジョブ
71+
![cancelled](https://raw.githubusercontent.com/technote-space/auto-cancel-redundant-job/images/cancelled.png)
72+
73+
### 結果
74+
![result](https://raw.githubusercontent.com/technote-space/auto-cancel-redundant-job/images/result.png)
75+
76+
## Outputs
77+
| name | description | e.g. |
78+
|:---:|:---|:---:|
79+
|ids|キャンセルされた Run ID|`1234,2345`|
80+
81+
## Author
82+
[GitHub (Technote)](https://github.com/technote-space)
83+
[Blog](https://technote.space)

README.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Auto Cancel Redundant Job
2+
3+
[![CI Status](https://github.com/technote-space/auto-cancel-redundant-job/workflows/CI/badge.svg)](https://github.com/technote-space/auto-cancel-redundant-job/actions)
4+
[![codecov](https://codecov.io/gh/technote-space/auto-cancel-redundant-job/branch/master/graph/badge.svg)](https://codecov.io/gh/technote-space/auto-cancel-redundant-job)
5+
[![CodeFactor](https://www.codefactor.io/repository/github/technote-space/auto-cancel-redundant-job/badge)](https://www.codefactor.io/repository/github/technote-space/auto-cancel-redundant-job)
6+
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/technote-space/auto-cancel-redundant-job/blob/master/LICENSE)
7+
8+
*Read this in other languages: [English](README.md), [日本語](README.ja.md).*
9+
10+
GitHub Actions to automatically cancel redundant jobs.
11+
12+
## Table of Contents
13+
14+
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
15+
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
16+
<details>
17+
<summary>Details</summary>
18+
19+
- [Usage](#usage)
20+
- [Screenshots](#screenshots)
21+
- [Cancelling jobs](#cancelling-jobs)
22+
- [Cancelled job](#cancelled-job)
23+
- [Result](#result)
24+
- [Outputs](#outputs)
25+
- [Author](#author)
26+
27+
</details>
28+
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
29+
30+
## Usage
31+
```yaml
32+
on:
33+
repository_dispatch:
34+
types: [test]
35+
# push:
36+
# ...
37+
38+
name: Example
39+
jobs:
40+
firstJob:
41+
name: First Job
42+
runs-on: ubuntu-latest
43+
steps:
44+
# Use this GitHub Actions at least once in this workflow as soon as possible.
45+
- uses: technote-space/auto-cancel-redundant-job@v1
46+
# Run any steps
47+
- name: any steps
48+
run: echo test
49+
# ...
50+
51+
# Run any jobs
52+
secondJob:
53+
name: Second Job
54+
needs: firstJob
55+
runs-on: ubuntu-latest
56+
steps:
57+
- run: echo test
58+
59+
# ...
60+
```
61+
62+
e.g.
63+
- [ci.yml](https://github.com/technote-space/toc-generator/blob/master/.github/workflows/ci.yml)
64+
- [update-dependencies.yml](https://github.com/technote-space/toc-generator/blob/master/.github/workflows/update-dependencies.yml)
65+
66+
## Screenshots
67+
### Cancelling jobs
68+
![cancelling](https://raw.githubusercontent.com/technote-space/auto-cancel-redundant-job/images/cancelling.png)
69+
70+
### Cancelled job
71+
![cancelled](https://raw.githubusercontent.com/technote-space/auto-cancel-redundant-job/images/cancelled.png)
72+
73+
### Result
74+
![result](https://raw.githubusercontent.com/technote-space/auto-cancel-redundant-job/images/result.png)
75+
76+
## Outputs
77+
| name | description | e.g. |
78+
|:---:|:---|:---:|
79+
|ids|The results of cancelled run ids.|`1234,2345`|
80+
81+
## Author
82+
[GitHub (Technote)](https://github.com/technote-space)
83+
[Blog](https://technote.space)

build.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"owner":"technote-space","repo":"auto-cancel-redundant-job","sha":"18de735eed447ec5d0e4363e8be7211b3958f23a","ref":"refs/tags/test/v1.4.4.213196783","tagName":"test/v1.4.4.213196783","branch":"gh-actions","tags":["test/v1.4.4.213196783","test/v1.4.4","test/v1.4","test/v1"],"updated_at":"2020-08-18T06:49:55.618Z"}
1+
{"owner":"technote-space","repo":"auto-cancel-redundant-job","sha":"FETCH_HEAD","ref":"refs/heads/master","tagName":"test/v1.4.5","branch":"gh-actions","tags":["test/v1.4.5","test/v1.4","test/v1"],"updated_at":"2020-08-25T13:12:15.156Z"}

lib/main.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"use strict";
2+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4+
return new (P || (P = Promise))(function (resolve, reject) {
5+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8+
step((generator = generator.apply(thisArg, _arguments || [])).next());
9+
});
10+
};
11+
Object.defineProperty(exports, "__esModule", { value: true });
12+
const path_1 = require("path");
13+
const core_1 = require("@actions/core");
14+
const context_1 = require("@actions/github/lib/context");
15+
const github_action_helper_1 = require("@technote-space/github-action-helper");
16+
const process_1 = require("./process");
17+
const run = () => __awaiter(void 0, void 0, void 0, function* () {
18+
const logger = new github_action_helper_1.Logger();
19+
const context = new context_1.Context();
20+
github_action_helper_1.ContextHelper.showActionInfo(path_1.resolve(__dirname, '..'), logger, context);
21+
yield process_1.execute(logger, github_action_helper_1.Utils.getOctokit(), context);
22+
});
23+
run().catch(error => {
24+
console.log(error);
25+
core_1.setFailed(error.message);
26+
});

lib/process.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
"use strict";
2+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4+
return new (P || (P = Promise))(function (resolve, reject) {
5+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8+
step((generator = generator.apply(thisArg, _arguments || [])).next());
9+
});
10+
};
11+
Object.defineProperty(exports, "__esModule", { value: true });
12+
exports.execute = void 0;
13+
const core_1 = require("@actions/core");
14+
const misc_1 = require("./utils/misc");
15+
const workflow_1 = require("./utils/workflow");
16+
exports.execute = (logger, octokit, context) => __awaiter(void 0, void 0, void 0, function* () {
17+
if (misc_1.isExcludeContext(context)) {
18+
logger.info('This is not target context.');
19+
core_1.setOutput('ids', '');
20+
return;
21+
}
22+
const runId = misc_1.getRunId();
23+
logger.info('run id: %d', runId);
24+
const workflowId = yield workflow_1.getWorkflowId(octokit, context);
25+
logger.info('workflow id: %d', workflowId);
26+
const runs = yield workflow_1.getWorkflowRuns(workflowId, logger, octokit, context);
27+
logger.log();
28+
const currentRun = runs.find(run => run.id === runId);
29+
if (!currentRun) {
30+
logger.info(logger.c('current run not found', { color: 'yellow' }));
31+
core_1.setOutput('ids', '');
32+
return;
33+
}
34+
const runsWithCreatedAtTime = runs.filter(run => run.id !== runId).map(run => (Object.assign(Object.assign({}, run), { createdAt: Date.parse(run.created_at) })));
35+
const createdAt = Date.parse(currentRun.created_at);
36+
if (runsWithCreatedAtTime.find(run => run.createdAt > createdAt)) {
37+
logger.info(logger.c('newer job exists', { color: 'yellow' }));
38+
core_1.setOutput('ids', '');
39+
return;
40+
}
41+
logger.startProcess('Cancelling...');
42+
yield Promise.all(runsWithCreatedAtTime.map(run => {
43+
logger.log('cancel: %d', run.id);
44+
return workflow_1.cancelWorkflowRun(run.id, octokit, context);
45+
}));
46+
logger.info('total: %d', runsWithCreatedAtTime.length);
47+
core_1.setOutput('ids', runsWithCreatedAtTime.map(run => run.id).join(','));
48+
logger.endProcess();
49+
});

lib/utils/misc.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"use strict";
2+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4+
return new (P || (P = Promise))(function (resolve, reject) {
5+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8+
step((generator = generator.apply(thisArg, _arguments || [])).next());
9+
});
10+
};
11+
Object.defineProperty(exports, "__esModule", { value: true });
12+
exports.getTargetBranch = exports.getRunId = exports.isNotExcludeRun = exports.isExcludeContext = void 0;
13+
const core_1 = require("@actions/core");
14+
const github_action_helper_1 = require("@technote-space/github-action-helper");
15+
const getMergeMessagePrefix = () => github_action_helper_1.Utils.getPrefixRegExp(core_1.getInput('MERGE_MESSAGE_PREFIX'));
16+
const isExcludeMerged = () => github_action_helper_1.Utils.getBoolValue(core_1.getInput('EXCLUDE_MERGED'));
17+
const isExcludeTagPush = () => github_action_helper_1.Utils.getBoolValue(core_1.getInput('EXCLUDE_TAG_PUSH'));
18+
exports.isExcludeContext = (context) => github_action_helper_1.ContextHelper.isPush(context) && ((isExcludeTagPush() && github_action_helper_1.Utils.isTagRef(context)) ||
19+
(isExcludeMerged() && getMergeMessagePrefix().test(context.payload.head_commit.message)));
20+
exports.isNotExcludeRun = (run) => !isExcludeMerged() || !getMergeMessagePrefix().test(run.head_commit.message);
21+
exports.getRunId = () => Number(process.env.GITHUB_RUN_ID);
22+
exports.getTargetBranch = (octokit, context) => __awaiter(void 0, void 0, void 0, function* () {
23+
if (context.payload.pull_request) {
24+
return context.payload.pull_request.head.ref;
25+
}
26+
return github_action_helper_1.Utils.getBranch(context) || undefined;
27+
});

lib/utils/workflow.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
"use strict";
2+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4+
return new (P || (P = Promise))(function (resolve, reject) {
5+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8+
step((generator = generator.apply(thisArg, _arguments || [])).next());
9+
});
10+
};
11+
Object.defineProperty(exports, "__esModule", { value: true });
12+
exports.cancelWorkflowRun = exports.getWorkflowRuns = exports.getWorkflowId = void 0;
13+
const misc_1 = require("./misc");
14+
exports.getWorkflowId = (octokit, context) => __awaiter(void 0, void 0, void 0, function* () {
15+
const run = yield octokit.actions.getWorkflowRun({
16+
owner: context.repo.owner,
17+
repo: context.repo.repo,
18+
'run_id': Number(process.env.GITHUB_RUN_ID),
19+
});
20+
const matches = run.data.workflow_url.match(/\d+$/);
21+
if (!matches) {
22+
throw new Error('Invalid workflow run');
23+
}
24+
return Number(matches[0]);
25+
});
26+
exports.getWorkflowRuns = (workflowId, logger, octokit, context) => __awaiter(void 0, void 0, void 0, function* () {
27+
const options = Object.assign(Object.assign({}, context.repo), { 'workflow_id': workflowId, status: 'in_progress', event: context.eventName });
28+
const branch = yield misc_1.getTargetBranch(octokit, context);
29+
logger.log('target event: %s', logger.c(context.eventName, { color: 'green' }));
30+
if (branch) {
31+
logger.log('target branch: %s', logger.c(branch, { color: 'green' }));
32+
options.branch = branch;
33+
}
34+
return (yield octokit.paginate(octokit.actions.listWorkflowRuns,
35+
// eslint-disable-next-line no-warning-comments
36+
// TODO: remove ts-ignore after fixed types (https://github.com/octokit/types.ts/issues/122)
37+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
38+
// @ts-ignore
39+
options)).map(run => run).filter(misc_1.isNotExcludeRun);
40+
});
41+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
42+
exports.cancelWorkflowRun = (runId, octokit, context) => __awaiter(void 0, void 0, void 0, function* () {
43+
return octokit.actions.cancelWorkflowRun(Object.assign(Object.assign({}, context.repo), { 'run_id': runId }));
44+
});

0 commit comments

Comments
 (0)