This is an automated email from the ASF dual-hosted git repository.
xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-website.git
The following commit(s) were added to refs/heads/master by this push:
new b3ba9359c6 ci: split website build and documentation build into
separate jobs
b3ba9359c6 is described below
commit b3ba9359c605c5e92ad2feac6444e03d16143fd3
Author: Swatantra Yadav <[email protected]>
AuthorDate: Fri Oct 9 17:29:56 2026 +0530
ci: split website build and documentation build into separate jobs
Decouple the monolithic CI workflow into two independent, parallel jobs to
resolve #180:
- build-website: builds the Jekyll static site using Ruby/Bundler and
deploys website updates to asf-site while strictly preserving existing
content/docs/. Runs on PRs and website commits in ~1-2 minutes.
- build-docs: builds Sphinx documentation using Python/Pipenv and the
incremental release doc restoration engine, deploying content/docs/
independently to asf-site.
- concurrency: add workflow concurrency group 'asf-site-publish' to
guarantee sequential, collision-free pushes to asf-site.
- publish.sh: add modular --website, --docs, and --all modes with safety
directory guards and cp -a preservation.
Prevents Sphinx documentation build errors from blocking website release
announcements and updates.
Fixes #180
Signed-off-by: Swatantra Yadav <[email protected]>
---
.github/workflows/main.yml | 71 ++++++++++++++-----
publish.sh | 171 ++++++++++++++++++++++++++++++++++++++-------
2 files changed, 197 insertions(+), 45 deletions(-)
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index ea3271d801..7bcb32becc 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -23,8 +23,49 @@ name: CI
permissions:
contents: write
+concurrency:
+ group: asf-site-publish
+ cancel-in-progress: false
+
jobs:
- build:
+ build-website:
+ name: Build Website
+ runs-on: ubuntu-latest
+ if: github.event_name != 'schedule' && (github.event_name !=
'repository_dispatch' || github.event.action != 'docs')
+ steps:
+ - name: Checkout Site
+ uses: actions/checkout@v7
+ with:
+ fetch-depth: 0
+
+ - name: Install Ruby tools
+ run: sudo apt-get install -y rubygems ruby-dev zlib1g-dev
+
+ - name: Build Site
+ run: |
+ export GEM_HOME=$HOME/.gem
+ export PATH=$PATH:$GEM_HOME/bin
+ username="$(git log -1 --pretty=format:'%an')"
+ email="$(git log -1 --pretty=format:'%ae')"
+ git config --global user.name "$username"
+ git config --global user.email "$email"
+ ./publish.sh --website
+
+ - name: Upload artifact of staged website
+ uses: actions/upload-artifact@v7
+ with:
+ name: website-site
+ path: content
+ include-hidden-files: true
+
+ - name: Publish Website
+ if: github.event_name == 'push' && github.ref == 'refs/heads/master'
+ run: |
+ git pull --rebase origin asf-site
+ git push origin asf-site:asf-site
+
+ build-docs:
+ name: Build Documentation
runs-on: ubuntu-latest
steps:
- name: Checkout Site
@@ -157,26 +198,20 @@ jobs:
cd ../..
echo " ========== DOCUMENTATION BUILD FINISHED ==========="
- - name: Install Ruby tools
- run: sudo apt-get install -y rubygems ruby-dev zlib1g-dev
+ - name: Upload artifact of staged documentation
+ uses: actions/upload-artifact@v7
+ with:
+ name: docs-site
+ path: docs
+ include-hidden-files: true
- - name: Build Site
+ - name: Publish Documentation
+ if: (github.event_name == 'push' || github.event_name ==
'repository_dispatch' || github.event_name == 'workflow_dispatch' ||
github.event_name == 'schedule') && github.ref == 'refs/heads/master'
run: |
- export GEM_HOME=$HOME/.gem
- export PATH=$PATH:$GEM_HOME/bin
username="$(git log -1 --pretty=format:'%an')"
email="$(git log -1 --pretty=format:'%ae')"
git config --global user.name "$username"
git config --global user.email "$email"
- ./publish.sh
-
- - name: Upload artifact of staged site
- uses: actions/upload-artifact@v7
- with:
- name: static-site
- path: content
- include-hidden-files: true
-
- - name: Publish Site
- if: (github.event_name == 'push' || github.event_name ==
'repository_dispatch' || github.event_name == 'workflow_dispatch' ||
github.event_name == 'schedule') && github.ref == 'refs/heads/master'
- run: git push origin asf-site:asf-site
+ ./publish.sh --docs
+ git pull --rebase origin asf-site
+ git push origin asf-site:asf-site
diff --git a/publish.sh b/publish.sh
index 815c902512..6ab6257171 100755
--- a/publish.sh
+++ b/publish.sh
@@ -18,35 +18,152 @@
set -e
-echo "Prior to running this make sure that the NuttX repo is checked out"
-echo "to nuttx and the documentation html has been generated."
-
-gem install bundler:2.1.2
-bundle config set path 'vendor/bundle'
-bundle install
-bundle exec jekyll clean --source .
-bundle exec jekyll build --source .
-
-# Gemfile.lock is sometimes updated, ignore that in CI.
-git checkout -- Gemfile.lock
-rm -rf target/docs
-mv docs target/
-
-COMMIT_HASH_WEB=`git rev-parse HEAD`
-COMMIT_HASH_NUTTX=`git -C nuttx rev-parse HEAD`
-git checkout asf-site
-#git pull --rebase
-rm -rf content
-mv target content
-git add content
-git status
-echo "Publishing website master branch $COMMIT_HASH_WEB"
-echo "Publishing docs from NuttX master branch $COMMIT_HASH_WEB"
-if git diff --staged --quiet; then
- echo "No changes to commit or publish."
+MODE="${1:---all}"
+
+echo "==================================================================="
+echo " Running publish.sh in mode: $MODE"
+echo "==================================================================="
+
+COMMIT_HASH_WEB=$(git rev-parse HEAD)
+if [ -d "nuttx" ]; then
+ COMMIT_HASH_NUTTX=$(git -C nuttx rev-parse HEAD 2>/dev/null || echo "HEAD")
else
- git commit -a -m "Publishing web: $COMMIT_HASH_WEB docs: $COMMIT_HASH_NUTTX"
+ COMMIT_HASH_NUTTX="n/a"
fi
+
+build_website() {
+ echo " ===> Building Jekyll website into target/..."
+ gem install bundler:2.1.2
+ bundle config set path 'vendor/bundle'
+ bundle install
+ bundle exec jekyll clean --source .
+ bundle exec jekyll build --source .
+ # Gemfile.lock is sometimes updated, ignore that in CI.
+ git checkout -- Gemfile.lock
+}
+
+stage_website_only() {
+ echo " ===> Staging website updates to asf-site (preserving content/docs)..."
+ if [ ! -d "target" ]; then
+ echo "::error::Directory 'target' does not exist. Build the website first."
+ exit 1
+ fi
+
+ git checkout asf-site
+ git pull --rebase origin asf-site 2>/dev/null || true
+
+ mkdir -p content
+ TEMP_DOCS_BACKUP=""
+ if [ -d "content/docs" ]; then
+ TEMP_DOCS_BACKUP=$(mktemp -d)
+ echo " ====> Backing up existing content/docs to $TEMP_DOCS_BACKUP/docs..."
+ mv content/docs "$TEMP_DOCS_BACKUP/docs"
+ fi
+
+ rm -rf content
+ mv target content
+
+ if [ -n "$TEMP_DOCS_BACKUP" ] && [ -d "$TEMP_DOCS_BACKUP/docs" ]; then
+ echo " ====> Restoring preserved content/docs..."
+ mv "$TEMP_DOCS_BACKUP/docs" content/docs
+ rm -rf "$TEMP_DOCS_BACKUP"
+ fi
+
+ git add content
+ git status
+ echo "Publishing website master branch $COMMIT_HASH_WEB"
+ if git diff --staged --quiet; then
+ echo "No changes to commit or publish for website."
+ else
+ git commit -a -m "Publishing web: $COMMIT_HASH_WEB"
+ fi
+}
+
+stage_docs_only() {
+ echo " ===> Staging documentation updates to asf-site (preserving
website)..."
+ if [ ! -d "docs" ]; then
+ echo "::error::Directory 'docs' does not exist. Documentation must be
generated first."
+ exit 1
+ fi
+
+ # Temporarily store docs outside git tree so git checkout asf-site does not
wipe untracked docs
+ TEMP_STAGE_DOCS=$(mktemp -d)
+ mv docs "$TEMP_STAGE_DOCS/docs"
+
+ git checkout asf-site
+ git pull --rebase origin asf-site 2>/dev/null || true
+
+ mkdir -p content/docs
+ cp -a "$TEMP_STAGE_DOCS/docs/." content/docs/
+ rm -rf "$TEMP_STAGE_DOCS"
+
+ git add content/docs
+ git status
+ echo "Publishing docs from NuttX master branch $COMMIT_HASH_NUTTX"
+ if git diff --staged --quiet; then
+ echo "No changes to commit or publish for docs."
+ else
+ git commit -a -m "Publishing docs: $COMMIT_HASH_NUTTX (web:
$COMMIT_HASH_WEB)"
+ fi
+}
+
+stage_all() {
+ echo " ===> Staging website and documentation..."
+ if [ ! -d "target" ]; then
+ echo "::error::Directory 'target' does not exist. Build the website first."
+ exit 1
+ fi
+
+ if [ -d "docs" ]; then
+ rm -rf target/docs
+ mv docs target/
+ fi
+
+ git checkout asf-site
+ git pull --rebase origin asf-site 2>/dev/null || true
+
+ # If docs was not present in target, preserve existing content/docs
+ if [ ! -d "target/docs" ] && [ -d "content/docs" ]; then
+ TEMP_DOCS_BACKUP=$(mktemp -d)
+ mv content/docs "$TEMP_DOCS_BACKUP/docs"
+ rm -rf content
+ mv target content
+ mv "$TEMP_DOCS_BACKUP/docs" content/docs
+ rm -rf "$TEMP_DOCS_BACKUP"
+ else
+ rm -rf content
+ mv target content
+ fi
+
+ git add content
+ git status
+ echo "Publishing website master branch $COMMIT_HASH_WEB"
+ echo "Publishing docs from NuttX master branch $COMMIT_HASH_NUTTX"
+ if git diff --staged --quiet; then
+ echo "No changes to commit or publish."
+ else
+ git commit -a -m "Publishing web: $COMMIT_HASH_WEB docs:
$COMMIT_HASH_NUTTX"
+ fi
+}
+
+case "$MODE" in
+ --website|-w)
+ build_website
+ stage_website_only
+ ;;
+ --docs|-d)
+ stage_docs_only
+ ;;
+ --all|-a)
+ build_website
+ stage_all
+ ;;
+ *)
+ echo "Unknown option $MODE. Usage: $0 [--website | --docs | --all]"
+ exit 1
+ ;;
+esac
+
echo " "
echo "==================================================================="
echo "You are now on the asf-site branch with your new changes committed."