Include documentation generator

libgit2 has a new documentation generator that generates API schema from
our headers, then produces reference documentation that is included into
the website directly.
This commit is contained in:
Edward Thomson
2024-11-25 10:12:29 +00:00
parent c6111ec06c
commit 89cc5ef8e8
8 changed files with 3132 additions and 49 deletions

60
.github/workflows/documentation.yml vendored Normal file
View File

@@ -0,0 +1,60 @@
# Update the www.libgit2.org reference documentation
name: Generate Documentation
on:
push:
branches: [ main, maint/* ]
release:
workflow_dispatch:
permissions:
contents: read
jobs:
documentation:
name: "Generate documentation"
runs-on: "ubuntu-latest"
steps:
- name: Check out source repository
uses: actions/checkout@v4
with:
path: source
fetch-depth: 0
- name: Check out documentation repository
uses: actions/checkout@v4
with:
repository: libgit2/www.libgit2.org
path: www
fetch-depth: 0
ssh-key: ${{ secrets.DOCS_PUBLISH_KEY }}
- name: Prepare branches
run: |
for a in main $(git branch -r --list 'origin/maint/*' | sed -e "s/^ origin\///"); do
git branch --track "$a" "origin/$a"
done
working-directory: source
- name: Generate documentation
run: |
npm install
./generate ../.. ../../../www/docs
working-directory: source/script/api-docs
- name: Examine changes
run: |
if [ -n "$(git diff --name-only)" ]; then
echo "changes=true" >> $GITHUB_OUTPUT
else
echo "changes=false" >> $GITHUB_OUTPUT
fi
id: check
working-directory: www
- name: Publish documentation
run: |
DATE=$(date +"%Y-%m-%d")
git config user.name 'Documentation Site Generator'
git config user.email 'libgit2@users.noreply.github.com'
git add .
git commit -m"Documentation update ${DATE}"
git push origin main
if: steps.check.outputs.changes == 'true'
working-directory: www

View File

@@ -245,52 +245,3 @@ jobs:
uses: test-summary/action@v2
with:
paths: 'test-results-*/*.xml'
# Generate documentation using docurium. We'll upload the documentation
# as a build artifact so that it can be reviewed as part of a pull
# request or in a forked build. For CI builds in the main repository's
# main branch, we'll push the gh-pages branch back up so that it is
# published to our documentation site.
documentation:
name: Generate documentation
if: success() || failure()
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v4
with:
path: source
fetch-depth: 0
- name: Set up container
uses: ./source/.github/actions/download-or-build-container
with:
registry: ${{ env.docker-registry }}
config-path: ${{ env.docker-config-path }}
container: docurium
github_token: ${{ secrets.github_token }}
dockerfile: ${{ matrix.platform.container.dockerfile }}
- name: Generate documentation
working-directory: source
run: |
git config user.name 'Documentation Generation'
git config user.email 'libgit2@users.noreply.github.com'
git branch gh-pages origin/gh-pages
docker login https://${{ env.docker-registry }} -u ${{ github.actor }} -p ${{ github.token }}
docker run \
--rm \
-v "$(pwd):/home/libgit2" \
-w /home/libgit2 \
${{ env.docker-registry }}/${{ github.repository }}/docurium:latest \
cm doc api.docurium
git checkout gh-pages
zip --exclude .git/\* --exclude .gitignore --exclude .gitattributes -r api-documentation.zip .
- uses: actions/upload-artifact@v4
name: Upload artifact
with:
name: api-documentation
path: source/api-documentation.zip
- name: Push documentation branch
working-directory: source
run: git push origin gh-pages
if: github.event_name == 'push' && github.repository == 'libgit2/libgit2'

13
script/api-docs/README.md Normal file
View File

@@ -0,0 +1,13 @@
# API Documentation Generator
These scripts generate the "raw API" specs and reference documentation
for [www.libgit2.org](https://libgit2.org/docs/reference).
The "raw API" specs consists of JSON documents, on per
released version or branch, that describes the APIs. This is
suitable for creating documentation from, or may be useful for
language bindings as well.
The reference documentation is documentation fragments for each
API in each version, ready to be included in the libgit2 documentation
website.

1543
script/api-docs/api-generator.js Executable file

File diff suppressed because it is too large Load Diff

1326
script/api-docs/docs-generator.js Executable file

File diff suppressed because it is too large Load Diff

105
script/api-docs/generate Executable file
View File

@@ -0,0 +1,105 @@
#!/usr/bin/env bash
#
# Usage: generate repo_path output_path
#
# Example: generate https://github.com/libgit2/libgit2 path_to_output
# to clone the repository from GitHub and produce documentation;
# the repo_path can also be a local path
set -eo pipefail
source_path=$(mktemp -d)
verbose=true
force=
if [ "$1" = "" ]; then
echo "usage: $0 repo_path output_path" 1>&2
exit 1
fi
repo_path=$1
output_path=$2
function do_checkout {
if [ "$1" = "" ]; then
echo "usage: $0 source_path" 1>&2
exit 1
fi
if [ "${verbose}" ]; then
echo ":: Checking out source trees..."
echo ""
fi
source_path=$1
mkdir -p "${source_path}"
git clone "${repo_path}" "${source_path}/main" --no-checkout
( cd "${source_path}/main" && git sparse-checkout set --no-cone 'include/*' )
( cd "${source_path}/main" && git read-tree origin/main )
( cd "${source_path}/main" && git checkout -- include )
for tag in $(git --git-dir="${source_path}/main/.git" tag -l); do
git --git-dir="${source_path}/main/.git" worktree add -f "${source_path}/${tag}" "${tag}" --no-checkout
( cd "${source_path}/${tag}" && git sparse-checkout set --no-cone 'include/*' )
( cd "${source_path}/${tag}" && git read-tree HEAD )
if [ "${tag}" == "v0.1.0" ]; then
( cd "${source_path}/${tag}" && git checkout -- src/git )
elif [ "${tag}" == "v0.2.0" -o "${tag}" == "v0.3.0" ]; then
( cd "${source_path}/${tag}" && git checkout -- src/git2 )
else
( cd "${source_path}/${tag}" && git checkout -- include )
fi
done
}
do_checkout ${source_path}
if [ "${verbose}" ]; then
echo ""
echo ":: Generating raw API documentation..."
echo ""
fi
for version in ${source_path}/*; do
version=$(echo "${version}" | sed -e "s/.*\///")
commit=$( cd "${source_path}/${version}" && git rev-parse HEAD )
if [ -f "${output_path}/api/${version}.json" ]; then
existing_commit=$(jq -r .info.commit < "${output_path}/api/${version}.json")
if [ "${existing_commit}" == "${commit}" -a ! "${force}" ]; then
if [ "${verbose}" ]; then
echo "Raw API documentation for ${version} exists; skipping..."
fi
continue
fi
fi
options=""
if [ "${force}" ]; then
options="${options} --force"
fi
echo "Generating raw API documentation for ${version}..."
mkdir -p "${output_path}/api"
node ./api-generator.js $options "${source_path}/${version}" > "${output_path}/api/${version}.json"
done
if [ "${verbose}" ]; then
echo ""
echo ":: Generating HTML documentation..."
echo ""
fi
options=""
if [ "${verbose}" ]; then
options="${options} --verbose"
fi
if [ "${force}" ]; then
options="${options} --force"
fi
node ./docs-generator.js --verbose --jekyll-layout default "${output_path}/api" "${output_path}/reference"

79
script/api-docs/package-lock.json generated Normal file
View File

@@ -0,0 +1,79 @@
{
"name": "_generator",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"dependencies": {
"commander": "^12.1.0",
"markdown-it": "^14.1.0"
}
},
"node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
},
"node_modules/commander": {
"version": "12.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
"integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
"engines": {
"node": ">=18"
}
},
"node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/linkify-it": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz",
"integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==",
"dependencies": {
"uc.micro": "^2.0.0"
}
},
"node_modules/markdown-it": {
"version": "14.1.0",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
"integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
"dependencies": {
"argparse": "^2.0.1",
"entities": "^4.4.0",
"linkify-it": "^5.0.0",
"mdurl": "^2.0.0",
"punycode.js": "^2.3.1",
"uc.micro": "^2.1.0"
},
"bin": {
"markdown-it": "bin/markdown-it.mjs"
}
},
"node_modules/mdurl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
"integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w=="
},
"node_modules/punycode.js": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
"integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
"engines": {
"node": ">=6"
}
},
"node_modules/uc.micro": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
"integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A=="
}
}
}

View File

@@ -0,0 +1,6 @@
{
"dependencies": {
"commander": "^12.1.0",
"markdown-it": "^14.1.0"
}
}