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
4 changes: 2 additions & 2 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ If you want to submit a pull request to fix an issue or add a feature, here's a

## Contributing to Documentation

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

### Documentation Structure

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

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

Expand Down
38 changes: 38 additions & 0 deletions .github/workflows/docs-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Deploy Docs to Internet Computer

on:
push:
branches: [docs-deployment]
workflow_dispatch:

concurrency:
group: ic-docs-deploy
cancel-in-progress: true

jobs:
deploy:
runs-on: ubuntu-latest
environment: IC mainnet
permissions:
contents: read
steps:
- name: Checkout docs-deployment branch
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
ref: docs-deployment

- name: Install icp-cli
run: npm i -g @icp-sdk/icp-cli @icp-sdk/ic-wasm

- name: Import deploy identity
run: |
mkdir -p ~/.local/share/icp-cli/identity/keys
echo "$ICP_IDENTITY" | base64 -d > ~/.local/share/icp-cli/identity/keys/deployer.pem
sed -i 's/\\r\\n/\r\n/g' ~/.local/share/icp-cli/identity/keys/deployer.pem
icp identity import deployer --from-pem ~/.local/share/icp-cli/identity/keys/deployer.pem --storage plaintext
icp identity default deployer
env:
ICP_IDENTITY: ${{ secrets.DFX_IDENTITY_DESIGN_TEAM }}

- name: Deploy to IC mainnet
run: icp deploy -e ic docs
60 changes: 23 additions & 37 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,11 @@ on:
- '.github/workflows/docs.yml'
workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: write

env:
# Site configuration - customize these for forks
# Production (dfinity/icp-cli):
PUBLIC_SITE: https://dfinity.github.io
PUBLIC_BASE_PREFIX: /icp-cli
# Forks should update these values:
# PUBLIC_SITE: https://your-username.github.io
# PUBLIC_BASE_PREFIX: /your-repo-name
PUBLIC_SITE: https://cli.internetcomputer.org

# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
Expand All @@ -42,20 +35,6 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Validate required environment variables
run: |
if [[ -z "${{ env.PUBLIC_SITE }}" ]]; then
echo "❌ Error: PUBLIC_SITE environment variable is not set"
exit 1
fi
if [[ -z "${{ env.PUBLIC_BASE_PREFIX }}" ]]; then
echo "❌ Error: PUBLIC_BASE_PREFIX environment variable is not set"
exit 1
fi
echo "✅ Required environment variables are set:"
echo " PUBLIC_SITE=${{ env.PUBLIC_SITE }}"
echo " PUBLIC_BASE_PREFIX=${{ env.PUBLIC_BASE_PREFIX }}"

- name: Checkout
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0

Expand All @@ -76,9 +55,8 @@ jobs:
env:
NODE_ENV: production
PUBLIC_SITE: ${{ env.PUBLIC_SITE }}
PUBLIC_BASE_PREFIX: ${{ env.PUBLIC_BASE_PREFIX }}

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

- name: Prepare root files
run: |
mkdir -p root
mkdir -p root/.well-known

# Copy versions.json from repo
cp docs-site/versions.json root/versions.json

# Copy IC asset canister config files
cp docs-site/icp.yaml root/icp.yaml
cp docs-site/.ic-assets.json5 root/.ic-assets.json5
mkdir -p root/.icp/data/mappings
cp docs-site/.icp/data/mappings/ic.ids.json root/.icp/data/mappings/ic.ids.json

# Copy custom domain file
cp docs-site/public/.well-known/ic-domains root/.well-known/ic-domains

# Extract the latest version from versions.json
LATEST_VERSION=$(jq -r ".versions[] | select(.latest == true) | .version" docs-site/versions.json)

Expand All @@ -121,11 +108,12 @@ jobs:
</html>
EOF

- name: Deploy root files to GitHub Pages
- name: Deploy root files to docs-deployment branch
uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./root
publish_branch: docs-deployment
keep_files: true

# Publish main branch docs for preview (always available at /main/)
Expand All @@ -151,19 +139,19 @@ jobs:
- name: Build main branch docs
working-directory: ./docs-site
run: |
BASE_PREFIX="${PUBLIC_BASE_PREFIX:-/icp-cli}"
echo "Building with base: ${BASE_PREFIX}/main/"
echo "Building with base: /main/"
npm run build
env:
NODE_ENV: production
PUBLIC_BASE_PATH: ${{ env.PUBLIC_BASE_PREFIX }}/main/
PUBLIC_BASE_PATH: /main/
PUBLIC_SITE: ${{ env.PUBLIC_SITE }}

- name: Deploy main docs to GitHub Pages
- name: Deploy main docs to docs-deployment branch
uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs-site/dist
publish_branch: docs-deployment
destination_dir: main
keep_files: true

Expand All @@ -189,28 +177,25 @@ jobs:

- name: Extract version from tag or branch
run: |
# Use repo-specific base prefix from env vars (defaults to /icp-cli)
BASE_PREFIX="${PUBLIC_BASE_PREFIX:-/icp-cli}"

if [[ "${GITHUB_REF}" == refs/tags/v* ]]; then
# Tag: v0.1.0 -> extract major.minor -> 0.1
VERSION=${GITHUB_REF#refs/tags/v}
# Strip patch version (0.1.0 -> 0.1)
VERSION=${VERSION%.*}
echo "DOCS_VERSION=${VERSION}" >> $GITHUB_ENV
echo "DOCS_BASE_PATH=${BASE_PREFIX}/${VERSION}/" >> $GITHUB_ENV
echo "DOCS_BASE_PATH=/${VERSION}/" >> $GITHUB_ENV
elif [[ "${GITHUB_REF}" == refs/heads/docs/v* ]]; then
# Branch: docs/v0.1 -> extract version -> 0.1
VERSION=${GITHUB_REF#refs/heads/docs/v}
echo "DOCS_VERSION=${VERSION}" >> $GITHUB_ENV
echo "DOCS_BASE_PATH=${BASE_PREFIX}/${VERSION}/" >> $GITHUB_ENV
echo "DOCS_BASE_PATH=/${VERSION}/" >> $GITHUB_ENV
else
echo "❌ Docs should only be published for version tags (v*) or docs branches (docs/v*)"
echo "Current ref: ${GITHUB_REF}"
exit 1
fi

echo "Building docs for version ${VERSION} with base: ${BASE_PREFIX}/${VERSION}/"
echo "Building docs for version ${VERSION} with base: /${VERSION}/"

- name: Build documentation site
working-directory: ./docs-site
Expand All @@ -220,9 +205,10 @@ jobs:
PUBLIC_BASE_PATH: ${{ env.DOCS_BASE_PATH }}
PUBLIC_SITE: ${{ env.PUBLIC_SITE }}

- name: Deploy versioned docs to GitHub Pages
- name: Deploy versioned docs to docs-deployment branch
uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs-site/dist
publish_branch: docs-deployment
destination_dir: ${{ env.DOCS_VERSION }}
30 changes: 30 additions & 0 deletions docs-site/.ic-assets.json5
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[
{
// Static assets built by Astro — content-hashed filenames, cache forever
"match": "**/_astro/**",
"headers": {
"Cache-Control": "public, max-age=31536000, immutable"
}
},
{
// Search index
"match": "**/pagefind/**",
"headers": {
"Cache-Control": "public, max-age=31536000, immutable"
}
},
{
// HTML pages — short cache so updates are visible quickly
"match": "**/*.html",
"headers": {
"Cache-Control": "public, max-age=300"
}
},
{
// Version list — very short cache so version switcher sees updates quickly
"match": "versions.json",
"headers": {
"Cache-Control": "public, max-age=60"
}
}
]
30 changes: 19 additions & 11 deletions docs-site/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,23 +96,31 @@ Removes `dist/` and `.astro/` directories

## Deployment

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

The workflow:
1. Installs dependencies
2. Runs `npm run build`
3. Uploads the `dist/` directory as a GitHub Pages artifact
4. Deploys to GitHub Pages
**Canister ID**: `ak73b-maaaa-aaaad-qlbgq-cai`

### How it works

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.)
2. **`.github/workflows/docs-deploy.yml`** triggers on pushes to `docs-deployment` and deploys the entire branch to the IC asset canister

### Triggers

- **Push to `main`**: Rebuilds `/main/` docs and root files (`index.html`, `versions.json`, IC config)
- **Tags (`v*`)**: Builds versioned docs (e.g., `v0.2.0` → `/0.2/`)
- **Branches (`docs/v*`)**: Updates versioned docs (e.g., `docs/v0.1` → `/0.1/`)

### Legacy redirect

The old GitHub Pages site at `https://dfinity.github.io/icp-cli/` redirects all paths to `https://cli.internetcomputer.org/`.

## Configuration

### Site Settings
In `astro.config.mjs`:
- `site`: Base URL for the site
- `base`: Base path (currently `/` for root domain)
- `site`: Base URL (`https://cli.internetcomputer.org` in production)
- `base`: Version path (set via `PUBLIC_BASE_PATH`, e.g., `/0.2/`, `/main/`)
- `title`, `description`: Site metadata
- `logo`: ICP logo configuration
- `favicon`: Site favicon
Expand Down
7 changes: 3 additions & 4 deletions docs-site/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ import rehypeRewriteLinks from './plugins/rehype-rewrite-links.mjs';
// https://astro.build/config
export default defineConfig({
site: process.env.PUBLIC_SITE,
// For versioned deployments: /icp-cli/0.1/, /icp-cli/0.2/, etc.
// For non-versioned: /icp-cli/ in production, / in development
// Defaults are set in the workflow, not here
base: process.env.PUBLIC_BASE_PATH || (process.env.NODE_ENV === 'production' ? process.env.PUBLIC_BASE_PREFIX + '/' : '/'),
// For versioned deployments: /0.1/, /0.2/, etc.
// PUBLIC_BASE_PATH is set per-version in CI (e.g., /0.2/, /main/)
base: process.env.PUBLIC_BASE_PATH || '/',
markdown: {
rehypePlugins: [
// Rewrite relative .md links for Astro's directory-based output
Expand Down
9 changes: 9 additions & 0 deletions docs-site/icp.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# yaml-language-server: $schema=https://github.com/dfinity/icp-cli/raw/refs/heads/main/docs/schemas/icp-yaml-schema.json

canisters:
- name: docs
recipe:
type: "@dfinity/asset-canister@v2.1.0"
configuration:
version: 0.29.2
dir: .
1 change: 1 addition & 0 deletions docs-site/public/.well-known/ic-domains
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
cli.internetcomputer.org
14 changes: 5 additions & 9 deletions docs-site/src/components/VersionSwitcher.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,11 @@
const isDev = import.meta.env.DEV;
const isMainBranch = import.meta.env.BASE_URL?.includes('/main/');

// Extract base prefix and version from BASE_URL
// Examples: "/icp-cli/0.1/" -> prefix="/icp-cli", version="0.1"
// "/your-repo/0.2/" -> prefix="/your-repo", version="0.2"
const baseUrl = import.meta.env.BASE_URL || '/';
const basePrefixMatch = baseUrl.match(/^(\/[^\/]+)/);
const basePrefix = basePrefixMatch ? basePrefixMatch[1] : '';

// Extract version from BASE_URL (e.g., "/icp-cli/0.1/" -> "0.1")
const versionMatch = baseUrl.match(/\/(\d+\.\d+)\//);
// No base prefix — versions live at the domain root (/0.1/, /0.2/, /main/)
const basePrefix = '';

// Extract version from BASE_URL (e.g., "/0.1/" -> "0.1")
const versionMatch = (import.meta.env.BASE_URL || '/').match(/\/(\d+\.\d+)\//);
const currentVersion = versionMatch ? versionMatch[1] : 'unknown';
---

Expand Down
Loading
Loading