mirror of
https://github.com/Sea-Haven-Industries/.github.git
synced 2026-09-30 04:43:12 +00:00
feat(ci): add formatter presets to autofix
Callers can run prettier, eslint, ruff, and terraform without passing npm run lint -- --fix, which chains non-fixers in several apps.
This commit is contained in:
parent
fd41132410
commit
b65ee0f475
3 changed files with 125 additions and 21 deletions
136
.github/workflows/ci-autofix.yaml
vendored
136
.github/workflows/ci-autofix.yaml
vendored
|
|
@ -9,6 +9,12 @@ name: CI — Autofix
|
|||
# head, then set output committed=true so the caller skips portions on SHA_old.
|
||||
# Do not --no-verify. Do not push to main.
|
||||
#
|
||||
# Presets run first, then any format-command / lint-fix-command / extra-command.
|
||||
# prettier npm ci + npm run format (requires package-lock.json)
|
||||
# eslint npm ci + npx eslint . --fix (opt-in; do not call npm run lint)
|
||||
# ruff ruff format . + ruff check --fix . (ruff 0.15.22)
|
||||
# terraform terraform fmt -recursive in terraform-working-directory
|
||||
#
|
||||
# Caller example:
|
||||
# jobs:
|
||||
# autofix:
|
||||
|
|
@ -17,38 +23,52 @@ name: CI — Autofix
|
|||
# permissions: { contents: write }
|
||||
# secrets: inherit
|
||||
# with:
|
||||
# format-command: npm run format
|
||||
# lint-fix-command: npm run lint -- --fix
|
||||
# presets: prettier,terraform
|
||||
#
|
||||
# Python callers pass presets: ruff,terraform. Add eslint only when that
|
||||
# repo's CI lint step is ESLint itself and Prettier owns formatting.
|
||||
# Do not pass `npm run lint -- --fix` (some apps chain Redocly into lint).
|
||||
#
|
||||
# Org secrets (names only): AUTOFMT_APP_ID, AUTOFMT_APP_PRIVATE_KEY.
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
format-command:
|
||||
description: "Write formatter command (e.g. npm run format, ruff format .)"
|
||||
presets:
|
||||
description: "Comma-separated presets: prettier, eslint, ruff, terraform"
|
||||
type: string
|
||||
required: true
|
||||
required: false
|
||||
default: ""
|
||||
format-command:
|
||||
description: "Optional write command run after presets (e.g. npm run format)"
|
||||
type: string
|
||||
required: false
|
||||
default: ""
|
||||
lint-fix-command:
|
||||
description: "Optional write lint-fix command (e.g. ruff check --fix .)"
|
||||
description: "Optional write lint-fix command run after presets"
|
||||
type: string
|
||||
required: false
|
||||
default: ""
|
||||
extra-command:
|
||||
description: "Optional extra write command (e.g. terraform fmt -write)"
|
||||
description: "Optional extra write command run after presets"
|
||||
type: string
|
||||
required: false
|
||||
default: ""
|
||||
node-version:
|
||||
description: "Node.js version when package-lock.json is present"
|
||||
description: "Node.js version for the prettier or eslint preset, or an npm command"
|
||||
type: string
|
||||
required: false
|
||||
default: "24"
|
||||
terraform-version:
|
||||
description: "Terraform version when extra-command mentions terraform"
|
||||
description: "Terraform version for the terraform preset or an extra-command that runs terraform"
|
||||
type: string
|
||||
required: false
|
||||
default: "1.16.0"
|
||||
terraform-working-directory:
|
||||
description: "Directory for the terraform preset (terraform fmt -recursive)"
|
||||
type: string
|
||||
required: false
|
||||
default: "terraform"
|
||||
outputs:
|
||||
committed:
|
||||
description: "true when this job pushed a formatter commit"
|
||||
|
|
@ -105,27 +125,93 @@ jobs:
|
|||
ref: ${{ github.head_ref }}
|
||||
persist-credentials: true
|
||||
|
||||
- name: Resolve presets
|
||||
id: presets
|
||||
env:
|
||||
SKIP_BOT: ${{ steps.skip-bot.outputs.skip }}
|
||||
PRESETS: ${{ inputs.presets }}
|
||||
FORMAT_COMMAND: ${{ inputs.format-command }}
|
||||
LINT_FIX_COMMAND: ${{ inputs.lint-fix-command }}
|
||||
EXTRA_COMMAND: ${{ inputs.extra-command }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
write_outputs() {
|
||||
{
|
||||
echo "prettier=$1"
|
||||
echo "eslint=$2"
|
||||
echo "ruff=$3"
|
||||
echo "terraform=$4"
|
||||
} >> "${GITHUB_OUTPUT}"
|
||||
}
|
||||
|
||||
if [ "${SKIP_BOT}" = "true" ]; then
|
||||
write_outputs false false false false
|
||||
exit 0
|
||||
fi
|
||||
|
||||
want_prettier=false
|
||||
want_eslint=false
|
||||
want_ruff=false
|
||||
want_terraform=false
|
||||
|
||||
if [ -n "${PRESETS}" ]; then
|
||||
IFS=',' read -ra parts <<< "${PRESETS}"
|
||||
for raw in "${parts[@]}"; do
|
||||
token=$(printf '%s' "${raw}" | tr -d '[:space:]')
|
||||
case "${token}" in
|
||||
"") ;;
|
||||
prettier) want_prettier=true ;;
|
||||
eslint) want_eslint=true ;;
|
||||
ruff) want_ruff=true ;;
|
||||
terraform) want_terraform=true ;;
|
||||
*)
|
||||
echo "Unknown preset: ${token}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
if { [ "${want_prettier}" = "true" ] || [ "${want_eslint}" = "true" ]; } && [ ! -f package-lock.json ]; then
|
||||
echo "prettier and eslint presets require package-lock.json" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${want_prettier}" = "false" ] \
|
||||
&& [ "${want_eslint}" = "false" ] \
|
||||
&& [ "${want_ruff}" = "false" ] \
|
||||
&& [ "${want_terraform}" = "false" ] \
|
||||
&& [ -z "${FORMAT_COMMAND}" ] \
|
||||
&& [ -z "${LINT_FIX_COMMAND}" ] \
|
||||
&& [ -z "${EXTRA_COMMAND}" ]; then
|
||||
echo "Set presets or a format, lint-fix, or extra command." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
write_outputs "${want_prettier}" "${want_eslint}" "${want_ruff}" "${want_terraform}"
|
||||
|
||||
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
if: ${{ steps.skip-bot.outputs.skip != 'true' && hashFiles('package-lock.json') != '' }}
|
||||
if: ${{ steps.skip-bot.outputs.skip != 'true' && hashFiles('package-lock.json') != '' && (steps.presets.outputs.prettier == 'true' || steps.presets.outputs.eslint == 'true' || contains(inputs.format-command, 'npm') || contains(inputs.lint-fix-command, 'npm')) }}
|
||||
with:
|
||||
node-version: ${{ inputs.node-version }}
|
||||
cache: npm
|
||||
|
||||
- name: Install npm dependencies
|
||||
if: ${{ steps.skip-bot.outputs.skip != 'true' && hashFiles('package-lock.json') != '' }}
|
||||
if: ${{ steps.skip-bot.outputs.skip != 'true' && hashFiles('package-lock.json') != '' && (steps.presets.outputs.prettier == 'true' || steps.presets.outputs.eslint == 'true' || contains(inputs.format-command, 'npm') || contains(inputs.lint-fix-command, 'npm')) }}
|
||||
run: npm ci
|
||||
|
||||
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
||||
if: ${{ steps.skip-bot.outputs.skip != 'true' && (contains(inputs.format-command, 'ruff') || contains(inputs.lint-fix-command, 'ruff')) }}
|
||||
if: ${{ steps.skip-bot.outputs.skip != 'true' && (steps.presets.outputs.ruff == 'true' || contains(inputs.format-command, 'ruff') || contains(inputs.lint-fix-command, 'ruff') || contains(inputs.extra-command, 'ruff')) }}
|
||||
with:
|
||||
python-version: "3.12"
|
||||
|
||||
- name: Install ruff
|
||||
if: ${{ steps.skip-bot.outputs.skip != 'true' && (contains(inputs.format-command, 'ruff') || contains(inputs.lint-fix-command, 'ruff')) }}
|
||||
if: ${{ steps.skip-bot.outputs.skip != 'true' && (steps.presets.outputs.ruff == 'true' || contains(inputs.format-command, 'ruff') || contains(inputs.lint-fix-command, 'ruff') || contains(inputs.extra-command, 'ruff')) }}
|
||||
run: pip install 'ruff==0.15.22'
|
||||
|
||||
- uses: hashicorp/setup-terraform@dfe3c3f87815947d99a8997f908cb6525fc44e9e # v4.0.1
|
||||
if: ${{ steps.skip-bot.outputs.skip != 'true' && contains(inputs.extra-command, 'terraform') }}
|
||||
if: ${{ steps.skip-bot.outputs.skip != 'true' && (steps.presets.outputs.terraform == 'true' || contains(inputs.extra-command, 'terraform')) }}
|
||||
with:
|
||||
terraform_version: ${{ inputs.terraform-version }}
|
||||
terraform_wrapper: false
|
||||
|
|
@ -133,12 +219,32 @@ jobs:
|
|||
- name: Apply formatter
|
||||
if: ${{ steps.skip-bot.outputs.skip != 'true' }}
|
||||
env:
|
||||
PRETTIER: ${{ steps.presets.outputs.prettier }}
|
||||
ESLINT: ${{ steps.presets.outputs.eslint }}
|
||||
RUFF: ${{ steps.presets.outputs.ruff }}
|
||||
TERRAFORM: ${{ steps.presets.outputs.terraform }}
|
||||
TERRAFORM_DIR: ${{ inputs.terraform-working-directory }}
|
||||
FORMAT_COMMAND: ${{ inputs.format-command }}
|
||||
LINT_FIX_COMMAND: ${{ inputs.lint-fix-command }}
|
||||
EXTRA_COMMAND: ${{ inputs.extra-command }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
bash -euo pipefail -c "${FORMAT_COMMAND}"
|
||||
if [ "${PRETTIER}" = "true" ]; then
|
||||
npm run format
|
||||
fi
|
||||
if [ "${ESLINT}" = "true" ]; then
|
||||
npx eslint . --fix
|
||||
fi
|
||||
if [ "${RUFF}" = "true" ]; then
|
||||
ruff format .
|
||||
ruff check --fix .
|
||||
fi
|
||||
if [ "${TERRAFORM}" = "true" ]; then
|
||||
terraform -chdir="${TERRAFORM_DIR}" fmt -recursive
|
||||
fi
|
||||
if [ -n "${FORMAT_COMMAND}" ]; then
|
||||
bash -euo pipefail -c "${FORMAT_COMMAND}"
|
||||
fi
|
||||
if [ -n "${LINT_FIX_COMMAND}" ]; then
|
||||
bash -euo pipefail -c "${LINT_FIX_COMMAND}"
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ The formatter GitHub App is not on the main-branch bypass list.
|
|||
|
||||
**`.github/workflows/ci-terraform.yaml`** — Terraform `fmt -check`, `init -backend=false`, and `validate`. Default version `1.16.0`.
|
||||
|
||||
**`.github/workflows/ci-autofix.yaml`** — Pull-request-only formatter. Mints a GitHub App token (`AUTOFMT_APP_ID`, `AUTOFMT_APP_PRIVATE_KEY`), runs the caller's write commands, and pushes `style: apply formatter` only when the tree is dirty. Output `committed` lets the caller skip portions on SHA_old. Does not `--no-verify` and does not push to `main`.
|
||||
**`.github/workflows/ci-autofix.yaml`** — Pull-request-only formatter. Mints a GitHub App token (`AUTOFMT_APP_ID`, `AUTOFMT_APP_PRIVATE_KEY`), runs the requested presets and any optional write commands, and pushes `style: apply formatter` only when the tree is dirty. Presets are `prettier` (`npm run format`), `eslint` (`npx eslint . --fix`, opt-in), `ruff` (`ruff format .` and `ruff check --fix .`), and `terraform` (`terraform fmt -recursive` in `terraform-working-directory`, default `terraform`). Output `committed` lets the caller skip portions on SHA_old. Does not `--no-verify` and does not push to `main`.
|
||||
|
||||
**`.github/workflows/cd-hcp-fargate.yaml`** — HCP Fargate image CD. Checkout at `ref` (empty means `github.sha`), OIDC, SSM cluster/service/family/ecr/container/api-url, docker build+push tagged `$sha` and `$environment`, patch `GIT_SHA`, RegisterTaskDefinition + UpdateService + services-stable, poll health SHA. `environment` is a `with:` input. The reusable job owns `environment:`, concurrency, OIDC, and `vars.DEPLOY_ROLE_ARN`.
|
||||
|
||||
|
|
@ -268,8 +268,7 @@ jobs:
|
|||
permissions: { contents: write }
|
||||
secrets: inherit
|
||||
with:
|
||||
format-command: npm run format
|
||||
lint-fix-command: npm run lint -- --fix
|
||||
presets: prettier,terraform
|
||||
|
||||
frontend:
|
||||
needs: autofix
|
||||
|
|
@ -304,7 +303,7 @@ jobs:
|
|||
test "${TERRAFORM}" = success
|
||||
```
|
||||
|
||||
Python HCP callers pass `format-command: ruff format .` and `lint-fix-command: ruff check --fix .`. Optional `extra-command: terraform fmt -write` is available on `ci-autofix.yaml`. Do not run `eslint --fix` unless that repo's `lint` script is already fix-safe. Flip org ruleset membership in the same window as this merge: include on `CI complete`, exclude from `main branch protection`. Never require both `ci / ci` and `ci-complete`. Do not edit native GitHub merge-queue rulesets.
|
||||
Python HCP callers pass `presets: ruff,terraform`. The `eslint` preset is opt-in and runs `npx eslint . --fix`. Do not pass `npm run lint -- --fix`: several apps chain Redocly into `lint`. Enable `eslint` only when that repo's CI lint step is ESLint itself and Prettier owns formatting. Optional `format-command`, `lint-fix-command`, and `extra-command` still run after the presets. Flip org ruleset membership in the same window as this merge: include on `CI complete`, exclude from `main branch protection`. Never require both `ci / ci` and `ci-complete`. Do not edit native GitHub merge-queue rulesets.
|
||||
|
||||
### 3. Add CD to a repo
|
||||
|
||||
|
|
|
|||
|
|
@ -17,8 +17,7 @@ jobs:
|
|||
contents: write
|
||||
secrets: inherit
|
||||
with:
|
||||
format-command: npm run format
|
||||
lint-fix-command: "npm run lint -- --fix"
|
||||
presets: prettier,terraform
|
||||
|
||||
frontend:
|
||||
needs: autofix
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue