Initial commit

This commit is contained in:
Takayuki Nakata 2022-11-01 16:07:10 +09:00
parent a1c82b8382
commit 88f670892d
6 changed files with 271 additions and 25 deletions

View file

@ -1,11 +1,51 @@
name: 'Your name here'
name: 'Run Clippy with reviewdog'
description: 'Provide a description here'
author: 'Your name or organization here'
inputs:
milliseconds: # change this
github_token:
description: "GITHUB_TOKEN."
required: true
description: 'input description here'
default: 'default value if applicable'
default: ${{ github.token }}
tool_name:
description: "Tool name to use for reviewdog reporter"
required: false
default: "clippy"
level:
description: "Report level for reviewdog [info,warning,error]"
required: false
default: "error"
reporter:
description: "Reporter of reviewdog command [github-pr-check,github-pr-review,github-check]."
required: false
default: "github-pr-check"
filter_mode:
description: |
Filtering for the reviewdog command [added,diff_context,file,nofilter].
Default is added.
required: false
default: "added"
fail_on_error:
description: |
Exit code for reviewdog when errors are found [true,false]
Default is `false`.
required: false
default: "false"
reviewdog_flags:
description: "Additional reviewdog flags"
required: false
default: ""
workdir:
description: "Working directory relative to the root directory."
required: false
default: "."
reviewdog_version:
description: "the version of reviewdog"
required: false
default: latest
cache:
deprecation: "enable cache"
default: true
required: false
runs:
using: 'node16'
main: 'dist/index.js'

77
package-lock.json generated
View file

@ -9,7 +9,10 @@
"version": "0.0.0",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.10.0"
"@actions/core": "1.10.0",
"@actions/exec": "1.1.1",
"@actions/http-client": "2.0.1",
"@actions/tool-cache": "2.0.1"
},
"devDependencies": {
"@types/node": "^18.11.0",
@ -34,6 +37,14 @@
"uuid": "^8.3.2"
}
},
"node_modules/@actions/exec": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.1.tgz",
"integrity": "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==",
"dependencies": {
"@actions/io": "^1.0.1"
}
},
"node_modules/@actions/http-client": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
@ -42,6 +53,33 @@
"tunnel": "^0.0.6"
}
},
"node_modules/@actions/io": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.2.tgz",
"integrity": "sha512-d+RwPlMp+2qmBfeLYPLXuSRykDIFEwdTA0MMxzS9kh4kvP1ftrc/9fzy6pX6qAjthdXruHQ6/6kjT/DNo5ALuw=="
},
"node_modules/@actions/tool-cache": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@actions/tool-cache/-/tool-cache-2.0.1.tgz",
"integrity": "sha512-iPU+mNwrbA8jodY8eyo/0S/QqCKDajiR8OxWTnSk/SnYg0sj8Hp4QcUEVC1YFpHWXtrfbQrE13Jz4k4HXJQKcA==",
"dependencies": {
"@actions/core": "^1.2.6",
"@actions/exec": "^1.0.0",
"@actions/http-client": "^2.0.1",
"@actions/io": "^1.1.1",
"semver": "^6.1.0",
"uuid": "^3.3.2"
}
},
"node_modules/@actions/tool-cache/node_modules/uuid": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
"deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
"bin": {
"uuid": "bin/uuid"
}
},
"node_modules/@babel/code-frame": {
"version": "7.12.11",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz",
@ -9328,7 +9366,6 @@
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
}
@ -10301,6 +10338,14 @@
"uuid": "^8.3.2"
}
},
"@actions/exec": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.1.tgz",
"integrity": "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==",
"requires": {
"@actions/io": "^1.0.1"
}
},
"@actions/http-client": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
@ -10309,6 +10354,31 @@
"tunnel": "^0.0.6"
}
},
"@actions/io": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.2.tgz",
"integrity": "sha512-d+RwPlMp+2qmBfeLYPLXuSRykDIFEwdTA0MMxzS9kh4kvP1ftrc/9fzy6pX6qAjthdXruHQ6/6kjT/DNo5ALuw=="
},
"@actions/tool-cache": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@actions/tool-cache/-/tool-cache-2.0.1.tgz",
"integrity": "sha512-iPU+mNwrbA8jodY8eyo/0S/QqCKDajiR8OxWTnSk/SnYg0sj8Hp4QcUEVC1YFpHWXtrfbQrE13Jz4k4HXJQKcA==",
"requires": {
"@actions/core": "^1.2.6",
"@actions/exec": "^1.0.0",
"@actions/http-client": "^2.0.1",
"@actions/io": "^1.1.1",
"semver": "^6.1.0",
"uuid": "^3.3.2"
},
"dependencies": {
"uuid": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
}
}
},
"@babel/code-frame": {
"version": "7.12.11",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz",
@ -17239,8 +17309,7 @@
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
},
"shebang-command": {
"version": "2.0.0",

View file

@ -25,7 +25,10 @@
"author": "",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.10.0"
"@actions/core": "1.10.0",
"@actions/exec": "1.1.1",
"@actions/http-client": "2.0.1",
"@actions/tool-cache": "2.0.1"
},
"devDependencies": {
"@types/node": "^18.11.0",

78
src/installer.ts Normal file
View file

@ -0,0 +1,78 @@
import * as path from "path";
import * as core from "@actions/core";
import * as tc from "@actions/tool-cache";
import * as http from "@actions/http-client";
export async function installReviewdog(tag: string, directory: string): Promise<string> {
const owner = "reviewdog";
const repo = "reviewdog";
const version = await tagToVersion(tag, owner, repo);
// get the os information
let platform = process.platform.toString();
let ext = "";
switch (platform) {
case "darwin":
platform = "Darwin";
break;
case "linux":
platform = "Linux";
break;
case "win32":
platform = "Windows";
ext = ".exe";
break;
default:
throw new Error(`unsupported platform: ${platform}`);
}
// get the arch information
let arch: string = process.arch;
switch (arch) {
case "x64":
arch = "x86_64";
break;
case "arm64":
break;
case "x32":
arch = "i386";
break;
default:
throw new Error(`unsupported arch: ${arch}`);
}
const url = `https://github.com/${owner}/${repo}/releases/download/v${version}/reviewdog_${version}_${platform}_${arch}.tar.gz`;
core.info(`downloading from ${url}`);
const archivePath = await tc.downloadTool(url);
core.info(`extracting`);
const extractedDir = await tc.extractTar(archivePath, directory);
return path.join(extractedDir, `reviewdog${ext}`);
}
async function tagToVersion(tag: string, owner: string, repo: string): Promise<string> {
core.info(`finding a release for ${tag}`);
interface Release {
tag_name: string;
}
const url = `https://github.com/${owner}/${repo}/releases/${tag}`;
const client = new http.HttpClient("clippy-action/v1");
const headers = { [http.Headers.Accept]: "application/json" };
const response = await client.getJson<Release>(url, headers);
if (response.statusCode != http.HttpCodes.OK) {
core.error(`${url} returns unexpected HTTP status code: ${response.statusCode}`);
}
if (!response.result) {
throw new Error(
`unable to find '${tag}' - use 'latest' or see https://github.com/${owner}/${repo}/releases for details`
);
}
let realTag = response.result.tag_name;
// if version starts with 'v', remove it
realTag = realTag.replace(/^v/, "");
return realTag;
}

View file

@ -1,19 +1,84 @@
import { promises as fs } from "fs";
import * as os from "os";
import * as path from "path";
import * as core from '@actions/core'
import {wait} from './wait'
import * as exec from '@actions/exec';
import * as installer from "./installer"
async function run(): Promise<void> {
const runnerTmpdir = process.env["RUNNER_TEMP"] || os.tmpdir();
const tmpdir = await fs.mkdtemp(path.join(runnerTmpdir, "reviewdog-"));
try {
const ms: string = core.getInput('milliseconds')
core.debug(`Waiting ${ms} milliseconds ...`) // debug is only output if you set the secret `ACTIONS_STEP_DEBUG` to true
const reviewdogVersion = core.getInput("reviewdog_version") || "latest";
const toolName = core.getInput("tool_name") || "golangci";
const level = core.getInput("level") || "error";
const reporter = core.getInput("reporter") || "github-pr-check";
const filterMode = core.getInput("filter_mode") || "added";
const failOnError = core.getInput("fail_on_error") || "false";
const reviewdogFlags = core.getInput("reviewdog_flags");
const workdir = core.getInput("workdir") || ".";
const cwd = path.relative(process.env["GITHUB_WORKSPACE"] || process.cwd(), workdir);
core.debug(new Date().toTimeString())
await wait(parseInt(ms, 10))
core.debug(new Date().toTimeString())
await core.group("Installing Rust ...", async () => {
// TODO
});
core.setOutput('time', new Date().toTimeString())
const reviewdog = await core.group(
"🐶 Installing reviewdog ... https://github.com/reviewdog/reviewdog",
async () => {
return await installer.installReviewdog(reviewdogVersion, tmpdir);
}
);
const code = await core.group("Running Clippy with reviewdog 🐶 ...", async (): Promise<number> => {
const output = await exec.getExecOutput(
"cargo",
["clippy", "--output-format", "short"],
{
cwd,
ignoreReturnCode: true,
}
);
process.env["REVIEWDOG_GITHUB_API_TOKEN"] = core.getInput("github_token");
return await exec.exec(
reviewdog,
[
"-f=clippy",
`-name=${toolName}`,
`-reporter=${reporter}`,
`-filter-mode=${filterMode}`,
`-fail-on-error=${failOnError}`,
`-level=${level}`,
...parse(reviewdogFlags),
],
{
cwd,
input: Buffer.from(output.stdout, "utf-8"),
ignoreReturnCode: true,
}
);
});
if (code != 0) {
core.setFailed(`reviewdog exited with status code: ${code}`);
}
} catch (error) {
if (error instanceof Error) core.setFailed(error.message)
}
}
function parse(flags: string): string[] {
flags = flags.trim();
if (flags === "") {
return [];
}
// TODO: need to simulate bash?
return flags.split(/\s+/);
}
run()

View file

@ -1,9 +0,0 @@
export async function wait(milliseconds: number): Promise<string> {
return new Promise(resolve => {
if (isNaN(milliseconds)) {
throw new Error('milliseconds not a number')
}
setTimeout(() => resolve('done!'), milliseconds)
})
}