Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .cspell.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json",
"version": "0.2",
"words": ["Bitwarden"],
"unknownWords": "report-common-typos",
"flagWords": [],
"ignorePaths": [
".vscode",
Expand Down
2 changes: 1 addition & 1 deletion .gitconfig
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[hook "linter"]
event = pre-commit
command = echo "Add linter in ./gitconfig"
command = sh .githooks/pre-commit
29 changes: 29 additions & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env sh
#
# Pre-commit linter: formats and spell-checks staged files.
# - Prettier (--check) on staged Markdown, JSON, JSON5, and YAML
# - CSpell on staged Markdown
#
# Wired up through .gitconfig ([hook "linter"]). Enable it once per clone by
# running the following from the repo root:
#
# git config set --local include.path "../.gitconfig"
#
# Requires Node.js (>=18); the tools are fetched on demand via `npx --yes`.

set -eu

staged_files=$(git diff --cached --name-only --diff-filter=ACMR -- '*.md' '*.json' '*.json5' '*.yml' '*.yaml')

if [ -n "$staged_files" ]; then
# Word-splitting is intentional: pass each newline-separated path as an argument.
# shellcheck disable=SC2086
npx --yes prettier@3.9.1 --check $staged_files
fi

staged_md=$(git diff --cached --name-only --diff-filter=ACMR -- '*.md')

if [ -n "$staged_md" ]; then
# shellcheck disable=SC2086
npx --yes cspell@10.0.1 --no-progress --gitignore $staged_md
fi
29 changes: 28 additions & 1 deletion .github/renovate.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,35 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["github>bitwarden/renovate-config"],
"enabledManagers": ["cargo", "docker-compose", "dockerfile", "github-actions", "npm", "nuget"],
"enabledManagers": [
"cargo",
"custom.regex",
"docker-compose",
"dockerfile",
"github-actions",
"npm",
"nuget"
],
"customManagers": [
{
"customType": "regex",
"description": "Pinned npx tool versions in the lint workflow and git hooks",
"fileMatch": [
"^\\.github/workflows/lint\\.yml$",
"^\\.githooks/pre-commit$"
],
"matchStrings": [
"(?<depName>prettier|cspell)@(?<currentValue>\\d+\\.\\d+\\.\\d+)"
],
"datasourceTemplate": "npm"
}
],
"packageRules": [
{
"groupName": "lint tooling",
"matchManagers": ["custom.regex"],
"matchPackageNames": ["prettier", "cspell"]
},
{
"groupName": "cargo minor",
"matchManagers": ["cargo"],
Expand Down
50 changes: 50 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Lint

# Keep the Prettier and CSpell tooling here in sync with the pre-commit linter
# in .githooks/pre-commit (versions, file globs, and flags) so local commits and
# CI enforce the same rules. Renovate bumps both together via .github/renovate.json.

on:
workflow_dispatch:
push:
branches: [main]
pull_request:
types: [opened, synchronize, reopened]

permissions:
contents: read

jobs:
format:
name: Prettier
runs-on: ubuntu-24.04
steps:
- name: Check out repo
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false

- name: Set up Node
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 24

- name: Check formatting
run: npx --yes prettier@3.9.1 --check "**/*.{md,json,json5,yml,yaml}"

spell:
name: CSpell
runs-on: ubuntu-24.04
steps:
- name: Check out repo
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false

- name: Set up Node
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 24

- name: Check spelling
run: npx --yes cspell@10.0.1 --no-progress --gitignore "**/*.md"
21 changes: 18 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,26 @@ This repository serves as a template for others and establishes very basic struc

## Hooks

Hooks are centrally configured for the repo in the `.gitconfig` file.
Hooks are centrally configured for the repo in the `.gitconfig` file. The `pre-commit` hook
([`.githooks/pre-commit`](.githooks/pre-commit)) runs [Prettier](https://prettier.io) (`--check`) on
staged Markdown, JSON, JSON5, and YAML, and [CSpell](https://cspell.org) against staged Markdown to
catch common typos; the spell-checker's settings live in `.cspell.json`. The same checks run in CI on
every pull request via the [Lint workflow](.github/workflows/lint.yml), and the pinned tool versions β€”
in both the hook and the workflow β€” are kept current by Renovate.

If you configure a linter you will want to include docs to have contributors run the following
command:
Hooks are opt-in per clone. Enable them once, from the repo root:

```bash
git config set --local include.path "../.gitconfig"
```

Running the hook requires [Node.js](https://nodejs.org) (>=18); the tools are fetched on demand via
`npx`.

## Customizing the linter

Because this is a template, treat the linter as a starting point and adjust it for your repo. The file
extensions are the most likely thing to change: Prettier checks Markdown, JSON, JSON5, and YAML, and
CSpell checks Markdown. If you change those globs, update both
[`.githooks/pre-commit`](.githooks/pre-commit) and the [Lint workflow](.github/workflows/lint.yml) so
local commits and CI stay in sync. Swapping tools or changing the pinned versions works the same way.