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 38493b1e..433fc720 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ vendor/ *.iml *.sw? *.old +.lycheecache diff --git a/CLAUDE.md b/CLAUDE.md index 1aeb36fb..46ba4675 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -397,5 +397,5 @@ vendor/bin/phpunit - [API Documentation](https://maxmind.github.io/minfraud-api-php/) - [minFraud Web Services Docs](https://dev.maxmind.com/minfraud/) -- [Report Transaction API Docs](https://dev.maxmind.com/minfraud/report-transaction/) +- [Report Transaction API Docs](https://dev.maxmind.com/minfraud/report-a-transaction/) - GitHub Issues: https://github.com/maxmind/minfraud-api-php/issues diff --git a/README.md b/README.md index 73b169b9..add514b1 100644 --- a/README.md +++ b/README.md @@ -44,14 +44,14 @@ require 'vendor/autoload.php'; ## Install via Phar Although we strongly recommend using Composer, we also provide a -[phar archive](https://php.net/manual/en/book.phar.php) containing most of the +[phar archive](https://www.php.net/manual/en/book.phar.php) containing most of the dependencies for this API. The latest phar archive is available on [our releases page](https://github.com/maxmind/minfraud-api-php/releases). ### Install Dependencies Please note that you must have the PHP -[cURL extension](https://php.net/manual/en/book.curl.php) installed to use +[cURL extension](https://www.php.net/manual/en/book.curl.php) installed to use this archive. For Debian based distributions, this can typically be found in the `php-curl` package. For other operating systems, please consult the relevant documentation. After installing the extension you may need to restart @@ -81,7 +81,7 @@ tab. This library provides access to both the [minFraud (Score, Insights and Factors)](https://dev.maxmind.com/minfraud/) -and [Report Transaction](https://dev.maxmind.com/minfraud/report-transaction/) +and [Report Transaction](https://dev.maxmind.com/minfraud/report-a-transaction/) APIs. ### minFraud API @@ -336,7 +336,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 diff --git a/lychee.toml b/lychee.toml new file mode 100644 index 00000000..ec85b170 --- /dev/null +++ b/lychee.toml @@ -0,0 +1,59 @@ +# Lychee link checker configuration +# https://lychee.cli.rs/#/usage/config +# +# Run locally with: +# lychee './**/*.md' './src/**/*.php' './composer.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', + # The minFraud API responses doc renders its schema anchors client-side, so + # lychee cannot verify the #fragment even though the page and anchor exist. + '^https://dev\.maxmind\.com/minfraud/api-documentation/responses/#', + # 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/', + '(^|/)vendor/', + # Generated Hugo docs site committed under docs/public + '(^|/)docs/public/', + '(^|/)\.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 6f4350e8..9e1c09ed 100644 --- a/mise.lock +++ b/mise.lock @@ -31,3 +31,31 @@ url = "https://github.com/gohugoio/hugo/releases/download/v0.161.1/hugo_0.161.1_ [tools.hugo."platforms.windows-x64"] checksum = "sha256:7f8d030b37600c60bf2a782611257e6a768934fbe7724c1f3a1a501e6724cf0d" url = "https://github.com/gohugoio/hugo/releases/download/v0.161.1/hugo_0.161.1_windows-amd64.zip" + +[[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" diff --git a/mise.toml b/mise.toml index ecc66982..8a944863 100644 --- a/mise.toml +++ b/mise.toml @@ -7,6 +7,7 @@ disable_backends = [ [tools] hugo = "latest" +lychee = "latest" [hooks] enter = "mise install --quiet" @@ -22,3 +23,7 @@ run = "hugo --source docs --minify" [tasks.serve-docs] 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/**/*.php' './composer.json'" diff --git a/src/MinFraud.php b/src/MinFraud.php index 731e410f..49eeebad 100644 --- a/src/MinFraud.php +++ b/src/MinFraud.php @@ -114,7 +114,7 @@ public function jsonSerialize(): array * This returns a `MinFraud` object with the array to be sent to the web * service set to `$values`. Existing values will be replaced. * - * @link https://dev.maxmind.com/minfraud/api-documentation?lang=en + * @link https://dev.maxmind.com/minfraud/api-documentation/?lang=en * minFraud API docs * * @param array $values The request as a structured array @@ -197,7 +197,7 @@ public function with(array $values): self * @return MinFraud A new immutable MinFraud object. This object is a clone * of the original with additional data. * - * @link https://dev.maxmind.com/minfraud/api-documentation/requests?lang=en#schema--request--device + * @link https://dev.maxmind.com/minfraud/api-documentation/requests/?lang=en#schema--request--device * minFraud device API docs */ public function withDevice( @@ -324,7 +324,7 @@ public function withDevice( * @return MinFraud A new immutable MinFraud object. This object is a clone of * the original with additional data. * - * @link https://dev.maxmind.com/minfraud/api-documentation/requests?lang=en#schema--request--event + * @link https://dev.maxmind.com/minfraud/api-documentation/requests/?lang=en#schema--request--event * minFraud event API docs */ public function withEvent( @@ -405,7 +405,7 @@ public function withEvent( * This returns a `MinFraud` object with the `account` array set to * the values provided. Existing `` data will be replaced. * - * @link https://dev.maxmind.com/minfraud/api-documentation/requests?lang=en#schema--request--account + * @link https://dev.maxmind.com/minfraud/api-documentation/requests/?lang=en#schema--request--account * minFraud account API docs * * @param array $values An array of account data. The keys are the same as @@ -458,7 +458,7 @@ public function withAccount( * This returns a `MinFraud` object with the `email` array set to * values provided. Existing `email` data will be replaced. * - * @link https://dev.maxmind.com/minfraud/api-documentation/requests?lang=en#schema--request--email + * @link https://dev.maxmind.com/minfraud/api-documentation/requests/?lang=en#schema--request--email * minFraud email API docs * * @param array $values An array of email data. The keys are the same as @@ -519,7 +519,7 @@ public function withEmail( * This returns a `MinFraud` object with the `billing` array set to * `$values`. Existing `billing` data will be replaced. * - * @link https://dev.maxmind.com/minfraud/api-documentation/requests?lang=en#schema--request--billing + * @link https://dev.maxmind.com/minfraud/api-documentation/requests/?lang=en#schema--request--billing * minFraud billing API docs * * @param array $values An array of billing data. The keys are the same as @@ -646,7 +646,7 @@ public function withBilling( * This returns a `MinFraud` object with the `shipping` array set to * the values provided. Existing `shipping` data will be replaced. * - * @link https://dev.maxmind.com/minfraud/api-documentation/requests?lang=en#schema--request--shipping + * @link https://dev.maxmind.com/minfraud/api-documentation/requests/?lang=en#schema--request--shipping * minFraud shipping API docs * * @param array $values An array of shipping data. The keys are the same as @@ -768,7 +768,7 @@ public function withShipping( * This returns a `MinFraud` object with the `payment` array set to * the values provided. Existing `payment` data will be replaced. * - * @link https://dev.maxmind.com/minfraud/api-documentation/requests?lang=en#schema--request--payment + * @link https://dev.maxmind.com/minfraud/api-documentation/requests/?lang=en#schema--request--payment * minFraud payment API docs * * @param array $values An array of payment data. The keys are the same as @@ -1027,7 +1027,7 @@ public function withPayment( * This returns a `MinFraud` object with the `credit_card` array set to * provided values. Existing `credit_card` data will be replaced. * - * @link https://dev.maxmind.com/minfraud/api-documentation/requests?lang=en#schema--request--credit-card + * @link https://dev.maxmind.com/minfraud/api-documentation/requests/?lang=en#schema--request--credit-card * minFraud credit_card API docs * * @param array $values An array of credit card data. The keys are the same as @@ -1225,7 +1225,7 @@ public function withCustomInputs(array $values): self * This returns a `MinFraud` object with the `order` array set to * the provided values. Existing `order` data will be replaced. * - * @link https://dev.maxmind.com/minfraud/api-documentation/requests?lang=en#schema--request--order + * @link https://dev.maxmind.com/minfraud/api-documentation/requests/?lang=en#schema--request--order * minFraud order API docs * * @param array $values An array of order data. The keys are the same as the JSON keys. @@ -1243,7 +1243,7 @@ public function withCustomInputs(array $values): self * * @return MinFraud A new immutable MinFraud object. This object is a clone of the original with additional data. * - * @see https://support.maxmind.com/hc/en-us/articles/5452293435675-Order-and-Shopping-Cart-Inputs#h_01G0Z50Q0MRXQ5R52EF34E6G7J + * @see https://support.maxmind.com/knowledge-base/articles/order-and-shopping-cart-inputs-minfraud */ public function withOrder( array $values = [], @@ -1326,7 +1326,7 @@ public function withOrder( * This returns a `MinFraud` object with the provided values added to the * shopping cart array. Existing shopping cart data will be preserved. * - * @link https://dev.maxmind.com/minfraud/api-documentation/requests?lang=en#schema--request--shopping-cart--item + * @link https://dev.maxmind.com/minfraud/api-documentation/requests/?lang=en#schema--request--shopping-cart * minFraud shopping cart item API docs * * @param array $values An array of shopping cart data. The keys are the same diff --git a/src/MinFraud/Model/Device.php b/src/MinFraud/Model/Device.php index 521c7580..33dfff1c 100644 --- a/src/MinFraud/Model/Device.php +++ b/src/MinFraud/Model/Device.php @@ -10,7 +10,7 @@ * In order to receive device output from minFraud Insights or minFraud * Factors, you must be using the Device Tracking Add-on. * - * @link https://dev.maxmind.com/minfraud/track-devices?lang=en Device Tracking + * @link https://dev.maxmind.com/minfraud/track-devices/?lang=en Device Tracking * Add-on */ class Device implements \JsonSerializable