Skip to content

Commit 764ce2a

Browse files
authored
docs: migrate hosting from GitHub Pages to IC asset canister (#439)
* docs: migrate hosting from GitHub Pages to IC asset canister - Remove /icp-cli/ base prefix from astro config and version switcher - Add IC asset canister config (icp.yaml, .ic-assets.json5, .well-known/ic-domains) - Add docs-deploy.yml workflow to deploy docs-deployment branch to IC mainnet - Update docs.yml to push built assets to docs-deployment instead of gh-pages - Update VERSIONED_DOCS.md, CONTRIBUTING.md, and README with new deployment info The docs-deployment branch has been bootstrapped from gh-pages (path rewrites applied) and is already deployed to ak73b-maaaa-aaaad-qlbgq-cai. * docs: update custom domain to cli.internetcomputer.org
1 parent bfbe837 commit 764ce2a

File tree

11 files changed

+194
-139
lines changed

11 files changed

+194
-139
lines changed

.github/CONTRIBUTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ If you want to submit a pull request to fix an issue or add a feature, here's a
8080

8181
## Contributing to Documentation
8282

83-
The documentation lives in the `docs/` directory and is deployed to https://dfinity.github.io/icp-cli/.
83+
The documentation lives in the `docs/` directory and is deployed to https://cli.internetcomputer.org.
8484

8585
### Documentation Structure
8686

@@ -97,7 +97,7 @@ The documentation site uses [Astro](https://astro.build/) with [Starlight](https
9797
1. **Source files** (`docs/`) are Markdown with minimal YAML frontmatter (title + description)
9898
2. **Starlight** reads directly from `docs/` via the glob content loader
9999
3. **Rehype plugin** (`docs-site/plugins/rehype-rewrite-links.mjs`) rewrites `.md` links at build time for Starlight's clean URLs
100-
4. **GitHub Actions** automatically deploys to GitHub Pages on push to main
100+
4. **GitHub Actions** automatically builds and deploys to an IC asset canister on push to main
101101

102102
This architecture keeps source docs GitHub-friendly (`.md` links work on GitHub) while producing clean URLs on the documentation site.
103103

.github/workflows/docs-deploy.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: Deploy Docs to Internet Computer
2+
3+
on:
4+
push:
5+
branches: [docs-deployment]
6+
workflow_dispatch:
7+
8+
concurrency:
9+
group: ic-docs-deploy
10+
cancel-in-progress: true
11+
12+
jobs:
13+
deploy:
14+
runs-on: ubuntu-latest
15+
environment: IC mainnet
16+
permissions:
17+
contents: read
18+
steps:
19+
- name: Checkout docs-deployment branch
20+
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
21+
with:
22+
ref: docs-deployment
23+
24+
- name: Install icp-cli
25+
run: npm i -g @icp-sdk/icp-cli @icp-sdk/ic-wasm
26+
27+
- name: Import deploy identity
28+
run: |
29+
mkdir -p ~/.local/share/icp-cli/identity/keys
30+
echo "$ICP_IDENTITY" | base64 -d > ~/.local/share/icp-cli/identity/keys/deployer.pem
31+
sed -i 's/\\r\\n/\r\n/g' ~/.local/share/icp-cli/identity/keys/deployer.pem
32+
icp identity import deployer --from-pem ~/.local/share/icp-cli/identity/keys/deployer.pem --storage plaintext
33+
icp identity default deployer
34+
env:
35+
ICP_IDENTITY: ${{ secrets.DFX_IDENTITY_DESIGN_TEAM }}
36+
37+
- name: Deploy to IC mainnet
38+
run: icp deploy -e ic docs

.github/workflows/docs.yml

Lines changed: 23 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,11 @@ on:
1818
- '.github/workflows/docs.yml'
1919
workflow_dispatch:
2020

21-
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
2221
permissions:
2322
contents: write
2423

2524
env:
26-
# Site configuration - customize these for forks
27-
# Production (dfinity/icp-cli):
28-
PUBLIC_SITE: https://dfinity.github.io
29-
PUBLIC_BASE_PREFIX: /icp-cli
30-
# Forks should update these values:
31-
# PUBLIC_SITE: https://your-username.github.io
32-
# PUBLIC_BASE_PREFIX: /your-repo-name
25+
PUBLIC_SITE: https://cli.internetcomputer.org
3326

3427
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
3528
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
@@ -42,20 +35,6 @@ jobs:
4235
build:
4336
runs-on: ubuntu-latest
4437
steps:
45-
- name: Validate required environment variables
46-
run: |
47-
if [[ -z "${{ env.PUBLIC_SITE }}" ]]; then
48-
echo "❌ Error: PUBLIC_SITE environment variable is not set"
49-
exit 1
50-
fi
51-
if [[ -z "${{ env.PUBLIC_BASE_PREFIX }}" ]]; then
52-
echo "❌ Error: PUBLIC_BASE_PREFIX environment variable is not set"
53-
exit 1
54-
fi
55-
echo "✅ Required environment variables are set:"
56-
echo " PUBLIC_SITE=${{ env.PUBLIC_SITE }}"
57-
echo " PUBLIC_BASE_PREFIX=${{ env.PUBLIC_BASE_PREFIX }}"
58-
5938
- name: Checkout
6039
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
6140

@@ -76,9 +55,8 @@ jobs:
7655
env:
7756
NODE_ENV: production
7857
PUBLIC_SITE: ${{ env.PUBLIC_SITE }}
79-
PUBLIC_BASE_PREFIX: ${{ env.PUBLIC_BASE_PREFIX }}
8058

81-
# Publish root index and versions list - only runs on main branch
59+
# Publish root index, versions list, and IC config files - only runs on main branch
8260
publish-root-files:
8361
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
8462
needs: build
@@ -94,11 +72,20 @@ jobs:
9472

9573
- name: Prepare root files
9674
run: |
97-
mkdir -p root
75+
mkdir -p root/.well-known
9876
9977
# Copy versions.json from repo
10078
cp docs-site/versions.json root/versions.json
10179
80+
# Copy IC asset canister config files
81+
cp docs-site/icp.yaml root/icp.yaml
82+
cp docs-site/.ic-assets.json5 root/.ic-assets.json5
83+
mkdir -p root/.icp/data/mappings
84+
cp docs-site/.icp/data/mappings/ic.ids.json root/.icp/data/mappings/ic.ids.json
85+
86+
# Copy custom domain file
87+
cp docs-site/public/.well-known/ic-domains root/.well-known/ic-domains
88+
10289
# Extract the latest version from versions.json
10390
LATEST_VERSION=$(jq -r ".versions[] | select(.latest == true) | .version" docs-site/versions.json)
10491
@@ -121,11 +108,12 @@ jobs:
121108
</html>
122109
EOF
123110
124-
- name: Deploy root files to GitHub Pages
111+
- name: Deploy root files to docs-deployment branch
125112
uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0
126113
with:
127114
github_token: ${{ secrets.GITHUB_TOKEN }}
128115
publish_dir: ./root
116+
publish_branch: docs-deployment
129117
keep_files: true
130118

131119
# Publish main branch docs for preview (always available at /main/)
@@ -151,19 +139,19 @@ jobs:
151139
- name: Build main branch docs
152140
working-directory: ./docs-site
153141
run: |
154-
BASE_PREFIX="${PUBLIC_BASE_PREFIX:-/icp-cli}"
155-
echo "Building with base: ${BASE_PREFIX}/main/"
142+
echo "Building with base: /main/"
156143
npm run build
157144
env:
158145
NODE_ENV: production
159-
PUBLIC_BASE_PATH: ${{ env.PUBLIC_BASE_PREFIX }}/main/
146+
PUBLIC_BASE_PATH: /main/
160147
PUBLIC_SITE: ${{ env.PUBLIC_SITE }}
161148

162-
- name: Deploy main docs to GitHub Pages
149+
- name: Deploy main docs to docs-deployment branch
163150
uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0
164151
with:
165152
github_token: ${{ secrets.GITHUB_TOKEN }}
166153
publish_dir: ./docs-site/dist
154+
publish_branch: docs-deployment
167155
destination_dir: main
168156
keep_files: true
169157

@@ -189,28 +177,25 @@ jobs:
189177

190178
- name: Extract version from tag or branch
191179
run: |
192-
# Use repo-specific base prefix from env vars (defaults to /icp-cli)
193-
BASE_PREFIX="${PUBLIC_BASE_PREFIX:-/icp-cli}"
194-
195180
if [[ "${GITHUB_REF}" == refs/tags/v* ]]; then
196181
# Tag: v0.1.0 -> extract major.minor -> 0.1
197182
VERSION=${GITHUB_REF#refs/tags/v}
198183
# Strip patch version (0.1.0 -> 0.1)
199184
VERSION=${VERSION%.*}
200185
echo "DOCS_VERSION=${VERSION}" >> $GITHUB_ENV
201-
echo "DOCS_BASE_PATH=${BASE_PREFIX}/${VERSION}/" >> $GITHUB_ENV
186+
echo "DOCS_BASE_PATH=/${VERSION}/" >> $GITHUB_ENV
202187
elif [[ "${GITHUB_REF}" == refs/heads/docs/v* ]]; then
203188
# Branch: docs/v0.1 -> extract version -> 0.1
204189
VERSION=${GITHUB_REF#refs/heads/docs/v}
205190
echo "DOCS_VERSION=${VERSION}" >> $GITHUB_ENV
206-
echo "DOCS_BASE_PATH=${BASE_PREFIX}/${VERSION}/" >> $GITHUB_ENV
191+
echo "DOCS_BASE_PATH=/${VERSION}/" >> $GITHUB_ENV
207192
else
208193
echo "❌ Docs should only be published for version tags (v*) or docs branches (docs/v*)"
209194
echo "Current ref: ${GITHUB_REF}"
210195
exit 1
211196
fi
212197
213-
echo "Building docs for version ${VERSION} with base: ${BASE_PREFIX}/${VERSION}/"
198+
echo "Building docs for version ${VERSION} with base: /${VERSION}/"
214199
215200
- name: Build documentation site
216201
working-directory: ./docs-site
@@ -220,9 +205,10 @@ jobs:
220205
PUBLIC_BASE_PATH: ${{ env.DOCS_BASE_PATH }}
221206
PUBLIC_SITE: ${{ env.PUBLIC_SITE }}
222207

223-
- name: Deploy versioned docs to GitHub Pages
208+
- name: Deploy versioned docs to docs-deployment branch
224209
uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0
225210
with:
226211
github_token: ${{ secrets.GITHUB_TOKEN }}
227212
publish_dir: ./docs-site/dist
213+
publish_branch: docs-deployment
228214
destination_dir: ${{ env.DOCS_VERSION }}

docs-site/.ic-assets.json5

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
[
2+
{
3+
// Static assets built by Astro — content-hashed filenames, cache forever
4+
"match": "**/_astro/**",
5+
"headers": {
6+
"Cache-Control": "public, max-age=31536000, immutable"
7+
}
8+
},
9+
{
10+
// Search index
11+
"match": "**/pagefind/**",
12+
"headers": {
13+
"Cache-Control": "public, max-age=31536000, immutable"
14+
}
15+
},
16+
{
17+
// HTML pages — short cache so updates are visible quickly
18+
"match": "**/*.html",
19+
"headers": {
20+
"Cache-Control": "public, max-age=300"
21+
}
22+
},
23+
{
24+
// Version list — very short cache so version switcher sees updates quickly
25+
"match": "versions.json",
26+
"headers": {
27+
"Cache-Control": "public, max-age=60"
28+
}
29+
}
30+
]

docs-site/README.md

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -96,23 +96,31 @@ Removes `dist/` and `.astro/` directories
9696

9797
## Deployment
9898

99-
The site is automatically deployed to GitHub Pages:
100-
- **URL**: https://dfinity.github.io/icp-cli/
101-
- **Workflow**: `.github/workflows/docs.yml`
102-
- **Trigger**: Push to `main` branch (docs or docs-site changes)
99+
The site is hosted on an IC asset canister and served at `https://cli.internetcomputer.org`.
103100

104-
The workflow:
105-
1. Installs dependencies
106-
2. Runs `npm run build`
107-
3. Uploads the `dist/` directory as a GitHub Pages artifact
108-
4. Deploys to GitHub Pages
101+
**Canister ID**: `ak73b-maaaa-aaaad-qlbgq-cai`
102+
103+
### How it works
104+
105+
1. **`.github/workflows/docs.yml`** builds documentation and pushes built files to the `docs-deployment` branch (one directory per version: `0.1/`, `0.2/`, `main/`, etc.)
106+
2. **`.github/workflows/docs-deploy.yml`** triggers on pushes to `docs-deployment` and deploys the entire branch to the IC asset canister
107+
108+
### Triggers
109+
110+
- **Push to `main`**: Rebuilds `/main/` docs and root files (`index.html`, `versions.json`, IC config)
111+
- **Tags (`v*`)**: Builds versioned docs (e.g., `v0.2.0``/0.2/`)
112+
- **Branches (`docs/v*`)**: Updates versioned docs (e.g., `docs/v0.1``/0.1/`)
113+
114+
### Legacy redirect
115+
116+
The old GitHub Pages site at `https://dfinity.github.io/icp-cli/` redirects all paths to `https://cli.internetcomputer.org/`.
109117

110118
## Configuration
111119

112120
### Site Settings
113121
In `astro.config.mjs`:
114-
- `site`: Base URL for the site
115-
- `base`: Base path (currently `/` for root domain)
122+
- `site`: Base URL (`https://cli.internetcomputer.org` in production)
123+
- `base`: Version path (set via `PUBLIC_BASE_PATH`, e.g., `/0.2/`, `/main/`)
116124
- `title`, `description`: Site metadata
117125
- `logo`: ICP logo configuration
118126
- `favicon`: Site favicon

docs-site/astro.config.mjs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@ import rehypeRewriteLinks from './plugins/rehype-rewrite-links.mjs';
66
// https://astro.build/config
77
export default defineConfig({
88
site: process.env.PUBLIC_SITE,
9-
// For versioned deployments: /icp-cli/0.1/, /icp-cli/0.2/, etc.
10-
// For non-versioned: /icp-cli/ in production, / in development
11-
// Defaults are set in the workflow, not here
12-
base: process.env.PUBLIC_BASE_PATH || (process.env.NODE_ENV === 'production' ? process.env.PUBLIC_BASE_PREFIX + '/' : '/'),
9+
// For versioned deployments: /0.1/, /0.2/, etc.
10+
// PUBLIC_BASE_PATH is set per-version in CI (e.g., /0.2/, /main/)
11+
base: process.env.PUBLIC_BASE_PATH || '/',
1312
markdown: {
1413
rehypePlugins: [
1514
// Rewrite relative .md links for Astro's directory-based output

docs-site/icp.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# yaml-language-server: $schema=https://github.com/dfinity/icp-cli/raw/refs/heads/main/docs/schemas/icp-yaml-schema.json
2+
3+
canisters:
4+
- name: docs
5+
recipe:
6+
type: "@dfinity/asset-canister@v2.1.0"
7+
configuration:
8+
version: 0.29.2
9+
dir: .
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
cli.internetcomputer.org

docs-site/src/components/VersionSwitcher.astro

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,11 @@
33
const isDev = import.meta.env.DEV;
44
const isMainBranch = import.meta.env.BASE_URL?.includes('/main/');
55
6-
// Extract base prefix and version from BASE_URL
7-
// Examples: "/icp-cli/0.1/" -> prefix="/icp-cli", version="0.1"
8-
// "/your-repo/0.2/" -> prefix="/your-repo", version="0.2"
9-
const baseUrl = import.meta.env.BASE_URL || '/';
10-
const basePrefixMatch = baseUrl.match(/^(\/[^\/]+)/);
11-
const basePrefix = basePrefixMatch ? basePrefixMatch[1] : '';
12-
13-
// Extract version from BASE_URL (e.g., "/icp-cli/0.1/" -> "0.1")
14-
const versionMatch = baseUrl.match(/\/(\d+\.\d+)\//);
6+
// No base prefix — versions live at the domain root (/0.1/, /0.2/, /main/)
7+
const basePrefix = '';
8+
9+
// Extract version from BASE_URL (e.g., "/0.1/" -> "0.1")
10+
const versionMatch = (import.meta.env.BASE_URL || '/').match(/\/(\d+\.\d+)\//);
1511
const currentVersion = versionMatch ? versionMatch[1] : 'unknown';
1612
---
1713

0 commit comments

Comments
 (0)