Skip to content
Merged
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
55 changes: 55 additions & 0 deletions .docs-test.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Configuration for the docs-theme-extras HTML test harness when run against
# agentregistry-oss.
#
# The harness lives in github.com/solo-io/docs-theme-extras and reads this file
# via the DOCS_TEST_CONFIG env var (set by the Makefile or CI). All relative
# paths are resolved against this file's directory. The harness does NOT build
# the site — `hugo` runs first and writes to builtRoot.
#
# First-pass config: structural HTML quality (no shortcode leaks, no markdown
# bleed, image alt text, console errors, contrast) against the production build.
# Tighten/expand as the suite stabilizes.

version = "1"
name = "agentregistry-oss"
brand = "oss"

# Where the consumer's built HTML lives. Everything operates on this tree.
builtRoot = "./public"
baseURL = "/"

# Source-tree roots for author-side lints (e.g. curl-quotes scans markdown
# directly). Narrowed to docs content so lints don't trip on the marketing
# landing page.
scanRoots = [
"./content/docs",
]

# NOTE: agentregistry is a flat, unversioned docs site (/docs/<section>/<page>/)
# with no site.Params.sections and no version segment. There is intentionally
# no [versioning] block — version-aware specs detect the absence and skip
# gracefully (same mechanism agw's standalone/unversioned docs rely on).

[checks]
# Smoke is for multi-product cross-runs (SMOKE_PRODUCT env); agr is a single
# site, so skip. Cross-browser is opt-in and slow; run it manually when needed.
smoke = false
crossBrowser = false

# Allowlists for known-benign noise that surfaces against real content (the
# module's bundled fixture has none of this). Tighten as content is fixed.
[allowlists]
consoleErrors = [
# Third-party analytics/chat (GA, GTM, Qualified) make backend calls on page
# init that fail in the offline test environment, surfacing as a bare
# "invalid_request" pageerror with no stack. Not fixable without a live
# backend — suppress until those scripts are refactored to not throw on init.
"invalid_request",
# Hextra's main.min.js null-derefs (reading 'removeAttribute' /
# 'addEventListener') on the /docs/ landing page, which suppresses the
# sidebar and so omits the toggle markup main.js expects. Same class of
# benign error agw fixed at source via hidden navbar stand-in elements;
# agr hasn't adopted that yet, so suppress here until it does.
"removeAttribute",
"addEventListener",
]
126 changes: 126 additions & 0 deletions .github/workflows/framework-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# Hugo + Hextra docs-framework harness, run against agentregistry-oss's built site.
#
# The harness lives in solo-io/docs-theme-extras and is checked out at the
# version pinned in go.mod (semver tag or pseudo-version). Layouts and tests
# stay in lockstep — bumping the module pin is one PR that updates both.
#
# NOTE: this workflow assumes go.mod pins a RELEASED docs-theme-extras version
# with no local `replace` directive. A local `replace` (absolute path) used for
# dev will fail the Hugo build here — remove it and bump the pin before relying
# on this check.
#
# Marked continue-on-error while allowlists and fixture-aware specs settle.
# Promote to a required check once it stays green for a sustained run.

name: Framework tests

on:
pull_request:
paths:
- 'layouts/**'
- 'static/**'
- 'assets/**'
- 'go.mod'
- 'go.sum'
- 'hugo.yaml'
- '.docs-test.toml'
- '.github/workflows/framework-tests.yml'
workflow_dispatch:

jobs:
framework-test-static:
name: Static checks
runs-on: ubuntu-latest
continue-on-error: true
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
with:
go-version: 'stable'
cache: false
- uses: peaceiris/actions-hugo@75d2e84710de30f6ff7268e08f310b60ef14033f # v3
with:
hugo-version: '0.160.1'
extended: true

- name: Resolve docs-theme-extras ref from go.mod
id: theme-sha
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Pull the version field for the module's `require` line. exit-on-first
# match takes `require` (which precedes any `replace`) so a dev-only
# replace line doesn't shadow it. Handles tags, prereleases, and Go
# pseudo-versions.
version=$(awk -v pkg="github.com/solo-io/docs-theme-extras" '
/^replace/ { next }
{ for (i=1; i<=NF; i++) if ($i == pkg) { print $(i+1); exit } }
' go.mod)
if [ -z "$version" ]; then
echo "Could not extract docs-theme-extras version from go.mod" >&2
exit 1
fi
# Pseudo-version shape: ends with .<14-digit timestamp>-<12-hex short SHA>.
if echo "$version" | grep -qE -- '\.[0-9]{14}-[0-9a-f]{12}$'; then
short=$(echo "$version" | grep -oE '[0-9a-f]{12}$')
ref=$(gh api "repos/solo-io/docs-theme-extras/commits/${short}" --jq .sha)
if [ -z "$ref" ]; then
echo "Could not resolve full SHA for short=${short}" >&2
exit 1
fi
else
ref="$version"
fi
echo "ref=$ref" >> "$GITHUB_OUTPUT"

- name: Check out docs-theme-extras at module pin
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
repository: solo-io/docs-theme-extras
ref: ${{ steps.theme-sha.outputs.ref }}
path: docs-theme-extras

- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: 'docs-theme-extras/package-lock.json'

- name: Build site with Hugo
run: |
# agentregistry's assets/css/main.css is compiled by Hugo's
# css.TailwindCSS, which shells out to the Tailwind CLI declared in
# this repo's devDependencies. Install them so Hugo finds the binary.
npm install
hugo --gc --minify

- name: Install harness dependencies
working-directory: docs-theme-extras
run: npm ci

- name: Run static specs
working-directory: docs-theme-extras
env:
DOCS_TEST_CONFIG: ${{ github.workspace }}/.docs-test.toml
run: |
npx playwright test --project=static --reporter=list,html 2>&1 | tee playwright-output.txt

- name: Append summary to PR check
if: always()
working-directory: docs-theme-extras
run: |
{
echo "## Framework tests — static (informational)"
echo ""
echo '```'
tail -25 playwright-output.txt 2>/dev/null || echo "No test output captured."
echo '```'
} >> "$GITHUB_STEP_SUMMARY"

- name: Upload report
if: always()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: framework-test-static-report
path: docs-theme-extras/playwright-report
retention-days: 7
188 changes: 188 additions & 0 deletions .github/workflows/links.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
name: Links

# Scheduled: full check on all files, creates an issue, posts to Slack.
# Pull request: local links only on changed files, no issue or Slack.
#
# The shared link-checking scripts live in the public solo-io/docs-link-checking
# repo, cloned with the built-in GITHUB_TOKEN (no dedicated secret needed). Only
# the scheduled run's Slack post needs a SLACK_BOT_TOKEN secret; PR runs skip it.
on:
workflow_dispatch:
schedule:
- cron: "00 04 * * MON"
pull_request:
paths:
- 'content/**'
- 'assets/**'
- 'static/**'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
linkChecker:
runs-on: ubuntu-latest
timeout-minutes: 60
permissions:
contents: read
issues: write
env:
PRODUCT_NAME: agentregistry OSS
ISSUE_TITLE: Link Checker Report - agentregistry OSS
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 100

- name: Checkout shared link-checking scripts
uses: actions/checkout@v4
with:
repository: solo-io/docs-link-checking
path: docs-link-checking
# solo-io/docs-link-checking is a public repo, so the auto-provided
# GITHUB_TOKEN can clone it — no dedicated GH_TOKEN secret needed
# (agentregistry-dev/website doesn't define one). Matches the token
# used in framework-tests.yml.
token: ${{ secrets.GITHUB_TOKEN }}

- name: Set up Hugo
uses: peaceiris/actions-hugo@v3
with:
hugo-version: '0.160.1'
extended: true

- name: Install Lychee
run: |
chmod +x docs-link-checking/install-lychee.sh
docs-link-checking/install-lychee.sh

- name: Hugo build
run: |
# Tailwind CLI (this repo's devDependencies) is invoked by Hugo's
# css.TailwindCSS for assets/css/main.css.
npm install
hugo --config hugo.yaml

- name: Prepare workspace
run: mkdir -p artifacts

- name: Check Links with Lychee
id: lychee
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
shopt -s globstar
set +e

# agentregistry is a flat, unversioned site (/docs/<section>/<page>/),
# so no version excludes/remaps are needed — just resolve absolute
# production URLs to the local build.
LYCHEE_COMMON=(lychee
--verbose
--config docs-link-checking/lychee.toml
--root-dir "${{ github.workspace }}/public"
--index-files index.html
--remap "^https://agentregistry\.dev/ file:///${{ github.workspace }}/public/"
--format json
--user-agent curl/8.4.0
--output "${{ github.workspace }}/artifacts/agentregistry-oss-links.json"
public/**/*.html
)

if [ "${{ github.event_name }}" = "pull_request" ]; then
# Skip external URLs on PRs; remaps still resolve agentregistry.dev
# links to local files so internal links are checked.
"${LYCHEE_COMMON[@]}" --exclude "^https?://"
else
"${LYCHEE_COMMON[@]}" --github-token ${{ secrets.GITHUB_TOKEN }}
fi > "${{ github.workspace }}/artifacts/agentregistry-oss-links-json.log" 2>&1

EXIT=$?
set -e
echo "has_failures=$([ "$EXIT" != "0" ] && echo 'true' || echo 'false')" >> "$GITHUB_OUTPUT"

- name: Generate markdown report from JSON
id: report
if: hashFiles('artifacts/agentregistry-oss-links.json') != ''
run: |
chmod +x docs-link-checking/generate-link-report.sh
docs-link-checking/generate-link-report.sh \
"${{ github.workspace }}/artifacts/agentregistry-oss-links.json" \
"${{ github.workspace }}/artifacts/agentregistry-oss-links.md" \
"${{ github.workspace }}/public" \
"${{ github.event_name == 'pull_request' && 'pr' || '' }}"

- name: Create issue from report
if: steps.report.outputs.has_issues == 'true' && github.event_name != 'pull_request'
id: create-issue
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
uses: peter-evans/create-issue-from-file@v6
with:
title: ${{ env.ISSUE_TITLE }}
content-filepath: ./artifacts/agentregistry-oss-links.md

- name: Set issue URL for Slack
if: steps.report.outputs.has_issues == 'true' && github.event_name != 'pull_request'
id: issue-url
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_NUMBER: ${{ steps.create-issue.outputs.issue-number }}
ISSUE_TITLE: ${{ env.ISSUE_TITLE }}
LABELS: links,bug
REPOSITORY: ${{ github.repository }}
run: |
chmod +x docs-link-checking/set-issue-url.sh
docs-link-checking/set-issue-url.sh

- name: Remove public directory
run: rm -rf public

- name: Read link checker results
id: link-stats
env:
MD_FILE: artifacts/agentregistry-oss-links.md
JSON_FILE: artifacts/agentregistry-oss-links.json
run: |
chmod +x docs-link-checking/read-link-stats.sh
docs-link-checking/read-link-stats.sh

- name: Post results to Slack
if: github.event_name != 'pull_request'
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
SLACK_CHANNEL: "#doctopus-tests"
ERRORS: ${{ steps.link-stats.outputs.errors }}
WARNINGS: ${{ steps.link-stats.outputs.warnings }}
REDIRECTS: ${{ steps.link-stats.outputs.redirects }}
ICON: ${{ steps.link-stats.outputs.icon }}
REPOSITORY: ${{ github.repository }}
RUN_ID: ${{ github.run_id }}
ISSUE_LINE: ${{ steps.issue-url.outputs.issue_line }}
run: |
chmod +x docs-link-checking/post-slack-results.sh
docs-link-checking/post-slack-results.sh

- name: Upload artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: link-checker-assets
path: artifacts/*

- name: Write report to job summary
if: hashFiles('artifacts/agentregistry-oss-links.md') != ''
run: cat artifacts/agentregistry-oss-links.md >> "$GITHUB_STEP_SUMMARY"

- name: Fail check if errors exist
if: github.event_name == 'pull_request'
env:
ERRORS: ${{ steps.link-stats.outputs.errors }}
run: |
if [ "${ERRORS:-0}" -gt 0 ]; then
echo "Link checker found ${ERRORS} error(s). See artifacts for details."
exit 1
else
echo "Link checker found ${ERRORS} errors."
fi
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
# Hugo build artifacts
public/
public-*/
resources/
.hugo_build.lock
.build.log

# Test artifacts (link checker, framework tests)
artifacts/
playwright-report/
test-results/

# OS files
.DS_Store
Expand Down
Loading
Loading