From 52ed659a9f1e8776c13bc4079c239e4236ca5dfd Mon Sep 17 00:00:00 2001 From: Brendan Ryan <1572504+brendanjryan@users.noreply.github.com> Date: Mon, 27 Apr 2026 19:48:31 -0700 Subject: [PATCH 1/3] ci: enable dead-link checks and lychee for external links Flip checkDeadlinks to true and add lychee for external URL validation. Extend the syncTips link-rewriter with two upstream-typo escape hatches (tip-1011 'verify/src' path, tip-0000 './tip_template.md') so the dead link checker passes against TIPs synced from tempoxyz/tempo. --- .github/workflows/links.yml | 59 +++++++++++++++++++++++++++++++++++++ lychee.toml | 41 ++++++++++++++++++++++++++ vite.config.ts | 18 ++++++++++- vocs.config.ts | 3 +- 4 files changed, 118 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/links.yml create mode 100644 lychee.toml diff --git a/.github/workflows/links.yml b/.github/workflows/links.yml new file mode 100644 index 00000000..4535e497 --- /dev/null +++ b/.github/workflows/links.yml @@ -0,0 +1,59 @@ +name: External Links + +on: + push: + branches: [main] + pull_request: + schedule: + # Weekly link-rot check, independent of code changes. + - cron: "0 9 * * 1" + workflow_dispatch: + +permissions: {} + +concurrency: + group: links-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + lychee: + name: Lychee + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: read + issues: write + + steps: + - name: Clone repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - name: Restore lychee cache + uses: actions/cache@v4 + with: + path: .lycheecache + key: lychee-${{ github.sha }} + restore-keys: lychee- + + - name: Run lychee + uses: lycheeverse/lychee-action@v2 + with: + args: >- + --config lychee.toml + --cache + --base . + 'README.md' + 'src/pages/**/*.{md,mdx}' + 'vocs.config.ts' + fail: ${{ github.event_name == 'pull_request' || github.event_name == 'push' }} + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Open issue on scheduled failure + if: failure() && github.event_name == 'schedule' + uses: peter-evans/create-issue-from-file@v5 + with: + title: "Broken external links detected" + content-filepath: ./lychee/out.md + labels: docs, links diff --git a/lychee.toml b/lychee.toml new file mode 100644 index 00000000..2fd902e9 --- /dev/null +++ b/lychee.toml @@ -0,0 +1,41 @@ +# lychee configuration for the Tempo docs site. +# Validates external links in markdown, MDX, and config sources. +# See https://lychee.cli.rs/usage/config/ + +# Network settings +max_redirects = 10 +max_concurrency = 16 +timeout = 20 +retry_wait_time = 2 + +# Some hosts (Twitter, LinkedIn, Cloudflare-protected sites) reject the default UA. +user_agent = "Mozilla/5.0 (compatible; tempo-docs-link-checker/1.0; +https://docs.tempo.xyz)" + +# Auth-walled or rate-limited statuses are still "reachable". +accept = ["200..=299", "401", "403", "429"] + +exclude_path = [ + "node_modules", + "dist", + ".vocs", + ".vercel", + "playwright-report", + "test-results", + "patches", +] + +exclude = [ + # Local / placeholder hosts. + "^https?://localhost", + "^https?://127\\.0\\.0\\.1", + "^https?://0\\.0\\.0\\.0", + "^https?://\\[::1\\]", + "^https?://([a-z0-9-]+\\.)*example\\.(com|org|net)", + # SVG xmlns reference, not a real link. + "^http://www\\.w3\\.org/2000/svg$", +] + +# Reuse cached results across runs. +cache = true +max_cache_age = "1d" +no_progress = true diff --git a/vite.config.ts b/vite.config.ts index 08ed63aa..3dd4c302 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -101,11 +101,27 @@ function syncTips(): Plugin { await Promise.all( tipFiles.map(async (file) => { let content = await fetch(file.download_url).then((r) => r.text()) - // Fix dead links in TIPs that reference local paths instead of GitHub URLs + // Fix dead links in TIPs that reference paths in the tempoxyz/tempo + // repo. These resolve fine on github.com but break Vocs' dead-link + // checker, since the files don't exist in the docs site. Rewriting + // them here lets us keep `checkDeadlinks: true` without forking + // upstream content. Add new patterns as upstream typos appear. content = content.replace( /\(tips\/ref-impls\/src\/interfaces\/(\w+\.sol)\)/g, '(https://github.com/tempoxyz/tempo-std/blob/master/src/interfaces/$1)', ) + // TIP-1011 references `tips/verify/src/interfaces/...` (upstream typo + // of `ref-impls`). Map it to the actual tempoxyz/tempo location. + content = content.replace( + /\(tips\/verify\/src\/interfaces\/(\w+\.sol)\)/g, + '(https://github.com/tempoxyz/tempo/blob/main/tips/ref-impls/src/interfaces/$1)', + ) + // tip-0000 links to `./tip_template.md`, which lives in the tempo + // repo but not in the docs site. + content = content.replace( + /\(\.\/tip_template\.md\)/g, + '(https://github.com/tempoxyz/tempo/blob/main/tips/tip_template.md)', + ) // Escape angle brackets outside of code blocks/inline code so MDX doesn't // treat them as JSX (e.g. `Mapping` in prose). content = escapeAngleBrackets(content) diff --git a/vocs.config.ts b/vocs.config.ts index 0f792237..e749fe4d 100644 --- a/vocs.config.ts +++ b/vocs.config.ts @@ -20,8 +20,7 @@ export default defineConfig({ // textColor: 'white', // }, changelog: Changelog.github({ prereleases: true, repo: 'tempoxyz/tempo' }), - // TODO: Set back to true once tempoxyz/tempo#tip-1011 dead link is fixed - checkDeadlinks: 'warn', + checkDeadlinks: true, editLink: { link: 'https://github.com/tempoxyz/docs/edit/main/src/pages/:path', text: 'Suggest changes to this page', From ad6584de417e680daa5a6a2fec15a9dfbc36f58b Mon Sep 17 00:00:00 2001 From: Brendan Ryan <1572504+brendanjryan@users.noreply.github.com> Date: Mon, 27 Apr 2026 19:51:50 -0700 Subject: [PATCH 2/3] ci(links): drop --base/--config/--cache args lychee auto-detects lychee.toml from cwd and inherits cache settings from config. The previous --base . was rejected by lychee 0.23 (must be URL or absolute path); we don't need root-relative resolution since Vocs checks internal links. --- .github/workflows/links.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/links.yml b/.github/workflows/links.yml index 4535e497..77aebef6 100644 --- a/.github/workflows/links.yml +++ b/.github/workflows/links.yml @@ -41,9 +41,6 @@ jobs: uses: lycheeverse/lychee-action@v2 with: args: >- - --config lychee.toml - --cache - --base . 'README.md' 'src/pages/**/*.{md,mdx}' 'vocs.config.ts' From 51ae2a85a42fa2ef677027c2a9b597b1ccad4b0a Mon Sep 17 00:00:00 2001 From: Brendan Ryan <1572504+brendanjryan@users.noreply.github.com> Date: Mon, 27 Apr 2026 19:56:20 -0700 Subject: [PATCH 3/3] fix: repair stale tempo repo links and scope lychee to docs Five sidebar 'Reference Implementation' entries pointed at tips/ref-impls/src/*.sol, which no longer exist on tempoxyz/tempo main. The Solidity reference now lives in tempoxyz/tempo-std interfaces; updated all five plus the renamed stablecoin_exchange precompile (now stablecoin_dex). Scoped lychee to src/pages and vocs.config.ts. README.md has pre-existing broken refs (missing LICENSE files, /public lockup paths) unrelated to docs content. Added --root-dir so future root-relative links in MDX resolve against the workspace. --- .github/workflows/links.yml | 5 ++++- vocs.config.ts | 10 +++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/links.yml b/.github/workflows/links.yml index 77aebef6..9da554a9 100644 --- a/.github/workflows/links.yml +++ b/.github/workflows/links.yml @@ -40,8 +40,11 @@ jobs: - name: Run lychee uses: lycheeverse/lychee-action@v2 with: + # README.md is a GitHub-only artifact with pre-existing + # broken references (LICENSE files, lockup paths); excluded + # from this check. Docs site content lives in src/pages/. args: >- - 'README.md' + --root-dir ${{ github.workspace }} 'src/pages/**/*.{md,mdx}' 'vocs.config.ts' fail: ${{ github.event_name == 'pull_request' || github.event_name == 'push' }} diff --git a/vocs.config.ts b/vocs.config.ts index e749fe4d..d9045790 100644 --- a/vocs.config.ts +++ b/vocs.config.ts @@ -467,7 +467,7 @@ export default defineConfig({ }, { text: 'Reference Implementation', - link: 'https://github.com/tempoxyz/tempo/blob/main/tips/ref-impls/src/TIP20.sol', + link: 'https://github.com/tempoxyz/tempo-std/blob/master/src/interfaces/ITIP20.sol', }, { text: 'Rust Implementation', @@ -503,7 +503,7 @@ export default defineConfig({ }, { text: 'Reference Implementation', - link: 'https://github.com/tempoxyz/tempo/blob/main/tips/ref-impls/src/TIP403Registry.sol', + link: 'https://github.com/tempoxyz/tempo-std/blob/master/src/interfaces/ITIP403Registry.sol', }, { text: 'Rust Implementation', @@ -537,7 +537,7 @@ export default defineConfig({ }, { text: 'Reference Implementation', - link: 'https://github.com/tempoxyz/tempo/blob/main/tips/ref-impls/src/FeeManager.sol', + link: 'https://github.com/tempoxyz/tempo-std/blob/master/src/interfaces/IFeeManager.sol', }, { text: 'Rust Implementation', @@ -625,11 +625,11 @@ export default defineConfig({ }, { text: 'Reference Implementation', - link: 'https://github.com/tempoxyz/tempo/blob/main/tips/ref-impls/src/stablecoinDex.sol', + link: 'https://github.com/tempoxyz/tempo-std/blob/master/src/interfaces/IStablecoinDEX.sol', }, { text: 'Rust Implementation', - link: 'https://github.com/tempoxyz/tempo/tree/main/crates/precompiles/src/stablecoin_exchange', + link: 'https://github.com/tempoxyz/tempo/tree/main/crates/precompiles/src/stablecoin_dex', }, ], },