Skip to content

Docs

Docs #546

Workflow file for this run

name: Docs
on:
push:
branches:
- main
pull_request:
branches:
- main
schedule:
- cron: "0 2 * * *"
jobs:
build:
name: Build website artifacts
runs-on: ubuntu-latest
steps:
- name: Checkout uutils.github.io Repository
uses: actions/checkout@v6
with:
repository: uutils/uutils.github.io
path: './uutils.github.io'
fetch-depth: 0
- name: Checkout Coreutils Repository
uses: actions/checkout@v6
with:
repository: uutils/coreutils
path: './coreutils'
fetch-depth: 0
- name: Checkout Coreutils L10n Repository
uses: actions/checkout@v6
with:
repository: uutils/coreutils-l10n
path: './coreutils-l10n'
fetch-depth: 0
- name: Checkout Findutils Repository
uses: actions/checkout@v6
with:
repository: uutils/findutils
path: './findutils'
fetch-depth: 0
- name: Checkout Grep Repository
uses: actions/checkout@v6
with:
repository: uutils/grep
path: './grep'
fetch-depth: 0
- name: Install `rust` toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-wasip1
- name: Install system deps
run: |
sudo apt update
sudo apt install libacl1-dev libselinux1-dev libsystemd-dev
pip install babel
- name: Install necessary tools (mdbook and mdbook-toc)
uses: taiki-e/install-action@v2
with:
tool: mdbook@0.5.0,mdbook-toc@0.15.3
- name: Copy l10n locales into coreutils
run: |
# Only copy locales into utilities that already exist in coreutils
# Exclude en-US.ftl to preserve the coreutils English originals
for util_dir in coreutils-l10n/src/uu/*/; do
util=$(basename "$util_dir")
if [ -d "coreutils/src/uu/$util/locales" ]; then
for ftl in "$util_dir"/locales/*.ftl; do
[ -f "$ftl" ] || continue
[ "$(basename "$ftl")" = "en-US.ftl" ] && continue
cp "$ftl" "coreutils/src/uu/$util/locales/"
done
fi
done
# Copy uucore l10n files, excluding en-US.ftl
if [ -d "coreutils-l10n/src/uucore/locales" ]; then
for ftl in coreutils-l10n/src/uucore/locales/*.ftl; do
[ -f "$ftl" ] || continue
[ "$(basename "$ftl")" = "en-US.ftl" ] && continue
cp "$ftl" "coreutils/src/uucore/locales/"
done
fi
- name: Patch mdbook theme with language selector
run: |
uutils.github.io/scripts/patch-mdbook-theme.sh coreutils/docs coreutils-l10n
- name: Build Coreutils Docs
run: |
cd coreutils
# Download and repack tldr zip: uudoc expects pages/common/ prefix
curl -sfL https://github.com/tldr-pages/tldr/releases/download/v2.3/tldr-pages.zip -o /tmp/tldr-raw.zip || true
if [ -f /tmp/tldr-raw.zip ]; then
mkdir -p /tmp/tldr-repack/pages
cd /tmp/tldr-repack && unzip -o /tmp/tldr-raw.zip -d pages/ > /dev/null
zip -r "$OLDPWD/docs/tldr.zip" pages/ > /dev/null
cd "$OLDPWD"
fi
cargo run --bin uudoc --all-features
cd docs
# Remove deprecated 'multilingual' field unsupported by newer mdbook
sed -i '/^multilingual/d' book.toml
# Strip the legacy FA4 `fa` class from uudoc-generated platform icons
# so mdbook 0.5's Font Awesome parser picks up the `fa-brands` family
# instead of defaulting to `regular` and warning about linux/windows/apple.
find src/utils -name '*.md' -exec sed -i 's|class="fa fa-brands |class="fa-brands |g' {} +
mdbook build
- name: Build Coreutils Docs (translations)
run: |
uutils.github.io/scripts/build-docs-l10n.sh coreutils
- name: Build Findutils Docs
run: |
cd findutils/docs
# Remove deprecated 'multilingual' field unsupported by newer mdbook
sed -i '/^multilingual/d' book.toml
mdbook build
- name: Build uutils WASM binary
run: |
cd coreutils
# Build the multicall binary for WASI target
# Use --no-default-features to avoid platform-specific dependencies
cargo build --release --target wasm32-wasip1 -p coreutils --no-default-features --features feat_wasm
if [ -f target/wasm32-wasip1/release/coreutils.wasm ]; then
mkdir -p ../uutils.github.io/static/wasm
cp target/wasm32-wasip1/release/coreutils.wasm ../uutils.github.io/static/wasm/uutils.wasm
# Optimize WASM size if wasm-opt is available
if command -v wasm-opt &> /dev/null; then
wasm-opt -Oz ../uutils.github.io/static/wasm/uutils.wasm -o ../uutils.github.io/static/wasm/uutils.wasm
fi
echo "WASM binary size: $(du -h ../uutils.github.io/static/wasm/uutils.wasm | cut -f1)"
# Generate the list of available locales from .ftl files
locales=$(find src/uu/*/locales src/uucore/locales -name '*.ftl' 2>/dev/null \
| sed 's|.*/||; s|\.ftl$||' | sort -u | paste -sd, -)
echo "const WASM_LOCALES = [$(echo "$locales" | sed 's/[^,]*/\"&\"/g')];" \
> ../uutils.github.io/static/wasm/locales.js
echo "Available locales: $locales"
# Generate the list of available commands from the feat_wasm feature
# in Cargo.toml so the playground stays in sync with the WASM build.
# HIDDEN_CMDS: utilities that ship in the binary but we don't want to
# advertise in the playground (e.g. `yes` produces infinite output
# that just spams the terminal).
HIDDEN_CMDS='^(false|true|yes)$'
commands=$(sed -n '/^feat_wasm = \[/,/^\]/p' Cargo.toml \
| grep -oE '"[a-zA-Z0-9_]+"' | tr -d '"' \
| sort -u | grep -vE "$HIDDEN_CMDS" | paste -sd, -)
echo "const WASM_COMMANDS = [$(echo "$commands" | sed 's/[^,]*/\"&\"/g')];" \
> ../uutils.github.io/static/wasm/commands.js
echo "Available commands: $commands"
# Record the coreutils commit used to build the WASM binary
commit_hash=$(git rev-parse HEAD)
commit_short=$(git rev-parse --short HEAD)
commit_date=$(git show -s --format=%cI HEAD)
# Record the uutils.github.io commit the site was built from
site_hash=$(git -C ../uutils.github.io rev-parse HEAD)
site_short=$(git -C ../uutils.github.io rev-parse --short HEAD)
site_date=$(git -C ../uutils.github.io show -s --format=%cI HEAD)
{
echo "const UUTILS_WASM_VERSION = {"
echo " commit: \"${commit_hash}\","
echo " short: \"${commit_short}\","
echo " date: \"${commit_date}\""
echo "};"
echo "const SITE_VERSION = {"
echo " commit: \"${site_hash}\","
echo " short: \"${site_short}\","
echo " date: \"${site_date}\""
echo "};"
} > ../uutils.github.io/static/wasm/version.js
echo "uutils WASM build: ${commit_short} (${commit_date})"
echo "site build: ${site_short} (${site_date})"
fi
- name: Build grep WASM binary
run: |
# uutils grep is a standalone binary (not part of the coreutils
# multicall) and depends on the Oniguruma C library (onig_sys), so the
# WASM build needs a WASI sysroot to compile the bundled C sources.
WASI_SDK_VERSION=25
WASI_SDK_DIR="wasi-sdk-${WASI_SDK_VERSION}.0-x86_64-linux"
curl -sL "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_VERSION}/${WASI_SDK_DIR}.tar.gz" | tar xz
export WASI_SDK_PATH="$PWD/${WASI_SDK_DIR}"
export CC_wasm32_wasip1="$WASI_SDK_PATH/bin/clang"
export CFLAGS_wasm32_wasip1="--sysroot=$WASI_SDK_PATH/share/wasi-sysroot"
cd grep
cargo build --release --target wasm32-wasip1 --bin grep
if [ -f target/wasm32-wasip1/release/grep.wasm ]; then
mkdir -p ../uutils.github.io/static/wasm
cp target/wasm32-wasip1/release/grep.wasm ../uutils.github.io/static/wasm/grep.wasm
# Optimize WASM size if wasm-opt is available
if command -v wasm-opt &> /dev/null; then
wasm-opt -Oz ../uutils.github.io/static/wasm/grep.wasm -o ../uutils.github.io/static/wasm/grep.wasm
fi
echo "grep WASM binary size: $(du -h ../uutils.github.io/static/wasm/grep.wasm | cut -f1)"
# Advertise grep in the playground's command list. grep ships as its
# own WASM module, so it isn't picked up by the coreutils feat_wasm
# scan above; append it to the generated list here.
commands_js=../uutils.github.io/static/wasm/commands.js
if [ -f "$commands_js" ]; then
existing=$(sed -n 's/^const WASM_COMMANDS = \[\(.*\)\];$/\1/p' "$commands_js")
echo "const WASM_COMMANDS = [${existing}, \"grep\"];" > "$commands_js"
else
echo 'const WASM_COMMANDS = ["grep"];' > "$commands_js"
fi
# Record the grep commit used to build its WASM module so the
# playground can show it alongside the coreutils build.
grep_hash=$(git rev-parse HEAD)
grep_short=$(git rev-parse --short HEAD)
grep_date=$(git show -s --format=%cI HEAD)
{
echo "const UUTILS_GREP_VERSION = {"
echo " commit: \"${grep_hash}\","
echo " short: \"${grep_short}\","
echo " date: \"${grep_date}\""
echo "};"
} >> ../uutils.github.io/static/wasm/version.js
echo "grep WASM build: ${grep_short} (${grep_date})"
fi
- name: Build find WASM binary
run: |
# uutils findutils ships `find` as a standalone binary (not part of the
# coreutils multicall) and, like grep, depends on the Oniguruma C
# library (onig_sys), so the WASM build needs a WASI sysroot to compile
# the bundled C sources. Reuse the WASI SDK fetched by the grep step if
# it's still around, otherwise download it.
WASI_SDK_VERSION=25
WASI_SDK_DIR="wasi-sdk-${WASI_SDK_VERSION}.0-x86_64-linux"
if [ ! -d "$WASI_SDK_DIR" ]; then
curl -sL "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_VERSION}/${WASI_SDK_DIR}.tar.gz" | tar xz
fi
export WASI_SDK_PATH="$PWD/${WASI_SDK_DIR}"
export CC_wasm32_wasip1="$WASI_SDK_PATH/bin/clang"
export CFLAGS_wasm32_wasip1="--sysroot=$WASI_SDK_PATH/share/wasi-sysroot"
cd findutils
# Only `find` is shipped: xargs/locate/updatedb need process spawning or
# an on-disk database, neither of which works in the browser WASI sandbox.
cargo build --release --target wasm32-wasip1 --bin find
if [ -f target/wasm32-wasip1/release/find.wasm ]; then
mkdir -p ../uutils.github.io/static/wasm
cp target/wasm32-wasip1/release/find.wasm ../uutils.github.io/static/wasm/find.wasm
# Optimize WASM size if wasm-opt is available
if command -v wasm-opt &> /dev/null; then
wasm-opt -Oz ../uutils.github.io/static/wasm/find.wasm -o ../uutils.github.io/static/wasm/find.wasm
fi
echo "find WASM binary size: $(du -h ../uutils.github.io/static/wasm/find.wasm | cut -f1)"
# Advertise find in the playground's command list. find ships as its
# own WASM module, so it isn't picked up by the coreutils feat_wasm
# scan above; append it to the generated list here.
commands_js=../uutils.github.io/static/wasm/commands.js
if [ -f "$commands_js" ]; then
existing=$(sed -n 's/^const WASM_COMMANDS = \[\(.*\)\];$/\1/p' "$commands_js")
echo "const WASM_COMMANDS = [${existing}, \"find\"];" > "$commands_js"
else
echo 'const WASM_COMMANDS = ["find"];' > "$commands_js"
fi
# Record the findutils commit used to build its WASM module so the
# playground can show it alongside the coreutils build.
find_hash=$(git rev-parse HEAD)
find_short=$(git rev-parse --short HEAD)
find_date=$(git show -s --format=%cI HEAD)
{
echo "const UUTILS_FINDUTILS_VERSION = {"
echo " commit: \"${find_hash}\","
echo " short: \"${find_short}\","
echo " date: \"${find_date}\""
echo "};"
} >> ../uutils.github.io/static/wasm/version.js
echo "find WASM build: ${find_short} (${find_date})"
fi
- name: Run Zola
uses: shalzz/zola-deploy-action@v0.22.1
env:
BUILD_DIR: uutils.github.io
BUILD_ONLY: true
- name: Collect results into `public` folder
run: |
cp -r uutils.github.io/public public
cp -r coreutils/docs/book public/coreutils/docs
cp -r findutils/docs/book public/findutils/docs
# Copy translated docs to /coreutils/docs-{lang}/
for lang_dir in coreutils/docs/book-*/; do
[ -d "$lang_dir" ] || continue
lang=$(basename "$lang_dir" | sed 's/^book-//')
cp -r "$lang_dir" "public/coreutils/docs-${lang}"
done
- name: Run playground JS tests
run: |
npm install puppeteer@24
node uutils.github.io/scripts/run-tests.js --dir public --port 8080
- name: Remove test files from deploy output
run: rm -f public/js/wasm-terminal.test.html
- name: Upload artifact for checking the output
uses: actions/upload-artifact@v7
with:
path: ./public
- name: Upload artifact for pages
uses: actions/upload-pages-artifact@v5
with:
path: ./public
# dev-docs:
# name: generate the dev doc
# runs-on: ubuntu-latest
# steps:
# - name: Checkout repository
# uses: actions/checkout@v4
# with:
# repository: uutils/coreutils
# path: './coreutils'
# fetch-depth: 0
# - name: Install `rust` toolchain
# uses: actions-rs/toolchain@v1
# with:
# toolchain: stable
# default: true
# profile: minimal
# - name: Build dev documentation
# run: |
# cd coreutils
# cargo doc --no-deps --all-features --workspace
# - name: Deploy Docs
# uses: peaceiris/actions-gh-pages@v3
# with:
# github_token: ${{ secrets.GITHUB_TOKEN }}
# publish_dir: ./coreutils/target/doc
# destination_dir: coreutils/dev/
# build-report:
# name: generate the build report
# runs-on: ubuntu-latest
# steps:
# - name: Checkout repository
# uses: actions/checkout@v4
# with:
# repository: uutils/coreutils
# path: './coreutils'
# fetch-depth: 0
# - name: Install `rust` toolchain
# uses: actions-rs/toolchain@v1
# with:
# toolchain: nightly
# default: true
# profile: minimal
# - name: Build report
# run: |
# cd coreutils
# cargo +nightly build --timings=html -Zunstable-options
# - name: Deploy build report
# uses: peaceiris/actions-gh-pages@v3
# with:
# github_token: ${{ secrets.GITHUB_TOKEN }}
# publish_dir: ./coreutils/target/cargo-timings/
# destination_dir: cargo-timings/
# Deployment job
deploy:
permissions:
contents: read
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
if: (github.event_name == 'push' && github.ref == 'refs/heads/main') || github.event_name == 'schedule'
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v5