Skip to content

chore: add markdown link checking (hk pre-commit hook + CI job)#38

Merged
amondnet merged 6 commits into
mainfrom
amondnet/markdown-lint-fix
Jun 22, 2026
Merged

chore: add markdown link checking (hk pre-commit hook + CI job)#38
amondnet merged 6 commits into
mainfrom
amondnet/markdown-lint-fix

Conversation

@amondnet

@amondnet amondnet commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Summary

Add markdown link validation using markdown-link-check, wired in at two layers with a single shared config (hk.pkl):

  • pre-commit hook (via hk) — checks staged *.md files before each commit
  • CI job — checks all *.md files on push/PR to main

Changes

  • hk.pklpre-commit + check hooks running markdown-link-check
  • .markdown-link-check.json — timeouts, 429 retries, ignored hosts (localhost), browser UA
  • mise.toml — provision markdown-link-check; add lint:links task (file written in English)
  • .github/workflows/ci.ymlMarkdown Link Check job reusing the same hk.pkl globs/excludes
  • dev-docs/GIT_HOOKS.md — setup & usage docs

CHANGELOG.md (auto-generated) and node_modules/** are excluded from checks.

Notes

  • hk install required per clone — the pre-commit hook lives in .git/hooks/ and is not committed.
  • hk is not in mise.toml [tools] — it ships no darwin/amd64 (Intel Mac) binary. Install via mise use -g hk (linux / Apple Silicon) or brew install hk (Intel Mac). CI installs it on the fly (mise exec hk@1.48.0).
  • The CI link-check is strict (blocking); external link outages/rate-limits can cause flaky failures. Mitigation options (continue-on-error or a weekly cron) can be added if desired.

Verification

  • Broken link → commit blocked (✗ ERROR); valid link → passes (verified by dogfooding this PR's own commits).
  • hk check --all --plan → 47 files matched (CHANGELOG.md excluded as expected).

Summary by cubic

Add Markdown link checking with markdown-link-check in hk pre-commit and CI to catch broken links early. Also fixes broken docs links and stabilizes tests that were flaky due to leaked module mocks.

  • New Features

    • hk pre-commit checks staged *.md; excludes CHANGELOG.md and node_modules/**.
    • CI job runs the same check on push/PRs to main using hk.pkl globs.
    • Shared .markdown-link-check.json sets timeouts, 429 retries, browser UA; ignores localhost, Nuxt internal routes, and bot-blocked hosts (app.asana.com, npmjs.com, npm.im).
    • mise.toml provisions npm:markdown-link-check and adds lint:links that runs the checker directly (no hk needed); docs in dev-docs/GIT_HOOKS.md.
  • Bug Fixes

    • Replaced dead GitHub links with https://github.com/pleaseai/asana.
    • Restored real modules in tests in afterAll to avoid mock.module() leaks and order-dependent CI failures.

Written for commit b366bff. Summary will update on new commits.

Summary by CodeRabbit

  • New Features
    • Added automated Markdown link validation to CI lint checks and the pre-commit hook for staged Markdown files.
  • Bug Fixes
    • Improved test isolation so Bun module mocks no longer leak between test files.
  • Documentation
    • Documented git hook setup and configuration for link checking.
    • Updated repository links across English and Korean documentation.
  • Chores
    • Updated lint/link-check tasks and tooling configuration to support the new link validation workflow.

amondnet added 2 commits June 22, 2026 15:22
Validate markdown links on staged *.md files before each commit using
tcort/markdown-link-check, orchestrated by the hk git hook manager.

- hk.pkl: pre-commit + check hooks running markdown-link-check
- .markdown-link-check.json: timeouts, 429 retries, ignored hosts, UA
- mise.toml: provision markdown-link-check; add lint:links task
- dev-docs/GIT_HOOKS.md: setup + usage (hk install required per clone)

CHANGELOG.md and node_modules are excluded from checks.
Run markdown-link-check on all *.md files on push/PR to main, reusing
the same hk.pkl globs/excludes as the local pre-commit hook for a single
source of truth.

hk is installed on the fly (mise exec hk@1.48.0) since it has no
Intel-Mac binary and is not in mise.toml [tools]; CI runs linux.
@vercel

vercel Bot commented Jun 22, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
asana Ready Ready Preview, Comment Jun 22, 2026 7:43am

Request Review

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds markdown link validation infrastructure via hk and markdown-link-check, integrates into mise tasks and CI lint job, and documents git hook setup. Updates repository references across English and Korean docs from amondnet/asana to pleaseai/asana. Fixes Bun module mock leakage in two test files by capturing and restoring real modules in afterAll hooks.

Changes

Markdown link-check setup

Layer / File(s) Summary
Link-check config and mise tooling
.markdown-link-check.json, mise.toml
New .markdown-link-check.json specifies URL ignore patterns (localhost, site roots, Asana, npmjs.com, npm.im), injects a browser-like User-Agent header, sets 20s timeout, enables retry-on-429 with up to 3 retries, adds 30s fallback retry delay, and treats status codes 200 and 206 as alive. mise.toml adds npm:markdown-link-check to [tools], introduces a tasks."lint:links" entry, updates task descriptions to English, and adds depends = ["lint", "test"] to tasks.check.
CI lint job link-check step
.github/workflows/ci.yml
Adds a link-check step in the CI lint job that invokes mise exec hk@1.48.0 -- hk check --all, reusing the same hk.pkl glob/exclude configuration as the local pre-commit hook and installing hk on the fly in CI.
Developer documentation and repository updates
dev-docs/GIT_HOOKS.md, docs/content/en/index.md, docs/content/ko/1.guide/1.getting-started.md, docs/content/ko/index.md
New GIT_HOOKS.md documents the hk-based pre-commit hook setup: targeted files (*.md), exclusions (CHANGELOG.md, node_modules/**), config file locations, one-time mise/hk install setup, .git/hooks/ persistence caveat, and helper commands. Updates GitHub repository URLs from amondnet/asana to pleaseai/asana across English and Korean documentation pages.

Test module mock leak prevention

Layer / File(s) Summary
Module mock isolation in tests
test/commands/auth-login-pat.test.ts, test/commands/task-create-due.test.ts
Adds module-leak prevention by capturing real asana/config (or asana-client/config) modules at load time into constants, then re-installing those real modules via afterAll hooks. Prevents mock.module() registrations from leaking into subsequent test files due to insufficient cleanup.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • pleaseai/asana#31: Changes to test/commands/auth-login-pat.test.ts for preventing Bun module mock leakage are directly related to regression tests that mock the Asana SDK and config modules.
  • pleaseai/asana#34: Changes to test/commands/task-create-due.test.ts for test isolation fix are related to due-date flag handling tests and mock setup in the same file.

Poem

🐇 Links are checked from burrow to top,
Configuration's done, let's never stop!
With hk watching every .md,
Test modules clean—no leaks for me!
From code to CI, all work is sound—
A tidy warren, test-safe ground! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately summarizes the primary changes: adding markdown link checking via a pre-commit hook (hk) and a CI job.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch amondnet/markdown-lint-fix

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request configures markdown link validation using markdown-link-check and the Git hook manager hk, adding configuration files, documentation, and a lint:links task in mise.toml. The review feedback suggests decoupling the lint:links task from hk by using find to run markdown-link-check directly, which improves compatibility for Intel Mac users who cannot easily install hk, and updating the documentation accordingly.

Comment thread mise.toml Outdated
Comment thread dev-docs/GIT_HOOKS.md Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/ci.yml:
- Around line 84-87: Replace the mutable version tags in the GitHub Actions
workflow with pinned SHAs to prevent supply chain drift. Update the
actions/checkout action from `@v4` to use a specific commit SHA, and update the
jdx/mise-action from `@v2` to use a specific commit SHA. Additionally, add
persist-credentials: false to the actions/checkout step to strengthen token
handling security by preventing the action from persisting authentication
credentials after the job completes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 90e7ea0e-c7e7-441b-81f4-0c5e1eb56161

📥 Commits

Reviewing files that changed from the base of the PR and between b342180 and 687b37b.

⛔ Files ignored due to path filters (1)
  • hk.pkl is excluded by !**/*.pkl
📒 Files selected for processing (4)
  • .github/workflows/ci.yml
  • .markdown-link-check.json
  • dev-docs/GIT_HOOKS.md
  • mise.toml

Comment thread .github/workflows/ci.yml

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 5 files

Architecture diagram
sequenceDiagram
    participant Dev as Developer
    participant Git as Git (commit)
    participant Hk as hk (hook manager)
    participant MLC as markdown-link-check
    participant Config as Config (hk.pkl + .markdown-link-check.json)
    participant CI as CI (GitHub Actions)
    participant External as External URLs

    Note over Dev,External: NEW: Markdown link check flow

    Dev->>Git: git commit staging
    Git->>Hk: NEW: invoke pre-commit hook (hk)

    Hk->>Config: read hk.pkl, parse steps
    Config-->>Hk: markdown-link-check step definition
    Hk->>Hk: NEW: filter staged *.md files, exclude CHANGELOG.md & node_modules/**
    Hk->>MLC: NEW: markdown-link-check --config .markdown-link-check.json --quiet <files>
    MLC->>External: HTTP HEAD/GET requests for each link
    alt All links valid
        External-->>MLC: 200/206 (or 2xx)
        MLC-->>Hk: exit 0
        Hk-->>Git: allow commit
        Git-->>Dev: commit success
    else Broken link or timeout
        External-->>MLC: 4xx/5xx / timeout
        MLC-->>Hk: exit non-zero
        Hk-->>Git: block commit
        Git-->>Dev: commit blocked with error
    end

    Note over CI,External: CI job on push/PR to main
    CI->>Git: checkout code
    CI->>CI: setup mise (node + markdown-link-check)
    CI->>Hk: NEW: mise exec hk@1.48.0 -- hk check --all
    Hk->>Config: read same hk.pkl config
    Config-->>Hk: steps for "check" hook (same as pre-commit)
    Hk->>Hk: NEW: glob all *.md (excluding CHANGELOG.md & node_modules/**)
    Hk->>MLC: same command, with all files
    MLC->>External: check links
    alt All valid
        External-->>MLC: success
        MLC-->>Hk: exit 0
        Hk-->>CI: pass
        CI-->>CI: job success
    else Links broken
        External-->>MLC: error
        MLC-->>Hk: exit non-zero
        Hk-->>CI: fail
        CI-->>CI: job failure (strict/blocking)
    end

    Note over Hk,CI: hk not in mise.toml (no Intel Mac binary)<br/>CI installs hk via mise exec
Loading

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread .github/workflows/ci.yml
amondnet added 3 commits June 22, 2026 16:33
Bun's mock.restore() does not revert mock.module() registrations, so the
config/asana-client module mocks in these command tests leaked into later
files. Depending on filesystem-dependent test file ordering (sorted on
macOS, inode order on Linux CI), a stubbed loadConfig made the
refreshTokenIfNeeded tests in asana-client.test.ts early-return, failing 3
tests on CI only. Capture the real modules by value and re-install them in
afterAll so each file leaves global module state clean.
- Point repo links at github.com/pleaseai/asana (amondnet/asana 404s)
- Ignore Nuxt Content internal routes (rendered, not file-checkable) and
  bot-blocked hosts (app.asana.com, npmjs.com, npm.im return 403 to the
  checker UA) in .markdown-link-check.json
- lint:links task no longer depends on hk (not in mise [tools]); run
  markdown-link-check directly via find so 'mise run lint:links' works
  without a separate hk install (gemini-code-assist)
- update GIT_HOOKS.md to reflect that lint:links runs markdown-link-check
  directly rather than via hk (gemini-code-assist)

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
mise.toml (1)

26-26: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Prune node_modules during traversal to avoid unnecessary filesystem scans.

At Line 26, -not -path excludes output but still traverses node_modules/**, which can make lint:links much slower on large workspaces.

Suggested change
-run = "find . -name '*.md' -not -path '*/node_modules/*' -not -name 'CHANGELOG.md' -exec markdown-link-check --config .markdown-link-check.json --quiet {} +"
+run = "find . -type d -name node_modules -prune -o -type f -name '*.md' -not -name 'CHANGELOG.md' -exec markdown-link-check --config .markdown-link-check.json --quiet {} +"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@mise.toml` at line 26, The find command in the run field at line 26 uses -not
-path to exclude node_modules from results, but still traverses into those
directories, causing unnecessary filesystem scans. Replace the -not -path
'*/node_modules/*' exclusion with -path '*/node_modules' -prune to prevent find
from descending into node_modules directories entirely during traversal. This
requires restructuring the find command to use the -prune action before the
-name and other conditions so that matching directories are skipped at traversal
time rather than just filtered from results.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@mise.toml`:
- Line 26: The find command in the run field at line 26 uses -not -path to
exclude node_modules from results, but still traverses into those directories,
causing unnecessary filesystem scans. Replace the -not -path '*/node_modules/*'
exclusion with -path '*/node_modules' -prune to prevent find from descending
into node_modules directories entirely during traversal. This requires
restructuring the find command to use the -prune action before the -name and
other conditions so that matching directories are skipped at traversal time
rather than just filtered from results.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 84224baf-ebd5-431d-8e44-7650be6ced6d

📥 Commits

Reviewing files that changed from the base of the PR and between 8614474 and b366bff.

📒 Files selected for processing (2)
  • dev-docs/GIT_HOOKS.md
  • mise.toml
✅ Files skipped from review due to trivial changes (1)
  • dev-docs/GIT_HOOKS.md

@amondnet
amondnet merged commit f1105a6 into main Jun 22, 2026
10 checks passed
@amondnet
amondnet deleted the amondnet/markdown-lint-fix branch July 6, 2026 12:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant