Skip to content
Open
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
32 changes: 32 additions & 0 deletions .github/workflows/links.yml
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
.claude
.gh-pages
.idea
.lycheecache
docs/.hugo_build.lock
docs/public/
.pmd
Expand Down
8 changes: 4 additions & 4 deletions README.dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@

To get this access, first create a Central Portal account. You will then need
access to our namespace, but we have not added anyone since switching to
Central Portal. Previously you would need to make an account on the [Sonatype
JIRA issue tracker](https://issues.sonatype.org/) and make an issue asking for
access [like so](https://issues.sonatype.org/browse/OSSRH-34414).
Central Portal. Previously you would need to make an account on the Sonatype
JIRA issue tracker and make an issue asking for access. That tracker has since
been [retired](https://central.sonatype.org/faq/what-happened-to-issues-sonatype-org/).

Ensure you inform MaxMind operations about your new access.

Expand Down Expand Up @@ -52,7 +52,7 @@ and enter `trust` and choose ultimate.
Make sure the key shows up in `gpg --list-secret-keys`.

Make sure you publish it to a keyserver. See
[here](http://central.sonatype.org/pages/working-with-pgp-signatures.html)
[here](https://central.sonatype.org/publish/requirements/gpg/)
for more info about that and the process in general.

### gpg "inappropriate ioctl" errors
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ Please report all issues with this code using the

If you are having an issue with the minFraud service that is not specific
to the client API, please see
[our support page](https://www.maxmind.com/en/support).
[our support page](https://support.maxmind.com/knowledge-base).

## Requirements ##

Expand Down
67 changes: 67 additions & 0 deletions lychee.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Lychee link checker configuration
# https://lychee.cli.rs/#/usage/config
#
# Run locally with:
# lychee './**/*.md' './src/**/*.java' './pom.xml'

# 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"]
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Accepting all 5xx status codes (500..=599) globally will prevent the link checker from detecting genuinely broken links when a server is permanently down or misconfigured. Since lychee has built-in retry logic for transient errors, it is safer to remove 500..=599 from the accept list so that persistent server errors are correctly flagged.

Suggested change
accept = ["100..=103", "200..=299", "403", "429", "500..=599", "999"]
accept = ["100..=103", "200..=299", "403", "429", "999"]

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Keeping 500..=599 in accept, matching the dev-site and blog-site configs — transient upstream 5xx shouldn't fail link-checking CI.

— Claude (posted on Greg's behalf)


# 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',
# XML namespace identifiers in pom.xml (not real links)
'^http://www\.w3\.org/',
'^http://maven\.apache\.org/',
'^https://maven\.apache\.org/xsd/',
'^http://java\.sun\.com/',
'^http://schemas\.',
# Maven property placeholder in a build-time download URL (not a real link)
'japicmp\.baselineVersion',
# dev.maxmind.com docs render anchors client-side, so lychee cannot verify
# the #schema-... fragment even though the page (a clean 200) contains it.
'^https://dev\.maxmind\.com/minfraud/api-documentation/responses/#',
# Placeholders / local
'^https?://example\.(com|org|net)',
'^http://localhost',
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The pattern ^http://localhost only matches HTTP local links. It is safer to use ^https?://localhost to also cover any local HTTPS endpoints if they are ever used.

Suggested change
'^http://localhost',
'^https?://localhost',

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

localhost only appears as an http:// placeholder in this repo, so this is a no-op today; kept to match the shared template. Happy to broaden to https? if desired.

— Claude (posted on Greg's behalf)

'127\.0\.0\.1',
]

# Exclude file paths from getting checked (treated as regular expressions)
exclude_path = [
'(^|/)node_modules/',
'(^|/)target/',
'(^|/)\.git/',
# Test code and fixtures contain example URLs (e.g. www.example.com), not ours
'(^|/)src/test/',
# 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
28 changes: 28 additions & 0 deletions mise.lock
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,34 @@ url = "https://github.com/gohugoio/hugo/releases/download/v0.161.1/hugo_0.161.1_
version = "26.0.1"
backend = "core:java"

[[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.maven]]
version = "3.9.15"
backend = "aqua:apache/maven"
Expand Down
5 changes: 5 additions & 0 deletions mise.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ disable_backends = [
[tools]
hugo = "latest"
java = "latest"
lychee = "latest"
maven = "latest"

[tasks.build-docs]
Expand All @@ -19,6 +20,10 @@ run = "hugo --source docs --minify"
description = "Serve the docs site locally with Hugo dev server"
run = "hugo server --source docs"

[tasks.check-links]
description = "Check links with lychee"
run = "lychee --no-progress './**/*.md' './src/**/*.java' './pom.xml'"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Using single quotes for arguments in the run command can cause issues on Windows environments (e.g., when run via cmd.exe), as single quotes are not stripped and are passed literally to the executable. Using escaped double quotes is more portable and cross-platform.

Suggested change
run = "lychee --no-progress './**/*.md' './src/**/*.java' './pom.xml'"
run = "lychee --no-progress \"./**/*.md\" \"./src/**/*.java\" \"./pom.xml\""

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The check-links task runs on ubuntu-latest (bash) in CI, where the single quotes are correct — they stop the shell from expanding the globs so lychee globs them itself. It isn't run on Windows.

— Claude (posted on Greg's behalf)


[hooks]
enter = "mise install --quiet --locked"

Expand Down
6 changes: 3 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@
<version>4.3.0</version>
<name>MaxMind minFraud API</name>
<description>MaxMind minFraud Score, Insights, Factors and Report Transaction API</description>
<url>http://dev.maxmind.com/minfraud</url>
<url>https://dev.maxmind.com/minfraud/</url>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.html</url>
<url>https://www.apache.org/licenses/LICENSE-2.0.html</url>
<distribution>repo</distribution>
</license>
</licenses>
<organization>
<name>MaxMind, Inc.</name>
<url>http://www.maxmind.com/</url>
<url>https://www.maxmind.com/en/home</url>
</organization>
<scm>
<url>https://github.com/maxmind/minfraud-api-java</url>
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/com/maxmind/minfraud/request/CustomInputs.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@

/**
* Custom inputs to be used in
* <a href="https://www.maxmind.com/en/minfraud-interactive/#/custom-rules">Custom Rules</a>.
* <a href="https://www.maxmind.com/en/accounts/current/minfraud-interactive/custom-rules">Custom
* Rules</a>.
* In order to use custom inputs, you must set them up from your account portal.
*/
public final class CustomInputs extends AbstractModel {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/maxmind/minfraud/response/Device.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
* date-time.
* @param localTime The date and time of the transaction at the UTC offset associated with the
* device. This is an RFC 3339 date-time.
* @see <a href="https://dev.maxmind.com/minfraud/track-devices?lang=en">Device Tracking Add-on</a>
* @see <a href="https://dev.maxmind.com/minfraud/track-devices/?lang=en">Device Tracking Add-on</a>
*/
public record Device(
@JsonProperty("confidence")
Expand Down
7 changes: 4 additions & 3 deletions src/main/java/com/maxmind/minfraud/response/Warning.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
* @param inputPointer This is a JSON Pointer to the input that the warning is associated with. For
* instance, if the warning was about the billing city, the value would be
* "/billing/city". See
* <a href="https://tools.ietf.org/html/rfc6901">RFC 6901</a> for the JSON
* Pointer spec.
* <a href="https://datatracker.ietf.org/doc/html/rfc6901">RFC 6901</a> for the
* JSON Pointer spec.
*/
public record Warning(
@JsonProperty("code")
Expand Down Expand Up @@ -99,7 +99,8 @@ public String getWarning() {
* @return This is a JSON Pointer to the input that the warning is associated with. For
* instance, if the warning was about the billing city, the value would be "/billing/city".
* See
* <a href="https://tools.ietf.org/html/rfc6901">RFC 6901</a> for the JSON Pointer spec.
* <a href="https://datatracker.ietf.org/doc/html/rfc6901">RFC 6901</a> for the JSON Pointer
* spec.
* @deprecated Use {@link #inputPointer()} instead. This method will be removed in 5.0.0.
*/
@Deprecated(since = "4.0.0", forRemoval = true)
Expand Down
Loading