From a90d121c4ae8e9ec2dade878eb45a57d6663aade Mon Sep 17 00:00:00 2001 From: MeilCli Date: Mon, 10 May 2021 10:40:27 +0900 Subject: [PATCH] update document --- .prettierignore | 1 + README.md | 85 +++++++++-- documents/lint-result.md | 19 +++ documents/operator/add.md | 63 ++++++++ documents/operator/context.md | 35 +++++ documents/operator/distinct.md | 54 +++++++ documents/operator/filter-by-file-changed.md | 34 +++++ documents/operator/filter.md | 52 +++++++ documents/operator/map.md | 54 +++++++ documents/oss-or-dependabot-usage.md | 146 +++++++++++++++++++ documents/report-lint-result.md | 97 ++++++++++++ documents/transformer/checkstyle.md | 20 +++ documents/transformer/eslint.md | 20 +++ documents/transformer/junit.md | 28 ++++ 14 files changed, 698 insertions(+), 10 deletions(-) create mode 100644 .prettierignore create mode 100644 documents/lint-result.md create mode 100644 documents/operator/add.md create mode 100644 documents/operator/context.md create mode 100644 documents/operator/distinct.md create mode 100644 documents/operator/filter-by-file-changed.md create mode 100644 documents/operator/filter.md create mode 100644 documents/operator/map.md create mode 100644 documents/oss-or-dependabot-usage.md create mode 100644 documents/report-lint-result.md create mode 100644 documents/transformer/checkstyle.md create mode 100644 documents/transformer/eslint.md create mode 100644 documents/transformer/junit.md diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..2e1fa2d5 --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +*.md \ No newline at end of file diff --git a/README.md b/README.md index d178d6e9..3f4ed105 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,85 @@ # common-lint-reporter - This is generalized lint reporter action +Focuses on: +- Many lint file format support +- Flexible extendable reporting +- Multiple report format support, as check-run, comment or inline-comment + +### Specification +Current supporting lint file format: +- eslint(JSON) +- checkstyle +- junit + - compatibility: eslint + +### Feature request +Now, this action is WIP. Features are not enough and should improve about transformer and operator. If you have nice idea, please send as issue:heart: + ## Usage +### Basic information +This action have 3 steps. Flexible and extendable are realized by separating step -ToDo +1. Transform lint report file to common lint format file +1. Operate converting common lint file +1. Report common lint to GitHub -## License +### Quick usage +```yml +name: CI +on: + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: 12 + - run: npm install + - run: npm run build + - run: npm run lint + continue-on-error: true + - uses: MeilCli/common-lint-reporter/transformer/eslint@0 + with: + # your output path + report_files: | + eslint_report.json + - uses: MeilCli/common-lint-reporter/operator/filter-by-file-changed@v0 + - uses: MeilCli/common-lint-reporter@v0 + with: + report_type: 'check_run' + report_name: 'Lint Report' +``` + +### Detail information +- General + - [Usage of oss or using dependabot repository](documents/oss-or-dependabot-usage.md) + - [Report lint result](documents/report-lint-result.md) +- Transformer + - [eslint](documents/transformer/eslint.md) + - [checkstyle](documents/transformer/checkstyle.md) + - [junit](documents/transformer/junit.md) +- Operator + - [add](documents/operator/add.md) + - [distinct](documents/operator/distinct.md) + - [filter](documents/operator/filter.md) + - [filter-by-file-changed](documents/operator/filter-by-file-changed.md) + - [map](documents/operator/map.md) +- Reference + - [Lint result file format](documents/lint-result.md) + - [Operator context](documents/operator/context.md) + +## License MIT License ### Using - -- [actions/toolkit](https://github.com/actions/toolkit), published by [MIT License](https://github.com/actions/toolkit/blob/master/LICENSE.md) -- [apollo-client](https://github.com/apollographql/apollo-client), published by [MIT License](https://github.com/apollographql/apollo-client/blob/main/LICENSE) -- [cross-fetch](https://github.com/lquixada/cross-fetch), published by [MIT License](https://github.com/lquixada/cross-fetch/blob/main/LICENSE) -- [graphql](https://github.com/graphql/graphql-js), published by [MIT License](https://github.com/graphql/graphql-js/blob/main/LICENSE) -- [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser), published by [MIT License](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/LICENSE) -- [he](https://github.com/mathiasbynens/he), published by [MIT License](https://github.com/mathiasbynens/he/blob/master/LICENSE-MIT.txt) +- [actions/toolkit](https://github.com/actions/toolkit), published by [MIT License](https://github.com/actions/toolkit/blob/master/LICENSE.md) +- [apollo-client](https://github.com/apollographql/apollo-client), published by [MIT License](https://github.com/apollographql/apollo-client/blob/main/LICENSE) +- [cross-fetch](https://github.com/lquixada/cross-fetch), published by [MIT License](https://github.com/lquixada/cross-fetch/blob/main/LICENSE) +- [graphql](https://github.com/graphql/graphql-js), published by [MIT License](https://github.com/graphql/graphql-js/blob/main/LICENSE) +- [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser), published by [MIT License](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/LICENSE) +- [he](https://github.com/mathiasbynens/he), published by [MIT License](https://github.com/mathiasbynens/he/blob/master/LICENSE-MIT.txt) diff --git a/documents/lint-result.md b/documents/lint-result.md new file mode 100644 index 00000000..cdbae88f --- /dev/null +++ b/documents/lint-result.md @@ -0,0 +1,19 @@ +# Lint result file format +Lint result file format is simply JSON + +```ts +type LintResultLevel = "notice" | "warning" | "failure"; + +interface LintResult { + path: string; + rule: string; + message: string; + startLine: number | undefined; + endLine: number | undefined; + startColumn: number | undefined; + endColumn: number | undefined; + level: LintResultLevel; +} +``` + +Lint result json is array of `LintResult` \ No newline at end of file diff --git a/documents/operator/add.md b/documents/operator/add.md new file mode 100644 index 00000000..0c5b77a5 --- /dev/null +++ b/documents/operator/add.md @@ -0,0 +1,63 @@ +# Operator of add +A action for manually add lint result +```yml +- uses: MeilCli/common-lint-reporter/operator/add@v0 + with: + function: | + () => add({path: "test/path3.txt", rule: "test-rule-ext", message: "hello", level: "notice"}) +``` + +## Option +### Input +- `github_token`: + - github app token, using to read and write repository + - required + - default: `${{ github.token }}` +- `workspace_path`: + - workspace path, using to convert relative path from absolute path +- `repository`: + - running repository, format: owner/repository +- `pull_request`: + - running pull request number +- `commit_sha`: + - running commit sha +- `report_files`: + - report file glob pattern + - required + - default: `common_lint.json` +- `report_files_follow_symbolic_links`: + - report file glob pattern option + - value: `true` or `false` +- `use_api_context` + - if this option is enabled, set information to context using api + - more information? see [this](context.md) + - value: `true` or `false` + - default: `false` +- `function`: + - the function of this action + - required +- `output_path`: + - output path + - required + - default: `common_lint.json` + +## function input +`function` must be JavaScript's function, such as named-function, no-named-function or lambda-function + +example: +```js +function run() { + add({ + path: "test/file.txt", + message: "test message", + rule: "test_rule_1", + startLine: 1, + startColumn: 10, + endLine: 1, + endColumn: 20, + level: "failure", + }) +} +``` + +`add` function argument? see [this](../lint-result.md) \ No newline at end of file diff --git a/documents/operator/context.md b/documents/operator/context.md new file mode 100644 index 00000000..4f5f3a54 --- /dev/null +++ b/documents/operator/context.md @@ -0,0 +1,35 @@ +# Operator context +Some functional operator can use context information + +Example: +```yml +- uses: MeilCli/common-lint-reporter/operator/... + with: + function: | + () => github.repository +``` + +## Context specification +```ts +interface GitHubContext { + workspacePath: string; + trimPath: (filePath: string) => string; + owner: string; + repository: string; + pullRequest: number | null; + commitSha: string; + api: ApiContext | null; +} + +interface ApiContext { + changedFiles: ChangedFile[]; +} + +interface ChangedFile { + path: string; + additions: number; + deletions: number; +} +``` + +`github.api` is only usable when `use_api_context` option is `true` \ No newline at end of file diff --git a/documents/operator/distinct.md b/documents/operator/distinct.md new file mode 100644 index 00000000..c139e1ea --- /dev/null +++ b/documents/operator/distinct.md @@ -0,0 +1,54 @@ +# Operator of distinct +A action for distinct duplicated lint result +```yml +- uses: MeilCli/common-lint-reporter/operator/distinct@v0 + with: + function: | + (x) => x.path + x.startLine +``` + +## Option +### Input +- `github_token`: + - github app token, using to read and write repository + - required + - default: `${{ github.token }}` +- `workspace_path`: + - workspace path, using to convert relative path from absolute path +- `repository`: + - running repository, format: owner/repository +- `pull_request`: + - running pull request number +- `commit_sha`: + - running commit sha +- `report_files`: + - report file glob pattern + - required + - default: `common_lint.json` +- `report_files_follow_symbolic_links`: + - report file glob pattern option + - value: `true` or `false` +- `use_api_context` + - if this option is enabled, set information to context using api + - more information? see [this](context.md) + - value: `true` or `false` + - default: `false` +- `function`: + - the function of this action + - required +- `output_path`: + - output path + - required + - default: `common_lint.json` + +## function input +`function` must be JavaScript's function, such as named-function, no-named-function or lambda-function + +example: +```js +function distinct(x) { + return x.path + x.startLine +} +``` + +Returning value is key of deduplication. If return same key, output first value to lint-result \ No newline at end of file diff --git a/documents/operator/filter-by-file-changed.md b/documents/operator/filter-by-file-changed.md new file mode 100644 index 00000000..fd144239 --- /dev/null +++ b/documents/operator/filter-by-file-changed.md @@ -0,0 +1,34 @@ +# Operator of filter-by-file-changed +A action for filter lint result by PullRequest's changed files +```yml +- uses: MeilCli/common-lint-reporter/operator/filter-by-file-changed@v0 +``` + +**If you use `workflow_run` workflow, must set `pull_request` input. see [this document](../oss-or-dependabot-usage.md)** + +## Option +### Input + +- `github_token`: + - github app token, using to read and write repository + - required + - default: `${{ github.token }}` +- `workspace_path`: + - workspace path, using to convert relative path from absolute path +- `repository`: + - running repository, format: owner/repository +- `pull_request`: + - running pull request number +- `commit_sha`: + - running commit sha +- `report_files`: + - report file glob pattern + - required + - default: `common_lint.json` +- `report_files_follow_symbolic_links`: + - report file glob pattern option + - value: `true` or `false` +- `output_path`: + - output path + - required + - default: `common_lint.json` diff --git a/documents/operator/filter.md b/documents/operator/filter.md new file mode 100644 index 00000000..323fe8c0 --- /dev/null +++ b/documents/operator/filter.md @@ -0,0 +1,52 @@ +# Operator of filter +A action for filter lint result +```yml +- uses: MeilCli/common-lint-reporter/operator/filter@v0 + with: + function: | + (x) => x.path != "test/path1.txt" +``` + +## Option +### Input +- `github_token`: + - github app token, using to read and write repository + - required + - default: `${{ github.token }}` +- `workspace_path`: + - workspace path, using to convert relative path from absolute path +- `repository`: + - running repository, format: owner/repository +- `pull_request`: + - running pull request number +- `commit_sha`: + - running commit sha +- `report_files`: + - report file glob pattern + - required + - default: `common_lint.json` +- `report_files_follow_symbolic_links`: + - report file glob pattern option + - value: `true` or `false` +- `use_api_context` + - if this option is enabled, set information to context using api + - more information? see [this](context.md) + - value: `true` or `false` + - default: `false` +- `function`: + - the function of this action + - required +- `output_path`: + - output path + - required + - default: `common_lint.json` + +## function input +`function` must be JavaScript's function, such as named-function, no-named-function or lambda-function + +example: +```js +function filter(x) { + return x.level == 'failure' +} +``` diff --git a/documents/operator/map.md b/documents/operator/map.md new file mode 100644 index 00000000..34eb1ae5 --- /dev/null +++ b/documents/operator/map.md @@ -0,0 +1,54 @@ +# Operator of map +A action for map lint result +```yml +- uses: MeilCli/common-lint-reporter/operator/map@v0 + with: + function: | + (x) => Object.assign(x, {message: "message: " + x.message}) +``` + +## Option +### Input +- `github_token`: + - github app token, using to read and write repository + - required + - default: `${{ github.token }}` +- `workspace_path`: + - workspace path, using to convert relative path from absolute path +- `repository`: + - running repository, format: owner/repository +- `pull_request`: + - running pull request number +- `commit_sha`: + - running commit sha +- `report_files`: + - report file glob pattern + - required + - default: `common_lint.json` +- `report_files_follow_symbolic_links`: + - report file glob pattern option + - value: `true` or `false` +- `use_api_context` + - if this option is enabled, set information to context using api + - more information? see [this](context.md) + - value: `true` or `false` + - default: `false` +- `function`: + - the function of this action + - required +- `output_path`: + - output path + - required + - default: `common_lint.json` + +## function input +`function` must be JavaScript's function, such as named-function, no-named-function or lambda-function + +example: +```js +function map(x) { + return { ...x, message: `[${x.rule}] ${x.message}` } +} +``` + +Specification of returning value? see [this](../lint-result.md) \ No newline at end of file diff --git a/documents/oss-or-dependabot-usage.md b/documents/oss-or-dependabot-usage.md new file mode 100644 index 00000000..11a4bab4 --- /dev/null +++ b/documents/oss-or-dependabot-usage.md @@ -0,0 +1,146 @@ +# Usage of oss or using dependabot repository +`github-actions` token has not `write` permission at triggered by `pull_request` that created from forked repository or created by dependabot. This reason is for security + +So, such repository's `pull_request` workflow can not report lint result. In this case, you can use `workflow_run` workflow instead of the normal workflow + +ref: [Keeping your GitHub Actions and workflows secure: Preventing pwn requests](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/) + +## Quick example +```yml +# ci.yml +name: CI + +on: + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: 12 + - run: npm install + - run: npm run build + - run: npm run lint:report + continue-on-error: true + - uses: actions/upload-artifact@v2 + with: + name: eslint + # your output path + path: eslint_report.json +``` +```yml +# report.yml +name: Report + +on: + workflow_run: + workflows: ['CI'] + types: + - completed + +jobs: + lint: + runs-on: ubuntu-latest + if: github.event.workflow_run.conclusion == 'success' + steps: + - uses: actions/checkout@v2 + - name: Download artifact + uses: dawidd6/action-download-artifact@v2 + with: + workflow: ci.yml + run_id: ${{ github.event.workflow_run.id }} + name: eslint + - uses: MeilCli/common-lint-reporter/transformer/eslint@v0 + with: + report_files: | + eslint_report.json + - name: Report lint result + uses: MeilCli/common-lint-reporter@v0 + with: + report_type: 'check_run' + report_name: 'Lint Report' +``` + +## If use pull request information +A problem of `workflow_run` is to not be able to use information of pull request. This reason is `workflow_run` context has not PullRequestPayload + +So, this action is prepared export-import pull request context tool!! + +```yml +# ci.yml +name: CI + +on: + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: 12 + - run: npm install + - run: npm run build + - run: npm run lint:report + continue-on-error: true + - uses: actions/upload-artifact@v2 + with: + name: eslint + # your output path + path: eslint_report.json + # export and updload context + - uses: MeilCli/common-lint-reporter/utils/export-context@v0 + - uses: actions/upload-artifact@v2 + with: + name: lint_context + path: common_lint_context.json +``` +```yml +# report.yml +name: Report + +on: + workflow_run: + workflows: ['CI'] + types: + - completed + +jobs: + lint: + runs-on: ubuntu-latest + if: github.event.workflow_run.conclusion == 'success' + steps: + - uses: actions/checkout@v2 + - name: Download artifact + uses: dawidd6/action-download-artifact@v2 + with: + workflow: ci.yml + run_id: ${{ github.event.workflow_run.id }} + name: eslint + # download and import context + - name: Download artifact + uses: dawidd6/action-download-artifact@v2 + with: + workflow: ci.yml + run_id: ${{ github.event.workflow_run.id }} + name: lint_context + - uses: MeilCli/common-lint-reporter/utils/import-context@v0 + id: lint_context + - uses: MeilCli/common-lint-reporter/transformer/eslint@v0 + with: + report_files: | + eslint_report.json + - name: Report lint result + uses: MeilCli/common-lint-reporter@v0 + with: + # inline_comment can use only provided pull_request when in this situation + report_type: 'inline_comment' + report_name: 'Lint Report' + # set the pull_request number + pull_request: ${{ steps.lint_context.outputs.pull_request }} +``` \ No newline at end of file diff --git a/documents/report-lint-result.md b/documents/report-lint-result.md new file mode 100644 index 00000000..a9a7fb33 --- /dev/null +++ b/documents/report-lint-result.md @@ -0,0 +1,97 @@ +# Report lint result +common-lint-reporter's final step, it's report lint result to GitHub + +```yml +- uses: MeilCli/common-lint-reporter@v0 + with: + report_type: 'check_run' + report_name: 'Lint Report' +``` + +## Reporter type +### Check run +Report lint-result as check-run annotations or check-run summary + +Check-run is based on Commit, so this reporter type can use target of Commit or PullRequest + +### Comment +Report lint-result as PullRequest comment + +This reporter type is only usable when provided `pull_request`. +common-lint-reporter find `pull_request` number automally. but, if use `workflow_run` workflow, cannot find `pull_request` number. +more inforemation: [this](oss-or-dependabot-usage.md) + +### Inline comment +Report lint-result as PullRequest review comment or comment + +This reporter type is only usable when provided `pull_request`. +common-lint-reporter find `pull_request` number automally. but, if use `workflow_run` workflow, cannot find `pull_request` number. +more inforemation: [this](oss-or-dependabot-usage.md) + +#### Outdated resolver +You can select way to resolve when common-lint-reporter find outdated review comment + +- `resolve_thread`: resolve review thread, but doesn't resolve it when additional comment by anyone +- `force_resolve_thread`: resolve review thread anytime +- `delete_thread`: delete review thread, but doesn't delte it when additional comment by anyone +- `delete_or_force_resolve_thread`: delete review thread, or resolve review thread when additional comment by anyone + +## Option +### Input +- `github_token`: + - github app token, using to read and write repository + - required + - default: `${{ github.token }}` +- `workspace_path`: + - workspace path, using to convert relative path from absolute path +- `repository`: + - running repository, format: owner/repository +- `pull_request`: + - running pull request number +- `commit_sha`: + - running commit sha +- `report_files`: + - report file glob pattern + - required + - default: `common_lint.json` +- `report_files_follow_symbolic_links`: + - report file glob pattern option + - value: `true` or `false` +- `report_name`: + - report name, if multiple report, should be unique name + - required + - default: `Lint report` +- `report_type`: + - report type, value is `check_run` or `comment` or `inline_comment` + - required + - default: `check_run` +- `conclusion_failure_threshold`: + - threshold of conclution as failure + - required + - default: `100` +- `conclusion_failure_weight`: + - weight of reported failure by lint for conclusion + - required + - default: `100` +- `conclusion_warning_weight`: + - weight of reported warning by lint for conclusion + - required + - default: `1` +- `conclusion_notice_weight`: + - weight of reported notice by lint for conclusion + - required + - default: `0` +- `outdated_resolver`: + - inline_comment only option, option of how resolve when found outdated thread + - value: `resolve_thread` or `force_resolve_thread` or `delete_thread` or `delete_or_force_resolve_thread` + - default: `delete_or_force_resolve_thread` + +### Conclusion formula +Conclusion is calculated each lint-level count and weight: +```ts +const score = + noticeCount * option.conclusionNoticeWeight + + warningCount * option.conclusionWarningWeight + + failureCount * option.conclusionFailureWeight; +return score < option.conclusionFailureThreshold ? CheckConclusionState.Success : CheckConclusionState.Failure; +``` \ No newline at end of file diff --git a/documents/transformer/checkstyle.md b/documents/transformer/checkstyle.md new file mode 100644 index 00000000..03a75977 --- /dev/null +++ b/documents/transformer/checkstyle.md @@ -0,0 +1,20 @@ +# Transformer of checkstyle +```yml +- uses: MeilCli/common-lint-reporter/transformer/checkstyle@v0 + with: + report_files: | + checkstyle_report.xml +``` + +## Option +### Input +- `report_files`: + - report file glob pattern + - required +- `report_files_follow_symbolic_links`: + - report file glob pattern option + - value: `true` or `false` +- `output_path`: + - output path + - required + - default: `common_lint.json` \ No newline at end of file diff --git a/documents/transformer/eslint.md b/documents/transformer/eslint.md new file mode 100644 index 00000000..d54d1a19 --- /dev/null +++ b/documents/transformer/eslint.md @@ -0,0 +1,20 @@ +# Transformer of eslint +```yml +- uses: MeilCli/common-lint-reporter/transformer/eslint@v0 + with: + report_files: | + eslint_report.json +``` + +## Option +### Input +- `report_files`: + - report file glob pattern + - required +- `report_files_follow_symbolic_links`: + - report file glob pattern option + - value: `true` or `false` +- `output_path`: + - output path + - required + - default: `common_lint.json` \ No newline at end of file diff --git a/documents/transformer/junit.md b/documents/transformer/junit.md new file mode 100644 index 00000000..4b5e0a21 --- /dev/null +++ b/documents/transformer/junit.md @@ -0,0 +1,28 @@ +# Transformer of junit +```yml +- uses: MeilCli/common-lint-reporter/transformer/junit@v0 + with: + report_files: | + junit_report.xml +``` + +## Compatibility +Many tool can report result as junit format, but each output files are not same formatting. For example, eslint's junit format has path and line information, but other tool's junit format hasn't it + +The compatibility is not needed because this action has standard resolver. But, if tool that is compatibility, will be better experience because transform to have many information + +Now compatibility: +- eslint + +## Option +### Input +- `report_files`: + - report file glob pattern + - required +- `report_files_follow_symbolic_links`: + - report file glob pattern option + - value: `true` or `false` +- `output_path`: + - output path + - required + - default: `common_lint.json` \ No newline at end of file