Skip to content

ci: Add GitHub Actions workflow for Cloudflare Pages deployment#141

Merged
Arctis-Fireblight merged 12 commits intoRedot-Engine:masterfrom
MichaelFisher1997:optimize-build-simplify
Feb 2, 2026
Merged

ci: Add GitHub Actions workflow for Cloudflare Pages deployment#141
Arctis-Fireblight merged 12 commits intoRedot-Engine:masterfrom
MichaelFisher1997:optimize-build-simplify

Conversation

@MichaelFisher1997
Copy link

@MichaelFisher1997 MichaelFisher1997 commented Feb 2, 2026

Summary

This PR adds a GitHub Actions workflow to build and deploy the documentation to Cloudflare Pages, solving the 20-minute build timeout issue.

Changes

  • New workflow (.github/workflows/build-and-deploy.yml): Builds on GitHub Actions (2-hour timeout) and deploys to Cloudflare Pages
  • Optimized build (build.sh): Uses -j 4 for parallel builds and adds caching support
  • Configuration (wrangler.toml): Infrastructure-as-code for Cloudflare Pages
  • Updated README: Documents the new build architecture

Benefits

  • No more 20-minute Cloudflare Pages timeout (builds take ~25 min on GitHub Actions)
  • Automatic deployment on every push to master or preview branches
  • Caching reduces subsequent builds to ~10-15 minutes
  • Works with preview deployments for PRs

Setup Required (Cloudflare Secrets)

Add these to repo Settings → Secrets → Actions:

Or provide existing secrets from current setup.

Testing

This has been tested on a fork and successfully deploys to: https://013ee7b0.redot-docs-7g4.pages.dev


Draft PR - ready for review and testing.

Summary by CodeRabbit

Release Notes

  • Documentation

    • Updated documentation with comprehensive build instructions, architecture overview, and deployment workflow guidance.
  • Chores

    • Established automated documentation building and deployment to Cloudflare Pages.
    • Refactored build script with streamlined workflow and enhanced status messaging.

✏️ Tip: You can customize this high-level summary in your review settings.

- Rewrite build.sh to remove SSH/git complexity (no more redot-docs-live repo)
- Use --exclude-classes for faster migration (skips class reference conversion)
- Use -j auto for parallel builds (uses all CPU cores)
- Output directly to /output for Cloudflare Pages (simplified architecture)
- Keep FULL_RUN conditional logic and branch handling
- Update README.md with new build instructions and architecture explanation

This simplifies the deployment from 2 repos to 1 repo + 1 Cloudflare Pages project.
- Verified build works locally (5.5min, 1509 HTML files, 2GB output)
- Build generates output/html/en/<branch>/ structure
- Build command: FULL_RUN=1 bash build.sh
- Output directory: output/
- Revert to -j 4 (matching original build speed ~36min)
- -j auto was detecting too many cores causing overhead on Cloudflare
- Add migration caching (skip if _migrated already exists)
- Should restore ~36min build time vs current ~50min
- Add .github/workflows/build-and-deploy.yml
  - Builds on GitHub Actions (2-hour timeout vs Cloudflare's 20-min limit)
  - Deploys to Cloudflare Pages using official action
  - Runs on push to master and optimize-build-simplify branches
  - Uses pip cache for faster dependency installation

- Update README.md with new GitHub Actions architecture documentation
- Add output/ to .gitignore (build artifacts should not be committed)

This solves the Cloudflare Pages 20-minute build timeout issue by
building on GitHub Actions first, then deploying the built output.
- Add caching for migrated files (skip migration if source unchanged)
- Add caching for Sphinx doctrees (60-80% faster incremental builds)
- Switch from cloudflare/pages-action to cloudflare/wrangler-action
- Update build.sh to use doctree cache directory

Expected improvement:
- First build: ~30 min (unchanged)
- Subsequent builds: ~10-15 min (with cache hits)
- Configuration-as-code for Cloudflare Pages deployment
- Build command: FULL_RUN=1 bash build.sh
- Output directory: output/
- master branch deploys output/html/en/latest/
- other branches deploy output/html/en/<branch>/
- This ensures index.html is at the root of the deployment
@coderabbitai
Copy link

coderabbitai bot commented Feb 2, 2026

📝 Walkthrough

Walkthrough

Introduces automated documentation building and deployment infrastructure with a GitHub Actions workflow, Cloudflare Wrangler configuration, and a rewritten build script. Changes enable deterministic builds triggered on push to master and optimize-build-simplify branches, with output deployed to Cloudflare Pages based on branch name.

Changes

Cohort / File(s) Summary
CI/CD Pipeline Configuration
.github/workflows/build-and-deploy.yml, wrangler.toml
Added GitHub Actions workflow with build job (Python 3.11 setup, dependencies, documentation build via shell script, artifact upload) and deploy job (artifact download, Cloudflare Pages deployment via Wrangler). Added Wrangler configuration defining site deployment settings, build command, and environment-specific names.
Build Script Rewrite
build.sh
Rewrote to streamlined, deterministic flow with set -e and environment-variable-driven behavior. Removed legacy Git operations (SSH, cloning, pushing), added CF_PAGES branch detection, introduced FULL_RUN flag for conditional builds, implemented branch-to-output-dir mapping (master → latest), organized build steps with [1/4]–[4/4] labels, and consolidated directory/doctree handling.
Project Configuration
.gitignore
Added output/ pattern to ignore build output directory.
Documentation Updates
README.md
Restructured and expanded with new "Building Documentation" section replacing prior migration focus, added "Quick Build (Local Development)" and "Manual Build" subsections with optimized commands, introduced "Architecture" section describing GitHub Actions + Cloudflare Pages workflow, added GitHub Actions Workflow details including triggers and required secrets, updated deployment flow explanation, and reworked Anaconda/miniconda setup guidance.

Sequence Diagram(s)

sequenceDiagram
    actor Dev as Developer
    participant GitHub as GitHub Repository
    participant GHActions as GitHub Actions<br/>(Build Job)
    participant Artifacts as Artifact Storage
    participant Deploy as GitHub Actions<br/>(Deploy Job)
    participant Cloudflare as Cloudflare Pages

    Dev->>GitHub: Push to master/<br/>optimize-build-simplify
    GitHub->>GHActions: Trigger workflow
    GHActions->>GHActions: Setup Python 3.11
    GHActions->>GHActions: Install dependencies
    GHActions->>GHActions: Build docs (FULL_RUN=1)
    GHActions->>Artifacts: Upload artifact<br/>(redot-docs-build)
    GHActions-->>Deploy: Workflow complete
    Deploy->>Artifacts: Download artifact
    Deploy->>Deploy: Determine DEPLOY_DIR<br/>(branch-based)
    Deploy->>Cloudflare: Deploy via Wrangler<br/>(output/html/en/...)
    Cloudflare-->>Dev: Docs published
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A workflow so swift, in Actions we trust,
From branch to the cloud, deployment's a must!
Build scripts now streamlined, no legacy chains,
Cloudflare deploys, documentation remains! 📚✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the primary change: introducing a GitHub Actions workflow for Cloudflare Pages deployment, which is the core focus of the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@MichaelFisher1997
Copy link
Author

ignore the 1st build, i didnt think it triggered on a draft

@Arctis-Fireblight
Copy link

Let me know when it is ready for review and merge

@MichaelFisher1997 MichaelFisher1997 marked this pull request as ready for review February 2, 2026 03:04
@Arctis-Fireblight Arctis-Fireblight merged commit 6ba1726 into Redot-Engine:master Feb 2, 2026
2 of 3 checks passed
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In `@build.sh`:
- Around line 22-27: The branch detection can return "HEAD" in detached-HEAD CI
runs; update the gitBranch assignment logic so after computing gitBranch with
git rev-parse you check if gitBranch == "HEAD" and then fall back to the GitHub
Actions environment variables: use GITHUB_HEAD_REF if set (PR branch), else use
GITHUB_REF_NAME, else default to "master"; keep the existing
CF_PAGES/CF_PAGES_BRANCH override logic intact (references: gitBranch, CF_PAGES,
CF_PAGES_BRANCH, GITHUB_HEAD_REF, GITHUB_REF_NAME).

In `@README.md`:
- Around line 77-80: Update the fenced code block under the "How it works:"
section to include a language identifier (e.g., add "text" after the opening
triple backticks) so the block becomes ```text ... ```, which satisfies
markdownlint MD040; locate the fenced block with the content "Push to branch →
GitHub Actions builds (30 min) → Deploys to Cloudflare Pages" and add the
language token to the opening fence.
- Around line 33-36: The README's Quick Build bullet incorrectly states "-j
auto"; update that bullet to match build.sh which now uses "-j 4" (change the
bullet text from "`-j auto`: Uses all available CPU cores for parallel builds"
to "`-j 4`: Uses 4 parallel jobs as configured in build.sh"), and ensure any
mention of parallel build flags references build.sh (e.g., build.sh's invocation
or variable) so the documentation and the build script stay in sync.

In `@wrangler.toml`:
- Around line 4-11: The wrangler.toml currently uses Workers Sites sections
[build] and [site]; remove the [build] block (the command invoking FULL_RUN=1
bash build.sh) and replace the [site] configuration with the Pages-specific key
pages_build_output_dir set to "output" so Wrangler v3 Pages recognizes the build
output; update or remove any references to build.sh invocation in wrangler.toml
since your CI/GitHub Actions handles the build.
🧹 Nitpick comments (1)
README.md (1)

116-116: Prefer a heading over bold text for section titles.
Markdownlint (MD036) flags emphasis used as a heading.

✏️ Suggested fix
-**Recommended: Use the build script**
+#### Recommended: Use the build script

Comment on lines +22 to 27
# Determine output directory based on branch
gitBranch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "master")
if [ -n "$CF_PAGES" ]; then
echo "Building on Cloudflare Pages"
gitBranch="${CF_PAGES_BRANCH:-master}"
fi
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

GitHub Actions git rev-parse --abbrev-ref HEAD detached HEAD GITHUB_REF_NAME GITHUB_HEAD_REF

💡 Result:

In GitHub Actions it’s common for:

git rev-parse --abbrev-ref HEAD

to print HEAD because the repository is checked out in detached HEAD mode (there is no local branch checked out).

Why you get detached HEAD

  • On pull_request workflows, actions/checkout typically checks out the PR’s merge commit ref (not your source branch), and Git ends up detached unless you explicitly check out a branch. The actions/checkout README calls out that PR triggers are detached by default and you must pass ref if you want the PR branch checked out. [1]

What the GitHub-provided variables mean

  • GITHUB_REF_NAME / github.ref_name: short ref name of what triggered the workflow. For PRs it is <pr_number>/merge, not a branch name. [2]
  • GITHUB_HEAD_REF / github.head_ref: the source branch name of the PR (only set for pull_request / pull_request_target). [3]

So on PR runs:

  • git rev-parse --abbrev-ref HEADHEAD (detached)
  • GITHUB_REF_NAME → like 123/merge
  • GITHUB_HEAD_REF → like feature/my-branch

Practical patterns

1) Get “the branch name” reliably (push OR PR)

env:
  BRANCH_NAME: ${{ github.head_ref || github.ref_name }}

This uses the PR source branch when available, otherwise the normal ref name. [2][3]

2) Make git rev-parse --abbrev-ref HEAD return a real branch on PRs

- uses: actions/checkout@v6
  with:
    ref: ${{ github.head_ref }}

This checks out the PR’s source branch instead of staying detached. [1][3]

Sources: [1] actions/checkout README (detached HEAD on PR unless ref set); [2] GitHub Docs: github.ref_name (PR format <pr_number>/merge); [3] GitHub Docs: github.head_ref (PR source branch).


🏁 Script executed:

# Find and examine the build.sh file and related CI configuration
find . -type f -name "build.sh" -o -name ".github" -type d | head -20

Repository: Redot-Engine/redot-docs

Length of output: 87


🏁 Script executed:

# Look for deploy logic that uses the output directory
rg "output/html|gitBranch" --type sh -A 3 -B 3

Repository: Redot-Engine/redot-docs

Length of output: 1660


🏁 Script executed:

# Check if there are GitHub Actions workflow files
find .github/workflows -type f -name "*.yml" -o -name "*.yaml" 2>/dev/null | head -10

Repository: Redot-Engine/redot-docs

Length of output: 216


🏁 Script executed:

# Examine the main build and deploy workflow
cat -n .github/workflows/build-and-deploy.yml

Repository: Redot-Engine/redot-docs

Length of output: 3143


🏁 Script executed:

# Also check the other build workflow
cat -n .github/workflows/build_offline_docs.yml

Repository: Redot-Engine/redot-docs

Length of output: 4253


Fix branch detection for GitHub Actions PRs (detached HEAD).
git rev-parse --abbrev-ref HEAD returns HEAD when the repository is checked out in detached HEAD mode (on pull requests), so build artifacts land in output/html/en/HEAD instead of the correct branch name. While this doesn't break the deploy step (which independently determines the directory using github.ref_name), it causes PR builds to be organized incorrectly.

🛠️ Suggested fix
-gitBranch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "master")
+gitBranch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "master")
+if [ -n "$GITHUB_HEAD_REF" ]; then
+    gitBranch="$GITHUB_HEAD_REF"
+elif [ -n "$GITHUB_REF_NAME" ]; then
+    gitBranch="$GITHUB_REF_NAME"
+fi
 if [ -n "$CF_PAGES" ]; then
     echo "Building on Cloudflare Pages"
     gitBranch="${CF_PAGES_BRANCH:-master}"
 fi
🤖 Prompt for AI Agents
In `@build.sh` around lines 22 - 27, The branch detection can return "HEAD" in
detached-HEAD CI runs; update the gitBranch assignment logic so after computing
gitBranch with git rev-parse you check if gitBranch == "HEAD" and then fall back
to the GitHub Actions environment variables: use GITHUB_HEAD_REF if set (PR
branch), else use GITHUB_REF_NAME, else default to "master"; keep the existing
CF_PAGES/CF_PAGES_BRANCH override logic intact (references: gitBranch, CF_PAGES,
CF_PAGES_BRANCH, GITHUB_HEAD_REF, GITHUB_REF_NAME).

Comment on lines +33 to +36
**Build optimizations:**
- `--exclude-classes`: Skips class reference migration (faster, these are auto-generated)
- `-j auto`: Uses all available CPU cores for parallel builds
- Branch mapping: `master` → `latest/`, other branches → `<branch-name>/`
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Sync the Quick Build optimization bullets with build.sh.
The script now uses -j 4, but the doc still says -j auto.

✏️ Suggested doc tweak
-- `-j auto`: Uses all available CPU cores for parallel builds
+- `-j 4`: Uses four parallel jobs (matches build.sh)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
**Build optimizations:**
- `--exclude-classes`: Skips class reference migration (faster, these are auto-generated)
- `-j auto`: Uses all available CPU cores for parallel builds
- Branch mapping: `master``latest/`, other branches → `<branch-name>/`
**Build optimizations:**
- `--exclude-classes`: Skips class reference migration (faster, these are auto-generated)
- `-j 4`: Uses four parallel jobs (matches build.sh)
- Branch mapping: `master``latest/`, other branches → `<branch-name>/`
🤖 Prompt for AI Agents
In `@README.md` around lines 33 - 36, The README's Quick Build bullet incorrectly
states "-j auto"; update that bullet to match build.sh which now uses "-j 4"
(change the bullet text from "`-j auto`: Uses all available CPU cores for
parallel builds" to "`-j 4`: Uses 4 parallel jobs as configured in build.sh"),
and ensure any mention of parallel build flags references build.sh (e.g.,
build.sh's invocation or variable) so the documentation and the build script
stay in sync.

Comment on lines +77 to 80
**How it works:**
```
sphinx-build -b html ./_migrated/ _build/html
Push to branch → GitHub Actions builds (30 min) → Deploys to Cloudflare Pages
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a language to the “How it works” fenced block.
Markdownlint (MD040) flags code fences without a language.

✏️ Suggested fix
-```
+```text
 Push to branch → GitHub Actions builds (30 min) → Deploys to Cloudflare Pages
</details>

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion
**How it works:**
🧰 Tools
🪛 markdownlint-cli2 (0.20.0)

[warning] 78-78: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
In `@README.md` around lines 77 - 80, Update the fenced code block under the "How
it works:" section to include a language identifier (e.g., add "text" after the
opening triple backticks) so the block becomes ```text ... ```, which satisfies
markdownlint MD040; locate the fenced block with the content "Push to branch →
GitHub Actions builds (30 min) → Deploys to Cloudflare Pages" and add the
language token to the opening fence.

Comment on lines +4 to +11
# Build settings
[build]
command = "FULL_RUN=1 bash build.sh"

# The directory containing your static files
[site]
bucket = "output"

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Cloudflare Wrangler v3 Pages wrangler.toml configuration keys pages_build_command pages_build_output_dir

💡 Result:

In Wrangler v3 for Cloudflare Pages, the relevant wrangler.toml key is:

  • pages_build_output_dir (string, required if you want Pages to treat your wrangler.toml as the source of truth): path to the directory containing the built static assets to upload (for example ./dist). [1]

There is no pages_build_command key in wrangler.toml for Pages—build commands are part of Pages “Build configuration” (dashboard/Git integration) or your CI/build step, not a Wrangler config field. [2]

Example:

name = "my-pages-app"
pages_build_output_dir = "./dist"

If pages_build_output_dir is missing, Wrangler warns and ignores the Pages config file for deploys. [3]

Sources: [1] [2] [3]


🏁 Script executed:

# Check if there are any other wrangler.toml files or docs in the repo
find . -name "wrangler.toml" -o -name "*wrangler*" -type f | head -20

Repository: Redot-Engine/redot-docs

Length of output: 82


🏁 Script executed:

# Look for any documentation or comments about the build configuration
rg "pages_build|build.sh|FULL_RUN" -A 2 -B 2

Repository: Redot-Engine/redot-docs

Length of output: 2822


🏁 Script executed:

# Check package.json or similar for Wrangler version info
find . -name "package.json" -o -name "package-lock.json" | head -5

Repository: Redot-Engine/redot-docs

Length of output: 49


Replace [build]/[site] with pages_build_output_dir for Cloudflare Pages.
The [build] and [site] sections are Workers Sites configuration, not Pages. For Wrangler v3 Pages, only pages_build_output_dir is recognized. Since your build is already orchestrated via GitHub Actions (which runs build.sh), remove the [build] section and replace [site] with:

pages_build_output_dir = "output"
Configuration change
-[build]
-command = "FULL_RUN=1 bash build.sh"
-
-[site]
-bucket = "output"
+pages_build_output_dir = "output"
🤖 Prompt for AI Agents
In `@wrangler.toml` around lines 4 - 11, The wrangler.toml currently uses Workers
Sites sections [build] and [site]; remove the [build] block (the command
invoking FULL_RUN=1 bash build.sh) and replace the [site] configuration with the
Pages-specific key pages_build_output_dir set to "output" so Wrangler v3 Pages
recognizes the build output; update or remove any references to build.sh
invocation in wrangler.toml since your CI/GitHub Actions handles the build.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants