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
53 changes: 43 additions & 10 deletions .github/workflows/gh-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,55 @@ name: GH-Pages
on:
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
versions:
runs-on: ubuntu-latest
outputs:
targets: ${{ steps.list.outputs.targets }}
latest: ${{ steps.list.outputs.latest }}
steps:
- uses: actions/checkout@v7
- id: list
run: ./publish.sh list >> "$GITHUB_OUTPUT"

concurrency:
group: ${{ github.ref }}
cancel-in-progress: true

build:
needs: versions
runs-on: ubuntu-latest
strategy:
# One broken version should not prevent the others from being published.
fail-fast: false
matrix:
version: ${{ fromJson(needs.versions.outputs.targets) }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
- uses: subosito/flutter-action@v2
- uses: bluefireteam/melos-action@v3
with:
melos-version: 7.0.0-dev.7
melos-version: 8.2.2
run-bootstrap: false
- uses: actions/setup-node@v3
- uses: actions/setup-node@v7
with:
node-version: 22
- run: ./publish.sh build "${{ matrix.version }}" "${{ needs.versions.outputs.latest }}"
- uses: actions/upload-artifact@v7
with:
name: docs-${{ matrix.version }}
path: out/
retention-days: 1

publish:
needs: [versions, build]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v7
- uses: actions/download-artifact@v8
with:
node-version: 16
- run: ./publish.sh
path: artifacts
pattern: docs-*
- run: ./publish.sh assemble '${{ needs.versions.outputs.targets }}'
143 changes: 115 additions & 28 deletions publish.sh
Original file line number Diff line number Diff line change
@@ -1,48 +1,97 @@
#!/bin/bash -e
#
# Builds the versioned Flame documentation.
#
# Usage:
# ./publish.sh Build every version sequentially, then
# assemble docs/ and push (local/full run).
# ./publish.sh list Print `latest` and `targets` (a JSON array
# of everything to build, in site order).
# ./publish.sh build <ver> <latest> Build a single version into out/.
# ./publish.sh assemble <targets> Combine out/ (or artifacts/) into docs/
# and push.
#
# The CI workflow uses `list` to fan out one `build` job per version, then a
# single `assemble` job to publish. Splitting it this way keeps one copy of the
# build logic rather than duplicating it between the script and the workflow.

tmp_flame_src='_flame'
tmp_stash='_stash'
flame_repo='https://github.com/flame-engine/flame.git'
out_dir='out'

function main {
case "${1:-}" in
list) cmd_list ;;
build) cmd_build "$2" "$3" ;;
assemble) cmd_assemble "$2" ;;
'') cmd_all ;;
*) echo "Unknown command: $1" >&2; exit 1 ;;
esac
}

function section {
echo
echo -e "\033[1;32m#-----------------------------------------------------------\033[m"
echo -e "\033[1;32m# $1\033[m"
echo -e "\033[1;32m#-----------------------------------------------------------\033[m"
}

# Obtain the list of documentation versions to build. The list is created from
# git tags, skipping the versions that started with 0, and removing all the old
# versions that don't support Melos 7 and pub workspaces.
function version_list {
git -C $tmp_flame_src for-each-ref --sort=creatordate \
--format '%(refname:short)' 'refs/tags/v*' | sed -n '29,$p' | sort -rV
}

# Prints `latest` and `targets` as `key=value` lines, ready to be appended to
# $GITHUB_OUTPUT. `targets` is main followed by the versions in descending
# order, which is also the order they are listed in on the site.
function cmd_list {
rm -rf $tmp_flame_src
# Only the refs are needed here, so skip blobs and the working copy.
git clone --filter=blob:none --no-checkout --quiet $flame_repo $tmp_flame_src
local list latest targets
list=$(version_list)
latest=$(head -n 1 <<< "$list")
targets=$(printf 'main\n%s\n' "$list" | jq -R . | jq -s -c .)
rm -rf $tmp_flame_src
echo "latest=$latest"
echo "targets=$targets"
}

function cmd_build {
prepare_flame_repo
prepare_docs
generate_docs_for_version "$1" "$2"
}

# Obtain the list of documentation versions to build. The list is
# created from git tags, skipping the versions that started with 0.
function cmd_all {
local list latest targets
prepare_flame_repo
section "List of versions to build:"
cd $tmp_flame_src
# Removes all the old versions that doesn't support Melos 7 and pub workspaces.
list=$(git for-each-ref --sort=creatordate --format '%(refname:short)' 'refs/tags/v*' | sed -n '29,$p' | sort -rV)
cd -
list=$(version_list)
echo "$list"
latest_version=$(head -n 1 <<< "$list")
sed -i "s/FLAME_VERSION/latest/g" docs/index.html
sed -i "s/FLAME_VERSION/latest/g" docs/404.html
latest=$(head -n 1 <<< "$list")
targets=$(printf 'main\n%s\n' "$list" | jq -R . | jq -s -c .)

generate_docs_for_version main "$latest_version"
generate_docs_for_version main "$latest"
while IFS= read -r line; do
generate_docs_for_version "$line" "$latest_version"
generate_docs_for_version "$line" "$latest"
done <<< "$list"

git_push
cmd_assemble "$targets"

rm -rf $tmp_flame_src
rm -rf $tmp_stash
section "Done."
}

function section {
echo
echo -e "\033[1;32m#-----------------------------------------------------------\033[m"
echo -e "\033[1;32m# $1\033[m"
echo -e "\033[1;32m#-----------------------------------------------------------\033[m"
}

function prepare_flame_repo {
section 'Downloading Flame repository'
rm -rf $tmp_flame_src
rm -rf $tmp_stash
git clone https://github.com/flame-engine/flame.git $tmp_flame_src
git clone $flame_repo $tmp_flame_src
mkdir $tmp_stash
cp -r $tmp_flame_src/doc/_sphinx $tmp_stash
cp -r $tmp_flame_src/scripts $tmp_stash
Expand All @@ -56,6 +105,9 @@ function prepare_docs {
cp -r template docs/
}

# Builds one version into out/<version>. The latest version is additionally
# copied to out/latest, before the noindex marker is added, so that only the
# versioned copy is hidden from search engines.
function generate_docs_for_version {
version=$1
latest_version=$2
Expand All @@ -64,6 +116,14 @@ function generate_docs_for_version {

cd $tmp_flame_src
git checkout -f "$version"
# `git checkout -f` leaves ignored files alone, so build output generated for
# a previously built version survives into this one. That breaks the Flutter
# apps: `.dart_tool/` holds a generated web plugin registrant, and a
# registrant left behind by a version using rive ^0.14 imports
# `package:rive_native`, which versions using rive ^0.13 do not depend on.
# The app then fails to compile with "Couldn't resolve the package
# 'rive_native'". Every version has to start from a pristine checkout.
git clean -xfd
cd -
rm -rf $tmp_flame_src/doc/_sphinx
cp -r $tmp_stash/_sphinx $tmp_flame_src/doc/
Expand All @@ -90,15 +150,17 @@ function generate_docs_for_version {
make html
cd -

mkdir -p $out_dir
if [[ "$version" == "$latest_version" ]]; then
cp -r $tmp_flame_src/doc/_build/html "docs/latest"
rm -rf "$out_dir/latest"
cp -r $tmp_flame_src/doc/_build/html "$out_dir/latest"
fi

cp -r $tmp_flame_src/doc/_build/html "docs/$version"
no_index_string="<meta name=\"robots\" content=\"noindex\">"
find "docs/$version" -type f -name "*.html" -exec sed -i "/<head>/a $no_index_string" {} +

echo "$version" >> docs/versions.txt
rm -rf "${out_dir:?}/$version"
cp -r $tmp_flame_src/doc/_build/html "$out_dir/$version"
no_index_string="<meta name=\"robots\" content=\"noindex\">"
find "$out_dir/$version" -type f -name "*.html" \
-exec sed -i "/<head>/a $no_index_string" {} +
}

function pre_process {
Expand All @@ -115,6 +177,31 @@ function pre_process {
fi
}

# Combines the per-version builds into docs/ and publishes them. Version
# directories are read from artifacts/*/ (one directory per CI artifact) when
# present, and from out/ otherwise.
function cmd_assemble {
local targets="$1"
section "Assembling docs"
prepare_docs
sed -i "s/FLAME_VERSION/latest/g" docs/index.html
sed -i "s/FLAME_VERSION/latest/g" docs/404.html

if compgen -G 'artifacts/*/' > /dev/null; then
cp -r artifacts/*/. docs/
else
cp -r $out_dir/. docs/
fi

# versions.txt drives the version picker, so the order has to be stable:
# main first, then newest to oldest.
jq -r '.[]' <<< "$targets" > docs/versions.txt
echo "Published versions:"
cat docs/versions.txt

git_push
}

function git_push {
section "Publishing to Git"
git config user.email "contact@blue-fire.xyz"
Expand All @@ -128,4 +215,4 @@ function git_push {
fi
}

main
main "$@"