diff --git a/README.md b/README.md index ea555e6..32baa43 100644 --- a/README.md +++ b/README.md @@ -63,3 +63,30 @@ while you could _technically_ configure this for a public repository (using a personal access token), I can't think of a way to do this safely without exposing a privileged token to pull requests -- if you have any ideas, please leave an issue! + +### run precommit against changed files + +to use the `changed` parameter, you must make sure your checkout contains enough depth +to compare against. + +here's an example which runs during pull requests and executes precommit against the files changed +from the target branch: + +```yaml +name: precommit + +on: [pull_request] +jobs: + precommit: + runs-on: ubuntu-latest + steps: + - name: checkout code + uses: actions/checkout@v2 + - run: | + git fetch --no-tags --prune --unshallow + - uses: actions/setup-python@v2 + - uses: pre-commit/action@v1.0.1 + with: + changed: true + base: ${{ github.event.pull_request.head.sha }} +``` diff --git a/action.yml b/action.yml index 941ec1d..b0379bf 100644 --- a/action.yml +++ b/action.yml @@ -4,6 +4,14 @@ inputs: token: description: github token to clone / push with required: false + changed: + description: only run against changed files in this commit. requires advanced checkout. + required: false + default: "false" + base: + description: base git ref for 'changed' parameter. requires advanced checkout. + required: false + default: "master" runs: - using: 'node12' - main: 'dist/index.js' + using: "node12" + main: "dist/index.js" diff --git a/index.js b/index.js index 64bdac2..fe55523 100644 --- a/index.js +++ b/index.js @@ -2,24 +2,57 @@ const core = require('@actions/core'); const exec = require('@actions/exec'); const github = require('@actions/github'); -const ARGS = [ +const ALL_ARGS = [ 'run', '--all-files', '--show-diff-on-failure', '--color=always' ]; +const CHANGED_ARGS = [ + 'run', '--show-diff-on-failure', '--color=always', '--files' +]; + + function addToken(url, token) { return url.replace(/^https:\/\//, `https://x-access-token:${token}@`) } +async function getChangedFiles() { + + let changedFiles = ''; + const baseRef = core.getInput('base'); + + const options = {}; + options.listeners = { + stdout: (data) => { + changedFiles += data.toString(); + }, + }; + + await exec.exec('git', ['diff', baseRef, '--name-only'], options); + + return changedFiles; +} + async function main() { + var ARGS + await core.group('install pre-commit', async () => { await exec.exec('pip', ['install', 'pre-commit']); await exec.exec('pip', ['freeze', '--local']); }); + if (core.getInput('changed')) { + ARGS = CHANGED_ARGS; + fileList = await getChangedFiles(); + ARGS.push(fileList); + } + else { + ARGS = ALL_ARGS; + } + const token = core.getInput('token'); const pr = github.context.payload.pull_request; const push = !!token && !!pr; - const ret = await exec.exec('pre-commit', ARGS, {ignoreReturnCode: push}); + const ret = await exec.exec('pre-commit', ARGS, { ignoreReturnCode: push }); if (ret && push) { // actions do not run on pushes made by actions. // need to make absolute sure things are good before pushing @@ -27,7 +60,7 @@ async function main() { await exec.exec('pre-commit', ARGS); const diff = await exec.exec( - 'git', ['diff', '--quiet'], {ignoreReturnCode: true} + 'git', ['diff', '--quiet'], { ignoreReturnCode: true } ); if (diff) { await core.group('push fixes', async () => {