Skip to content

Commit 3ed43ed

Browse files
authored
chore(docs): overhaul CI pipeline, fix anchor links, and refine UI navigation (#270)
* chore: split docs build and deploy workflow and add manual trigger * chore: dynamically cache ucp-schema based on crate version * fix: disable instant navigation which is causing url anchor issues * fix: use environment variable for site_url in mkdocs config * fix: export SITE_URL to deploy jobs to correctly resolve absolute URLs * style: prevent site title and version selector from hiding on scroll
1 parent 5f8b834 commit 3ed43ed

File tree

4 files changed

+191
-78
lines changed

4 files changed

+191
-78
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: 'Setup Docs Build Environment'
2+
description: 'Installs dependencies needed to build the UCP documentation'
3+
runs:
4+
using: "composite"
5+
steps:
6+
- name: Install system dependencies
7+
shell: bash
8+
run: sudo apt-get update && sudo apt-get install -y libcairo2-dev libfreetype6-dev libffi-dev libjpeg-dev libpng-dev libz-dev
9+
10+
- name: Install uv
11+
uses: astral-sh/setup-uv@v7
12+
with:
13+
enable-cache: true
14+
15+
- name: Install documentation dependencies
16+
shell: bash
17+
run: uv sync
18+
19+
- name: Get latest ucp-schema version
20+
id: get-version
21+
shell: bash
22+
run: |
23+
VERSION=$(curl -s https://crates.io/api/v1/crates/ucp-schema | jq -r '.crate.max_version')
24+
echo "version=$VERSION" >> $GITHUB_OUTPUT
25+
26+
- name: Cache ucp-schema binary
27+
id: cache-ucp-schema
28+
uses: actions/cache@v4
29+
with:
30+
path: ~/.cargo/bin/ucp-schema
31+
key: ${{ runner.os }}-ucp-schema-${{ steps.get-version.outputs.version }}
32+
33+
- name: Install ucp-schema
34+
if: steps.cache-ucp-schema.outputs.cache-hit != 'true'
35+
shell: bash
36+
run: cargo install ucp-schema
37+
38+
- name: Add cargo to PATH
39+
shell: bash
40+
run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH

.github/workflows/docs.yml

Lines changed: 134 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -35,35 +35,15 @@ on:
3535
- "source/**"
3636

3737
jobs:
38-
build_and_deploy:
38+
lint:
3939
runs-on: ubuntu-latest
40-
permissions:
41-
contents: write
42-
actions: read
43-
pages: read
44-
4540
steps:
4641
- name: Checkout Code
4742
uses: actions/checkout@v5
4843
with:
49-
token: ${{ secrets.GITHUB_TOKEN }}
5044
fetch-depth: 0
5145

52-
- name: Configure Git Credentials
53-
run: |
54-
git config --global user.name github-actions[bot]
55-
git config --global user.email 41898282+github-actions[bot]@users.noreply.github.com
56-
57-
- name: Install system dependencies
58-
run: |
59-
sudo apt-get update
60-
sudo apt-get install -y libcairo2-dev libfreetype6-dev libffi-dev libjpeg-dev libpng-dev libz-dev
61-
62-
- name: Install the latest version of uv
63-
uses: astral-sh/setup-uv@v7
64-
65-
- name: Install documentation dependencies
66-
run: uv sync
46+
- uses: ./.github/actions/setup-build-env
6747

6848
- name: Lint YAML files
6949
run: uv run yamllint -c .github/linters/.yamllint.yml .
@@ -74,75 +54,126 @@ jobs:
7454
with:
7555
files: source/**
7656

77-
- name: Install ucp-schema for runtime resolution
78-
run: |
79-
cargo install ucp-schema
80-
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
81-
8257
- name: Lint source schemas
83-
if: steps.source_files_changed.outputs.any_changed == 'true'
58+
if: steps.source_files_changed.outputs.any_changed == 'true' || github.event_name == 'workflow_dispatch'
8459
run: ucp-schema lint source/
8560

86-
- name: Create folders for JSON publishing
61+
build_and_verify_main:
62+
needs: lint
63+
runs-on: ubuntu-latest
64+
if: github.ref == 'refs/heads/main' || github.event.pull_request.base.ref == 'main'
65+
steps:
66+
- name: Checkout Code
67+
uses: actions/checkout@v5
68+
with:
69+
fetch-depth: 0
70+
71+
- name: Configure Git Credentials
8772
run: |
88-
mkdir -p site/schemas
89-
mkdir -p site/services
90-
mkdir -p site/handlers
91-
mkdir -p site/discovery
73+
git config --global user.name github-actions[bot]
74+
git config --global user.email 41898282+github-actions[bot]@users.noreply.github.com
75+
76+
- uses: ./.github/actions/setup-build-env
9277

9378
- name: Configure Site URL
9479
env:
9580
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
9681
run: |
97-
# Fetch the Pages URL. Fails safely if not enabled.
9882
PAGES_URL=$(gh api "repos/${{ github.repository }}/pages" --jq '.html_url' 2>/dev/null || true)
99-
100-
if [ -z "$PAGES_URL" ]; then
101-
echo "Pages URL not detected. Falling back to default structure."
102-
PAGES_URL="https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}"
103-
fi
104-
105-
# Ensure trailing slash
106-
if [[ "$PAGES_URL" != */ ]]; then
107-
PAGES_URL="${PAGES_URL}/"
108-
fi
109-
110-
echo "Set SITE_URL to $PAGES_URL"
83+
if [ -z "$PAGES_URL" ]; then PAGES_URL="https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}"; fi
84+
if [[ "$PAGES_URL" != */ ]]; then PAGES_URL="${PAGES_URL}/"; fi
11185
echo "SITE_URL=$PAGES_URL" >> $GITHUB_ENV
86+
echo "SPEC_URL=${PAGES_URL}latest/specification/overview/" >> $GITHUB_ENV
11287
11388
- name: Build and Verify Documentation Site (Main/PR)
114-
if: github.ref == 'refs/heads/main' || github.event.pull_request.base.ref == 'main'
11589
run: |
116-
# Create a full local preview (including mike logic) for validation
11790
bash scripts/build_local.sh --main-only
11891
uv run python scripts/check_links.py local_preview
11992
93+
build_and_verify_release:
94+
needs: lint
95+
runs-on: ubuntu-latest
96+
if: startsWith(github.ref, 'refs/heads/release/') || startsWith(github.event.pull_request.base.ref, 'release/')
97+
steps:
98+
- name: Checkout Code
99+
uses: actions/checkout@v5
100+
with:
101+
fetch-depth: 0
102+
103+
- name: Configure Git Credentials
104+
run: |
105+
git config --global user.name github-actions[bot]
106+
git config --global user.email 41898282+github-actions[bot]@users.noreply.github.com
107+
108+
- uses: ./.github/actions/setup-build-env
109+
110+
- name: Configure Site URL
111+
env:
112+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
113+
run: |
114+
PAGES_URL=$(gh api "repos/${{ github.repository }}/pages" --jq '.html_url' 2>/dev/null || true)
115+
if [ -z "$PAGES_URL" ]; then PAGES_URL="https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}"; fi
116+
if [[ "$PAGES_URL" != */ ]]; then PAGES_URL="${PAGES_URL}/"; fi
117+
echo "SITE_URL=$PAGES_URL" >> $GITHUB_ENV
118+
echo "SPEC_URL=${PAGES_URL}latest/specification/overview/" >> $GITHUB_ENV
119+
120120
- name: Build and Verify Specification Docs (Release Branches)
121-
if: startsWith(github.ref, 'refs/heads/release/') || startsWith(github.event.pull_request.base.ref, 'release/')
122121
run: |
123122
export DOCS_MODE=spec
124123
uv run mkdocs build --strict
125124
uv run python scripts/check_links.py site
126125
126+
deploy_main:
127+
needs: build_and_verify_main
128+
runs-on: ubuntu-latest
129+
if: contains(fromJson('["push", "workflow_dispatch"]'), github.event_name) && github.ref == 'refs/heads/main'
130+
permissions:
131+
contents: write
132+
pages: read
133+
steps:
134+
- name: Checkout Code
135+
uses: actions/checkout@v5
136+
with:
137+
token: ${{ secrets.GITHUB_TOKEN }}
138+
fetch-depth: 0
139+
140+
- name: Configure Git Credentials
141+
run: |
142+
git config --global user.name github-actions[bot]
143+
git config --global user.email 41898282+github-actions[bot]@users.noreply.github.com
144+
145+
- uses: ./.github/actions/setup-build-env
146+
147+
- name: Configure Site URL
148+
env:
149+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
150+
run: |
151+
PAGES_URL=$(gh api "repos/${{ github.repository }}/pages" --jq '.html_url' 2>/dev/null || true)
152+
if [ -z "$PAGES_URL" ]; then PAGES_URL="https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}"; fi
153+
if [[ "$PAGES_URL" != */ ]]; then PAGES_URL="${PAGES_URL}/"; fi
154+
echo "SITE_URL=$PAGES_URL" >> $GITHUB_ENV
155+
echo "SPEC_URL=${PAGES_URL}latest/specification/overview/" >> $GITHUB_ENV
156+
127157
- name: Deploy development version from main branch
128-
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
129158
run: |
130-
# 1. Deploy Specification Site using mike (DOCS_MODE=spec)
131159
export DOCS_MODE=spec
132160
uv run mike deploy --push draft
133161
134-
# 2. Build Root Site (DOCS_MODE=root)
135162
export DOCS_MODE=root
136163
uv run mkdocs build --strict
137164
138-
# 3. Deploy Root Site to gh-pages root
139-
# Fetch and checkout gh-pages
140-
git fetch origin gh-pages
141-
git checkout gh-pages
165+
# Checkout gh-pages into a separate directory to avoid overwriting the workspace
166+
# and causing GitHub Actions post-run hooks to fail (as they need .github/actions)
167+
git clone --branch gh-pages "https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git" gh-pages-branch
168+
cd gh-pages-branch
169+
170+
# Remove existing root files except versions and git metadata
171+
git ls-files | grep -vE "^(\.nojekyll|draft|latest|[0-9]{4}-[0-9]{2}-[0-9]{2}|versions\.json|\.git)" | xargs -r rm -f
172+
find . -maxdepth 1 -type d -empty -not -path "./.git*" -delete
142173
143174
# Copy build artifacts to root
144-
cp -r site/* .
145-
rm -rf site
175+
cp -r ../site/* .
176+
rm -rf ../site
146177
147178
# Add redirects for all specification files
148179
rm -rf specification
@@ -153,43 +184,72 @@ jobs:
153184
git commit -m "Deploy root site from main" --allow-empty
154185
git push origin gh-pages
155186
187+
deploy_release:
188+
needs: build_and_verify_release
189+
runs-on: ubuntu-latest
190+
if: contains(fromJson('["push", "workflow_dispatch"]'), github.event_name) && startsWith(github.ref, 'refs/heads/release/')
191+
permissions:
192+
contents: write
193+
pages: read
194+
steps:
195+
- name: Checkout Code
196+
uses: actions/checkout@v5
197+
with:
198+
token: ${{ secrets.GITHUB_TOKEN }}
199+
fetch-depth: 0
200+
201+
- name: Configure Git Credentials
202+
run: |
203+
git config --global user.name github-actions[bot]
204+
git config --global user.email 41898282+github-actions[bot]@users.noreply.github.com
205+
206+
- uses: ./.github/actions/setup-build-env
207+
208+
- name: Configure Site URL
209+
env:
210+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
211+
run: |
212+
PAGES_URL=$(gh api "repos/${{ github.repository }}/pages" --jq '.html_url' 2>/dev/null || true)
213+
if [ -z "$PAGES_URL" ]; then PAGES_URL="https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}"; fi
214+
if [[ "$PAGES_URL" != */ ]]; then PAGES_URL="${PAGES_URL}/"; fi
215+
echo "SITE_URL=$PAGES_URL" >> $GITHUB_ENV
216+
echo "SPEC_URL=${PAGES_URL}latest/specification/overview/" >> $GITHUB_ENV
217+
156218
- name: Deploy release version
157-
if: startsWith(github.ref, 'refs/heads/release/')
158219
run: |
159220
export DOCS_MODE=spec
160-
# Extract the date (e.g., release/2026-01-11 -> 2026-01-11)
161221
VERSION_NAME=${GITHUB_REF#refs/heads/release/}
162-
163-
# Fetch all release branches to determine if this is the latest
164222
git fetch origin "+refs/heads/release/*:refs/remotes/origin/release/*"
165-
166-
# Find the highest version number among all release branches
167223
LATEST_VERSION=$(git branch -r --list "origin/release/*" | sed 's|origin/release/||' | sort -V | tail -n 1 | tr -d ' ')
168224
169-
echo "Deploying version: $VERSION_NAME"
170-
echo "Latest detected version: $LATEST_VERSION"
171-
172225
if [ "$VERSION_NAME" = "$LATEST_VERSION" ]; then
173-
echo "This is the latest version. Updating 'latest' alias."
174226
uv run mike deploy --push --update-aliases "$VERSION_NAME" latest
175227
else
176-
echo "This is NOT the latest version. Deploying without updating 'latest' alias."
177228
uv run mike deploy --push "$VERSION_NAME"
178229
fi
179230
231+
create_release:
232+
needs: deploy_release
233+
runs-on: ubuntu-latest
234+
if: contains(fromJson('["push", "workflow_dispatch"]'), github.event_name) && startsWith(github.ref, 'refs/heads/release/')
235+
permissions:
236+
contents: write
237+
steps:
238+
- name: Checkout Code
239+
uses: actions/checkout@v5
240+
with:
241+
token: ${{ secrets.GITHUB_TOKEN }}
242+
fetch-depth: 0
243+
180244
- name: Create GitHub Release and Tag
181-
if: startsWith(github.ref, 'refs/heads/release/')
182245
env:
183246
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
184247
run: |
185248
VERSION_DATE=${GITHUB_REF#refs/heads/release/}
186249
TAG_NAME="v$VERSION_DATE"
187250
188-
# Create Release (This implicitly creates the git tag)
189-
# The '|| true' ensures the workflow doesn't fail if you
190-
# push updates to this branch later (re-running the build).
191251
gh release create "$TAG_NAME" \
192252
--title "Release $TAG_NAME" \
193253
--generate-notes \
194254
--target "$GITHUB_REF_NAME" \
195-
|| echo "Release $TAG_NAME already exists, skipping creation."
255+
|| echo "Release $TAG_NAME already exists, skipping creation."

docs/stylesheets/custom.css

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,3 +822,16 @@ p.hero-description {
822822
letter-spacing: -0.5px;
823823
font-family: "Google Sans", sans-serif;
824824
}
825+
826+
/* Prevent the site title and version selector from being hidden on scroll */
827+
[class~="md-header__title"] [class~="md-header__topic"]:first-child {
828+
opacity: 1 !important;
829+
transform: none !important;
830+
z-index: 1 !important;
831+
pointer-events: auto !important;
832+
}
833+
834+
/* Hide the page title that replaces the site title on scroll */
835+
[class~="md-header__title"] [class~="md-header__topic"]:nth-child(2) {
836+
display: none !important;
837+
}

mkdocs.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616

1717
site_name: Universal Commerce Protocol (UCP)
18-
site_url: https://ucp.dev/ # Required for the llmstxt plugin to work.
18+
site_url: !ENV [SITE_URL, "https://ucp.dev/"] # Required for the llmstxt plugin to work.
1919
site_description: >
2020
The Universal Commerce Protocol (UCP) is a solution for enabling gen AI agents
2121
to make payments on behalf of users, safely, securely, and in a decentralized
@@ -30,7 +30,7 @@ nav:
3030
- Overview:
3131
- Home: index.md
3232
- Core Concepts: documentation/core-concepts.md
33-
- Specification: /latest/specification/overview/
33+
- Specification: !ENV [SPEC_URL, "https://ucp.dev/latest/specification/overview/"]
3434
- UCP and AP2: documentation/ucp-and-ap2.md
3535
- Roadmap: documentation/roadmap.md
3636
- Schema Authoring: documentation/schema-authoring.md
@@ -142,8 +142,8 @@ theme:
142142
# - navigation.expand
143143
- navigation.footer
144144
# - navigation.indexes
145-
- navigation.instant
146-
- navigation.instant.progress
145+
# - navigation.instant
146+
# - navigation.instant.progress
147147
# - navigation.path
148148
- navigation.top
149149
- navigation.tracking

0 commit comments

Comments
 (0)