From 06facdab3b778e97b46a697baf18dc6f3b7174d8 Mon Sep 17 00:00:00 2001 From: Dan Crews Date: Fri, 21 Nov 2025 12:11:57 -0800 Subject: [PATCH] Add pre-commit hooks for maintaining version match --- .github/scripts/sync-version-on-commit.mjs | 48 ++++++++++++++++++++ .github/workflows/pre-commit.yml | 28 ++++++++++++ .pre-commit-config.yaml | 11 +++++ .pre-commit-hooks.yaml | 4 +- README.md | 52 +++++++++++++++++++++- markdownlint.js | 2 +- package.json | 2 +- 7 files changed, 142 insertions(+), 5 deletions(-) create mode 100644 .github/scripts/sync-version-on-commit.mjs create mode 100644 .github/workflows/pre-commit.yml create mode 100644 .pre-commit-config.yaml diff --git a/.github/scripts/sync-version-on-commit.mjs b/.github/scripts/sync-version-on-commit.mjs new file mode 100644 index 000000000..e1481035d --- /dev/null +++ b/.github/scripts/sync-version-on-commit.mjs @@ -0,0 +1,48 @@ +#!/usr/bin/env node + +import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +console.info('Syncing all version references...'); + +// Read version from package.json +const packageJsonPath = path.join(__dirname, '..', '..', 'package.json'); +const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); +const version = packageJson.version; + +console.info(`Version from package.json: ${version}`); + +// File paths +const markdownlintJsPath = path.join(__dirname, '..', '..', 'markdownlint.js'); +const readmePath = path.join(__dirname, '..', '..', 'README.md'); +const preCommitHooksPath = path.join(__dirname, '..', '..', '.pre-commit-hooks.yaml'); + +// Update markdownlint.js +let markdownlintJs = fs.readFileSync(markdownlintJsPath, 'utf8'); +markdownlintJs = markdownlintJs.replace( + /const version = '[^']+';/, + `const version = '${version}';` +); +fs.writeFileSync(markdownlintJsPath, markdownlintJs); + +// Update README.md +let readme = fs.readFileSync(readmePath, 'utf8'); +readme = readme.replace( + /rev: v[0-9]+\.[0-9]+\.[0-9]+/, + `rev: v${version}` +); +fs.writeFileSync(readmePath, readme); + +// Update .pre-commit-hooks.yaml +let preCommitHooks = fs.readFileSync(preCommitHooksPath, 'utf8'); +preCommitHooks = preCommitHooks.replace( + /entry: ghcr\.io\/igorshubovych\/markdownlint-cli(?::[^\s]+)?(\s|$)/g, + `entry: ghcr.io/igorshubovych/markdownlint-cli:v${version}$1` +); +fs.writeFileSync(preCommitHooksPath, preCommitHooks); + +console.info('✓ Version sync complete'); diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml new file mode 100644 index 000000000..ed2d7fc53 --- /dev/null +++ b/.github/workflows/pre-commit.yml @@ -0,0 +1,28 @@ +name: Pre-commit + +on: + push: + branches: + - master + pull_request: + +jobs: + pre-commit: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v6 + + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version: lts/* + + - name: Setup Python + uses: actions/setup-python@v6 + with: + python-version: '3.x' + + - name: Run pre-commit + uses: pre-commit/action@v3.0.1 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000..e48ee8c1f --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,11 @@ +# See https://pre-commit.com for more information +# See https://pre-commit.com/hooks.html for more hooks +repos: + - repo: local + hooks: + - id: sync-version + name: Sync version references + entry: node .github/scripts/sync-version-on-commit.mjs + language: system + files: ^(package\.json|markdownlint\.js|README\.md|\.pre-commit-hooks\.yaml)$ + pass_filenames: false diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index 35f6a0981..26f033146 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -15,14 +15,14 @@ - id: markdownlint-docker name: markdownlint-docker description: "Checks the style of Markdown/Commonmark files." - entry: ghcr.io/igorshubovych/markdownlint-cli + entry: ghcr.io/igorshubovych/markdownlint-cli:v0.46.1 language: docker_image types: [markdown] minimum_pre_commit_version: 0.15.0 - id: markdownlint-fix-docker name: markdownlint-fix-docker description: "Fixes the style of Markdown/Commonmark files." - entry: ghcr.io/igorshubovych/markdownlint-cli --fix + entry: ghcr.io/igorshubovych/markdownlint-cli:v0.46.1 --fix language: docker_image types: [markdown] minimum_pre_commit_version: 0.15.0 diff --git a/README.md b/README.md index baa77afae..fee4c0c04 100644 --- a/README.md +++ b/README.md @@ -142,13 +142,63 @@ To run `markdownlint-cli` as part of a [pre-commit][pre-commit] workflow, add so ```yaml - repo: https://github.com/igorshubovych/markdownlint-cli - rev: v0.46.0 + rev: v0.46.1 hooks: - id: markdownlint ``` > Depending on the environment this workflow runs in, it may be necessary to [override the language version of Node.js used by pre-commit][pre-commit-version]. +## Contributing + +### Setting up local development + +This project uses [pre-commit][pre-commit] hooks to maintain version consistency across multiple files. To set up your local development environment: + +#### macOS/Linux + +```bash +# Install pre-commit (if not already installed) +pip install pre-commit +# or +brew install pre-commit + +# Install the git hook scripts +pre-commit install +``` + +#### Windows + +```powershell +# Install pre-commit via pip +pip install pre-commit + +# Install the git hook scripts +pre-commit install +``` + +#### What the pre-commit hooks do + +- **Version sync**: Automatically ensures version references in `markdownlint.js`, `README.md`, and `.pre-commit-hooks.yaml` stay in sync with `package.json` + +When you commit changes to any version-related files, the hooks will: + +1. Read the version from `package.json` +2. Update all other files to match +3. If files were modified, the commit will fail with a message asking you to review and stage the changes +4. Review the changes with `git diff` and re-add them with `git add` +5. Retry your commit + +#### Running hooks manually + +```bash +# Run all hooks on all files +pre-commit run --all-files + +# Run hooks only on staged files +pre-commit run +``` + ## Related - [markdownlint][markdownlint] - API for this module diff --git a/markdownlint.js b/markdownlint.js index ff5ec67f4..17818b609 100755 --- a/markdownlint.js +++ b/markdownlint.js @@ -16,7 +16,7 @@ import jsonpointer from 'jsonpointer'; const require = Module.createRequire(import.meta.url); const options = program.opts(); // The following two values are copied from package.json (and validated by tests) -const version = '0.46.0'; +const version = '0.46.1'; const description = 'MarkdownLint Command Line Interface'; function markdownItFactory() { diff --git a/package.json b/package.json index 08e1a5eaf..cf6afd5ce 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "markdownlint-cli", - "version": "0.46.0", + "version": "0.46.1", "description": "MarkdownLint Command Line Interface", "type": "module", "main": "markdownlint.js",