|
| 1 | +# suggestion-bot |
| 2 | + |
| 3 | +[](https://github.com/microsoft/rnx-kit/actions/workflows/build.yml) |
| 4 | +[](https://www.npmjs.com/package/suggestion-bot) |
| 5 | + |
| 6 | +`suggestion-bot` submits code reviews with suggestions based on your diffs. |
| 7 | + |
| 8 | + |
| 9 | + |
| 10 | +## Usage |
| 11 | + |
| 12 | +``` |
| 13 | +Usage: cli.js [options] [diff | file] |
| 14 | +
|
| 15 | +Submit code reviews with suggestions based on your diffs |
| 16 | +
|
| 17 | +Arguments: |
| 18 | + diff | file the diff or file containing diff to create suggestions from |
| 19 | +
|
| 20 | +Options: |
| 21 | + -h, --help display this help message |
| 22 | + -v, --version display version number |
| 23 | + -m, --message <msg> use the specified message as the PR comment |
| 24 | + -f, --fail fail if comments could not be posted |
| 25 | +
|
| 26 | +Examples: |
| 27 | + # Submit current changes as suggestions |
| 28 | + GITHUB_TOKEN=<secret> suggestion-bot "$(git diff)" |
| 29 | +
|
| 30 | + # Alternatively, pipe to suggestion-bot |
| 31 | + # to avoid escape character issues |
| 32 | + git diff | GITHUB_TOKEN=<secret> suggestion-bot |
| 33 | +``` |
| 34 | + |
| 35 | +If your CI is hosted by Azure DevOps, replace `GITHUB_TOKEN` with |
| 36 | +`AZURE_PERSONAL_ACCESS_TOKEN`. |
| 37 | + |
| 38 | +## Requirements |
| 39 | + |
| 40 | +- Host your code on [GitHub](https://github.com/) |
| 41 | +- `GITHUB_TOKEN` permissions: |
| 42 | + - `pull-requests: write` — required for creating code reviews |
| 43 | + - `issues: write` — fallback in case creating a review fails |
| 44 | + |
| 45 | +-- or -- |
| 46 | + |
| 47 | +- Host your code on [Azure DevOps](https://dev.azure.com/) |
| 48 | +- An Azure DevOps [personal access token][ado-personal-access-token] |
| 49 | + |
| 50 | +## Recipes |
| 51 | + |
| 52 | +- [Using `suggestion-bot` with GitHub Actions](#using-suggestion-bot-with-github-actions) |
| 53 | +- [Using `suggestion-bot` with `clang-format`](#using-suggestion-bot-with-clang-format) |
| 54 | +- [Using `suggestion-bot` with Prettier](#using-suggestion-bot-with-prettier) |
| 55 | + |
| 56 | +### Using `suggestion-bot` with GitHub Actions |
| 57 | + |
| 58 | +1. Install `suggestion-bot` in your project |
| 59 | + |
| 60 | + ```sh |
| 61 | + yarn add suggestion-bot --dev |
| 62 | + ``` |
| 63 | + |
| 64 | +2. Configure your GitHub workflow so `suggestion-bot` can access the |
| 65 | + `GITHUB_TOKEN` secret provided by GitHub via an environment variable with the |
| 66 | + same name: |
| 67 | + |
| 68 | + ```yaml |
| 69 | + # .github/workflows/build.yml |
| 70 | + jobs: |
| 71 | + lint: |
| 72 | + runs-on: ubuntu-latest |
| 73 | + steps: |
| 74 | + - name: Set up Node.js |
| 75 | + uses: actions/setup-node@v6 |
| 76 | + with: |
| 77 | + node-version: 24 |
| 78 | + - name: Checkout |
| 79 | + uses: actions/checkout@v6 |
| 80 | + - name: Install |
| 81 | + run: yarn |
| 82 | + - name: ClangFormat |
| 83 | + if: ${{ github.event_name == 'pull_request' }} |
| 84 | + env: |
| 85 | + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 86 | + run: scripts/clang-format-diff.sh | yarn suggestion-bot |
| 87 | + ``` |
| 88 | +
|
| 89 | +### Using `suggestion-bot` with `clang-format` |
| 90 | + |
| 91 | +Use [`clang-format-diff`][] to format only changed files: |
| 92 | + |
| 93 | +```sh |
| 94 | +curl --silent --show-error --remote-name https://raw.githubusercontent.com/llvm/llvm-project/release/10.x/clang/tools/clang-format/clang-format-diff.py |
| 95 | +git diff --unified=0 --no-color @^ \ |
| 96 | + | python clang-format-diff.py -p1 -regex '.*\.(cpp|cc|c\+\+|cxx|c|cl|h|hh|hpp|m|mm|inc)' -sort-includes \ |
| 97 | + | yarn suggestion-bot |
| 98 | +``` |
| 99 | + |
| 100 | +### Using `suggestion-bot` with Prettier |
| 101 | + |
| 102 | +We must first write a script that pipes [Prettier][]'s output to `diff` so we |
| 103 | +can feed it to `suggestion-bot` later. |
| 104 | + |
| 105 | +```js |
| 106 | +#!/usr/bin/env node |
| 107 | +
|
| 108 | +import { spawnSync } from "node:child_process"; |
| 109 | +import * as fs from "node:fs"; |
| 110 | +import * as prettier from "prettier"; |
| 111 | +import suggest from "suggestion-bot"; |
| 112 | +
|
| 113 | +const diff = process.argv.slice(2).reduce((diff, filepath) => { |
| 114 | + const source = fs.readFileSync(filepath, { encoding: "utf8" }); |
| 115 | + const { stdout } = spawnSync("diff", ["--unified", filepath, "-"], { |
| 116 | + input: prettier.format(source, { filepath }), |
| 117 | + encoding: "utf-8", |
| 118 | + }); |
| 119 | + return diff + stdout; |
| 120 | +}, ""); |
| 121 | +
|
| 122 | +suggest(diff); |
| 123 | +``` |
| 124 | + |
| 125 | +Save the script somewhere, e.g. `scripts/prettier-diff.mjs`, then invoke it with |
| 126 | +Node: |
| 127 | + |
| 128 | +```sh |
| 129 | +node scripts/prettier-diff.mjs $(git ls-files '*.js') |
| 130 | +``` |
| 131 | + |
| 132 | +<!-- References --> |
| 133 | + |
| 134 | +[Prettier]: https://prettier.io/ |
| 135 | +[`clang-format-diff`]: https://clang.llvm.org/docs/ClangFormat.html#script-for-patch-reformatting |
| 136 | +[ado-personal-access-token]: https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=preview-page |
0 commit comments