diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md index b9e78716..d9a8adc1 100644 --- a/.github/ISSUE_TEMPLATE/question.md +++ b/.github/ISSUE_TEMPLATE/question.md @@ -1,7 +1,7 @@ --- name: Question -about: 'Please use Stack Overflow for questions #geoip2-node.' +about: 'Please use Stack Overflow for questions #maxmind.' --- -For _how-to_ questions and other non-bugs, please use StackOverflow instead of Github issues. You can tag your questions with [geoip2-node](https://stackoverflow.com/questions/tagged/geoip2-node). +For _how-to_ questions and other non-bugs, please use StackOverflow instead of Github issues. You can tag your questions with [maxmind](https://stackoverflow.com/questions/tagged/maxmind). diff --git a/.github/workflows/links.yml b/.github/workflows/links.yml new file mode 100644 index 00000000..5e3255ba --- /dev/null +++ b/.github/workflows/links.yml @@ -0,0 +1,32 @@ +name: Links + +on: + push: + pull_request: + schedule: + - cron: "0 13 * * 1" # weekly, to catch external link rot without a commit + workflow_dispatch: + +permissions: + contents: read + +jobs: + linkChecker: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - name: Setup mise + uses: jdx/mise-action@6d1e696aa24c1aa1bcc1adea0212707c71ab78a8 # v3.6.1 + with: + install: false + + # Install only lychee (not the repo's full toolchain) and run the check. + - name: Check links + env: + MISE_AUTO_INSTALL: "false" + run: | + mise install lychee + mise run check-links diff --git a/.gitignore b/.gitignore index 3876da99..64d73cda 100644 --- a/.gitignore +++ b/.gitignore @@ -71,3 +71,5 @@ local # Claude config .claude + +.lycheecache diff --git a/CLAUDE.md b/CLAUDE.md index 4a5ff47c..a31cfeba 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -336,7 +336,7 @@ Refer to the GeoIP2-php implementation for guidance on new features (especially ## Additional Resources - [API Documentation](https://maxmind.github.io/GeoIP2-node/) -- [GeoIP Web Services Docs](https://dev.maxmind.com/geoip/docs/web-services) +- [GeoIP Web Services Docs](https://dev.maxmind.com/geoip/docs/web-services/) - [MaxMind DB Format](https://maxmind.github.io/MaxMind-DB/) - [node-maxmind library](https://github.com/runk/node-maxmind) - GitHub Issues: https://github.com/maxmind/GeoIP2-node/issues diff --git a/README.dev.md b/README.dev.md index 1ce940e9..2776f773 100644 --- a/README.dev.md +++ b/README.dev.md @@ -15,7 +15,7 @@ - Commit changes and push - Create a GitHub release (which triggers the npm publish workflow) 6. Merge the release PR after the workflow succeeds. -7. Verify the release on [npm](https://npmjs.com/package/@maxmind/geoip2-node). +7. Verify the release on [npm](https://www.npmjs.com/package/@maxmind/geoip2-node). Note: Publishing is done via GitHub Actions using npm Trusted Publishing (OIDC). Manual `npm publish` is not supported. diff --git a/README.md b/README.md index 38b49c6b..0f7263d0 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,9 @@ ## Description This package provides a server-side API for the [GeoIP databases and GeoLite -databases](https://dev.maxmind.com/geoip/docs/databases), and a server-side +databases](https://dev.maxmind.com/geoip/docs/databases/), and a server-side API for the [GeoIP web services and GeoLite web -services](https://dev.maxmind.com/geoip/docs/web-services). +services](https://dev.maxmind.com/geoip/docs/web-services/). **This package will not work client-side.** @@ -410,7 +410,7 @@ data set, it will be automatically incorporated into future MaxMind releases. If you are a paying MaxMind customer and you're not sure where to submit a -correction, please [contact MaxMind support for help](https://support.maxmind.com/hc/en-us/requests/new). +correction, please [contact MaxMind support for help](https://support.maxmind.com/knowledge-base/submit-a-support-request). ## Requirements @@ -432,7 +432,7 @@ Please report all issues with this code using the [GitHub issue tracker](https://github.com/maxmind/GeoIP2-node/issues) If you are having an issue with a MaxMind service that is not specific to the -client API, please contact [MaxMind support for assistance](https://support.maxmind.com/hc/en-us/requests/new). +client API, please contact [MaxMind support for assistance](https://support.maxmind.com/knowledge-base/submit-a-support-request). ## Copyright and License diff --git a/lychee.toml b/lychee.toml new file mode 100644 index 00000000..c6070224 --- /dev/null +++ b/lychee.toml @@ -0,0 +1,62 @@ +# Lychee link checker configuration +# https://lychee.cli.rs/#/usage/config +# +# Run locally with: +# lychee './**/*.md' './src/**/*.ts' './package.json' + +# Include URL fragments in checks +include_fragments = true + +# Don't allow any redirects, so links that have moved are surfaced and updated +# to their canonical destination. +max_redirects = 0 + +# Accept these HTTP status codes +# 100-103: Informational responses +# 200-299: Success responses +# 403: Forbidden (some sites use this for rate limiting) +# 429: Too Many Requests +# 500-599: Server errors (temporary issues shouldn't fail CI) +# 999: LinkedIn's custom status code +accept = ["100..=103", "200..=299", "403", "429", "500..=599", "999"] + +# Exclude URL patterns from checking (treated as regular expressions) +exclude = [ + '^file://', + # Live / auth-gated endpoints that appear as string literals or require login + '^https://geoip\.maxmind\.com', + '^https://geolite\.info', + '^https://minfraud\.maxmind\.com', + '^https://sandbox\.maxmind\.com', + '^https://updates\.maxmind\.com', + '^https://www\.maxmind\.com/en/accounts/', + 'https://www\.maxmind\.com/en/account/login', + # package.json repository.url uses the canonical npm git clone URL + # (https://github.com/maxmind/GeoIP2-node.git); the ".git" form 301s to the + # web UI but is the correct packaging metadata, so it is not a "link" to fix. + '^https://github\.com/maxmind/GeoIP2-node\.git$', + # Placeholders / local + '^https?://example\.(com|org|net)', + '^http://localhost', + '127\.0\.0\.1', +] + +# Exclude file paths from getting checked (treated as regular expressions) +exclude_path = [ + '(^|/)node_modules/', + '(^|/)dist/', + '(^|/)build/', + '(^|/)coverage/', + # docs/ contains generated TypeDoc HTML (gitignored) + '(^|/)docs/', + '(^|/)\.git/', + # Changelog: historical entries are preserved as-is, not rewritten + '(^|/)CHANGELOG\.md$', +] + +# Cache results for 1 day to speed up repeated checks +cache = true +max_cache_age = "1d" + +# Skip missing input files instead of erroring +skip_missing = true diff --git a/mise.lock b/mise.lock index de597f28..f6e8c7f0 100644 --- a/mise.lock +++ b/mise.lock @@ -1,5 +1,33 @@ # @generated - this file is auto-generated by `mise lock` https://mise.jdx.dev/dev-tools/mise-lock.html +[[tools.lychee]] +version = "0.23.0" +backend = "aqua:lycheeverse/lychee" + +[tools.lychee."platforms.linux-arm64"] +checksum = "sha256:97eb93b02a7d78a752fc33e5b0983439ccaadbf3db952b68a0a4401acd92e6e0" +url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.23.0/lychee-aarch64-unknown-linux-gnu.tar.gz" + +[tools.lychee."platforms.linux-arm64-musl"] +checksum = "sha256:97eb93b02a7d78a752fc33e5b0983439ccaadbf3db952b68a0a4401acd92e6e0" +url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.23.0/lychee-aarch64-unknown-linux-gnu.tar.gz" + +[tools.lychee."platforms.linux-x64"] +checksum = "sha256:5538440d2c69a45a0a09983271e5dee0c2fe7137d8035d25b2632e10a66a090a" +url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.23.0/lychee-x86_64-unknown-linux-musl.tar.gz" + +[tools.lychee."platforms.linux-x64-musl"] +checksum = "sha256:5538440d2c69a45a0a09983271e5dee0c2fe7137d8035d25b2632e10a66a090a" +url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.23.0/lychee-x86_64-unknown-linux-musl.tar.gz" + +[tools.lychee."platforms.macos-arm64"] +checksum = "sha256:4c8034900e11083b68ac6f6582c377ff1f704e268991999e09d717973e493e7f" +url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.23.0/lychee-arm64-macos.dmg" + +[tools.lychee."platforms.windows-x64"] +checksum = "sha256:0fda7ff0a60c0250939fc25361c2d4e6e7853c31c996733fdd5a1dd760bcb824" +url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.23.0/lychee-x86_64-windows.exe" + [[tools.node]] version = "26.1.0" backend = "core:node" diff --git a/mise.toml b/mise.toml index 48e0bb7b..55928a7a 100644 --- a/mise.toml +++ b/mise.toml @@ -8,6 +8,7 @@ disable_backends = [ [tools] node = "latest" +lychee = "latest" [hooks] enter = "mise install --quiet --locked" @@ -15,3 +16,7 @@ enter = "mise install --quiet --locked" [[watch_files]] patterns = ["mise.toml", "mise.lock"] run = "mise install --quiet --locked" + +[tasks.check-links] +description = "Check links with lychee" +run = "lychee --no-progress './**/*.md' './src/**/*.ts' './package.json'"