docs: API reference and getting-started guide for developers.pezkuwichain.io (#21)

* docs: generate the API reference for developers.pezkuwichain.io

Add TypeDoc (0.28.20) and `yarn docs`, which builds the reference for the
nine public API packages from src/ into build-docs/, with a landing page
and a getting-started guide whose examples were run against the live
network. The PR workflow builds it so a broken doc comment or config is
caught before merge.

docs/ held only a redirect to polkadot.js.org; it now holds the guide
sources. The README, packages/api/README.md and three CHANGELOG entries
linked to js.pezkuwichain.app, a domain that is not ours and is listed
for sale; they now point to developers.pezkuwichain.io, the Pezkuwi
Portal, or the upstream polkadot.js.org pages the entries came from.

* ci(docs): deploy the reference to developers.pezkuwichain.io

On every master push that changes the generated reference, build it with
`yarn docs` and publish it to the web host the same way pezkuwi-apps
publishes the portal: an approved production environment holds the deploy
key, the bundle is unpacked into releases/<sha>, and going live is one
rename of the current symlink. The switch is checked through nginx for the
public name (deploy sha, index, main.js, search index) and rolled back if
the new release is not served. workflow_dispatch with rollback_to makes an
earlier release live again.

Release-bot version bumps ([CI Skip]) and changes that cannot affect the
output do not ask for an approval.
This commit is contained in:
SatoshiQaziMuhammed authored and GitHub committed 2026-11-12 22:32:28 +04:00
1 parent 9cfa765e61
commit 1914388d2b
15 files changed
+563 -38

No files matched your search

+82
View File
@@ -0,0 +1,82 @@
#!/usr/bin/env bash
# Runs on the web host as the docs-deploy user, fed over ssh by docs-deploy.yml.
#
# release.sh deploy <sha> unpack incoming/<sha>.tgz and make it live
# release.sh rollback <sha> make an already unpacked release live again
#
# nginx serves /var/www/subdomains/developers, a symlink to $BASE/current, which
# in turn points at releases/<sha>. Going live is one rename of that link, so a
# reader never sees a half-copied tree, and the previous release stays on disk
# for an instant rollback. Same layout as the apps deploy in pezkuwi-apps.
set -euo pipefail
BASE=${DOCS_DEPLOY_BASE:-/var/www/docs-deploy}
SITE=developers.pezkuwichain.io
KEEP=5
mode=${1:?mode}
sha=${2:?sha}
[[ $sha =~ ^[0-9a-f]{40}$ ]] || { echo "not a commit sha: $sha"; exit 1; }
rel=$BASE/releases/$sha
switch_to () {
ln -sfn "releases/$1" "$BASE/current.new"
mv -T "$BASE/current.new" "$BASE/current"
}
# The answer has to come through nginx for the public name, not from the
# disk: that is the path a visitor takes.
served_sha () {
curl -sf --max-time 10 --resolve "$SITE:443:127.0.0.1" "https://$SITE/.deploy-sha"
}
check_live () {
local want=$1
[ "$(served_sha)" = "$want" ] || return 1
# The page must render: the index has to name TypeDoc's script, and the
# script and the search index have to be served too.
curl -sf --max-time 10 --resolve "$SITE:443:127.0.0.1" "https://$SITE/" \
| grep -q 'src="assets/main.js"' || return 1
curl -sf --max-time 10 -o /dev/null --resolve "$SITE:443:127.0.0.1" "https://$SITE/assets/main.js" || return 1
curl -sf --max-time 10 -o /dev/null --resolve "$SITE:443:127.0.0.1" "https://$SITE/assets/search.js"
}
prev=$(readlink "$BASE/current" || true)
case $mode in
deploy)
tgz=$BASE/incoming/$sha.tgz
rm -rf "$rel.tmp"
mkdir -p "$rel.tmp"
tar -xzf "$tgz" -C "$rel.tmp"
[ -f "$rel.tmp/index.html" ] || { echo "no index.html in the bundle"; exit 1; }
[ "$(cat "$rel.tmp/.deploy-sha")" = "$sha" ] || { echo ".deploy-sha does not match $sha"; exit 1; }
rm -rf "$rel"
mv "$rel.tmp" "$rel"
rm -f "$tgz"
;;
rollback)
[ -d "$rel" ] || { echo "no unpacked release $sha"; ls "$BASE/releases"; exit 1; }
;;
*)
echo "unknown mode: $mode"; exit 1 ;;
esac
switch_to "$sha"
if ! check_live "$sha"; then
echo "$SITE does not serve $sha after the switch"
if [ -n "$prev" ]; then
switch_to "${prev#releases/}"
echo "restored ${prev#releases/}"
fi
exit 1
fi
echo "live: $sha (was ${prev#releases/})"
# Keep the newest releases, and always the one just replaced.
cd "$BASE/releases"
ls -1t | tail -n +$((KEEP + 1)) | while read -r old; do
[ "$old" = "$sha" ] || [ "releases/$old" = "$prev" ] || rm -rf -- "$old"
done
+92
View File
@@ -0,0 +1,92 @@
name: Docs
on:
push:
branches:
- master
# Only what changes the generated reference. Every run asks for an approval,
# and an approval request that cannot matter teaches people to tap without
# reading.
paths:
- 'packages/**'
- 'docs/**'
- 'typedoc.config.mjs'
- 'yarn.lock'
- '.github/deploy/**'
- '.github/workflows/docs-deploy.yml'
workflow_dispatch:
inputs:
rollback_to:
description: 'Make an earlier release live again (full commit sha); empty = deploy this commit'
required: false
default: ''
# Deploys wait for each other; a newer push queues behind a running one.
concurrency:
group: deploy-docs
cancel-in-progress: false
permissions:
contents: read
jobs:
build:
# The release bot's version-bump commits change no source.
if: github.event.inputs.rollback_to == '' && !startsWith(github.event.head_commit.message, '[CI Skip]')
runs-on: ubuntu-latest
env:
YARN_ENABLE_SCRIPTS: false
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 'lts/*'
- name: docs
run: |
yarn install --immutable
yarn docs
echo "$GITHUB_SHA" > build-docs/.deploy-sha
tar -C build-docs -czf docs-www.tgz .
- uses: actions/upload-artifact@v4
with:
name: docs-www
path: docs-www.tgz
retention-days: 7
# The only job that names the environment, so a run asks for approval once,
# and the deploy secrets (environment-scoped) exist only after it is given.
deploy:
needs: build
if: always() && (needs.build.result == 'success' || (needs.build.result == 'skipped' && github.event.inputs.rollback_to != ''))
runs-on: ubuntu-latest
environment: production
env:
HOST: ${{ secrets.DOCS_DEPLOY_HOST }}
steps:
- uses: actions/checkout@v4
with:
sparse-checkout: .github/deploy
- name: ssh setup
env:
KEY: ${{ secrets.DOCS_DEPLOY_SSH_KEY }}
KNOWN_HOSTS: ${{ secrets.DOCS_DEPLOY_KNOWN_HOSTS }}
run: |
install -m 700 -d ~/.ssh
printf '%s\n' "$KEY" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
printf '%s\n' "$KNOWN_HOSTS" > ~/.ssh/known_hosts
- uses: actions/download-artifact@v4
if: github.event.inputs.rollback_to == ''
with:
name: docs-www
- name: upload
if: github.event.inputs.rollback_to == ''
run: scp -o BatchMode=yes docs-www.tgz "docs-deploy@$HOST:/var/www/docs-deploy/incoming/$GITHUB_SHA.tgz"
- name: go live
env:
ROLLBACK_TO: ${{ github.event.inputs.rollback_to }}
run: |
if [ -n "$ROLLBACK_TO" ]; then set -- rollback "$ROLLBACK_TO"; else set -- deploy "$GITHUB_SHA"; fi
# ssh hands its arguments to the remote shell as one string: only a
# bare sha may get there.
[[ $2 =~ ^[0-9a-f]{40}$ ]] || { echo "not a full commit sha: $2"; exit 1; }
ssh -o BatchMode=yes "docs-deploy@$HOST" bash -s -- "$@" < .github/deploy/release.sh
+1 -1
View File
@@ -11,7 +11,7 @@ jobs:
strategy:
fail-fast: false
matrix:
step: ['lint', 'test', 'build']
step: ['lint', 'test', 'build', 'docs']
runs-on: ubuntu-latest
env:
YARN_ENABLE_SCRIPTS: false