Skip to content

About

Offers to format pull requests with whatever formatter your project is already using, then formats them on demand. 🧼

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

81 Commits

Folders and files

Repository files navigation

Formatly on Demand

Offers to format pull requests with whatever formatter your project is already using, then formats them on demand. 🚿

πŸ‘ͺ All Contributors: 1 🀝 Code of Conduct: Kept πŸ§ͺ Coverage πŸ“ License: MIT πŸ“¦ npm version πŸ’ͺ TypeScript: Strict

Usage

formatly-on-demand posts a friendly comment when a pull request's files aren't formatted the way your repository formats code. It doesn't touch the branch until the pull request's author or a maintainer comments /formatly to ask it to. Then it formats those files with formatly and pushes a single commit.

Setup

Add three workflow files to your repository.

.github/workflows/formatly-on-demand-detect.yaml checks each pull request:

name: Formatly on Demand Detect

on:
  pull_request: ~

jobs:
  detect:
    uses: JoshuaKGoldberg/formatly-on-demand/.github/workflows/detect.yaml@v0
    with:
      install: pnpm install --frozen-lockfile

.github/workflows/formatly-on-demand-offer.yaml posts the comment:

name: Formatly on Demand Offer

on:
  workflow_run:
    types:
      - completed
    workflows:
      - Formatly on Demand Detect

permissions:
  actions: read
  issues: write
  pull-requests: read

jobs:
  offer:
    uses: JoshuaKGoldberg/formatly-on-demand/.github/workflows/offer.yaml@v0

.github/workflows/formatly-on-demand-format.yaml does the formatting when someone asks:

name: Formatly on Demand Format

on:
  issue_comment:
    types:
      - created

permissions:
  issues: write
  pull-requests: read

jobs:
  format:
    secrets:
      push-token: ${{ secrets.ACCESS_TOKEN }}
    uses: JoshuaKGoldberg/formatly-on-demand/.github/workflows/format.yaml@v0
    with:
      install: pnpm install --frozen-lockfile

The install input is whatever command installs your dependencies, such as npm ci or pnpm install --frozen-lockfile. Leave it out for repositories that don't need an install step, such as ones formatted by deno fmt.

Pushing to Pull Requests From Forks

A workflow's built-in GITHUB_TOKEN can't push to a branch that lives in somebody else's fork. Formatting pull requests from forks, which is most of them for most open source repositories, needs a token of its own:

  1. Create a classic personal access token with the public_repo scope, from an account with push access to your repository
  2. Save it as a repository secret, such as ACCESS_TOKEN
  3. Pass it as the push-token secret, as in the workflow above

Without that secret, pull requests from forks get a comment explaining that a maintainer will need to format them by hand. Pull requests from branches in your own repository work with no extra setup.

Two GitHub limitations apply to pull requests from forks even with a token:

  • The pull request must have Allow edits by maintainers enabled, which is the default. formatly-on-demand says so in its comment when it isn't.
  • Forks owned by organizations can't grant that access at all.

Options

Reusable workflow inputs:

Input Default Description
accept-yes true Whether a comment of just yes counts as asking for formatting
allowed-associations OWNER,MEMBER,COLLABORATOR Who besides the pull request's author may ask for formatting
command /formatly Comment text that asks for formatting
comment-footer Custom footer text for comments
comment-header Custom header text for comments
commit-message chore: apply formatly formatting Message for the formatting commit
install Command that installs dependencies
node-version lts/* Node.js version to run the formatter with
working-directory . Directory holding the project to format

Repositories needing setup that the install input can't express, such as a custom toolchain, can use the action directly instead of these reusable workflows. See action.yaml for its inputs and the reusable workflows for how they're wired together.

How It Stays Safe

Running your repository's formatter means installing your pull request's dependencies and loading its config and plugins. That is arbitrary code execution from whoever opened the pull request, so formatly-on-demand never lets it share a job with a token:

  • Jobs that check out and run pull request code declare permissions: {} and reference no secrets.
  • The job that pushes runs no project code at all: no install, no scripts, no hooks. It applies a patch with git and nothing else.
  • That patch is validated first: modifications to existing files only, never .github/workflows, never symlinks, submodules, renames, or paths outside the repository, and never more than max-files files or max-patch-bytes bytes.
  • Detection results are re-verified against the GitHub API before any comment or push, because the job that produced them ran pull request code.
  • Formatting is only ever pushed to the commit it was computed from. If the branch moves first, formatly-on-demand stops and says so rather than pushing over new work.
  • Pushes are never forced.
  • Only the pull request's author and the associations in allowed-associations can ask for formatting. Comments from anyone else are ignored.

That being said, it is impossible to be 100% confident in all actions' security measures. Please use this action with caution and be safe with potentially malicious external contributors.

Development

See .github/CONTRIBUTING.md, then .github/DEVELOPMENT.md. Thanks! πŸ’–

Contributors

Josh Goldberg ✨
Josh Goldberg ✨

πŸ’» πŸ–‹ πŸ“– πŸ€” πŸš‡ 🚧 πŸ“† πŸ”§

πŸ’ This package was templated with create-typescript-app using the Bingo framework.

About

Offers to format pull requests with whatever formatter your project is already using, then formats them on demand. 🧼

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages