Skip to content

automated deployment

1 post with the tag “automated deployment”

HagiCode in Practice: How to Use GitHub Actions for Docusaurus Automated Deployment

Adding GitHub Pages Automated Deployment Support to HagiCode

Section titled “Adding GitHub Pages Automated Deployment Support to HagiCode”

The project’s early codename was PCode, and it has now officially been renamed HagiCode. This article records how we introduced automated static site deployment for the project so publishing content becomes as easy as drinking water.

During HagiCode development, we ran into a very practical problem: as the amount of documentation and proposals kept growing, efficiently managing and presenting that content became increasingly urgent. We decided to use GitHub Pages to host our static site, but building and deploying manually was simply too much trouble. Every change required a local build, packaging, and then a manual push to the gh-pages branch. That was not only inefficient, but also error-prone.

To solve this problem (mostly because we wanted to be lazy), we needed an automated deployment workflow. This article documents in detail how we added GitHub Actions-based automated deployment support to the HagiCode project, so we can focus on creating content and leave the rest to automation.

Hey, let us introduce what we are building

We are developing HagiCode - an AI-powered coding assistant that makes development smarter, easier, and more enjoyable.

Smarter - AI assistance throughout the whole process, from ideas to code, multiplying coding efficiency. More convenient - multi-threaded concurrent operations that make full use of resources and keep the development workflow smooth. More enjoyable - gamification mechanisms and an achievement system that make coding less dull and far more rewarding.

The project is evolving quickly. If you are interested in technical writing, knowledge management, or AI-assisted development, feel free to check it out on GitHub~

Before getting started, we first need to clarify what exactly this task is supposed to accomplish. After all, sharpening the axe does not delay the work.

  1. Automated build: Automatically trigger the build process when code is pushed to the main branch.
  2. Automated deployment: After a successful build, automatically deploy the generated static files to GitHub Pages.
  3. Environment consistency: Ensure the CI environment matches the local build environment to avoid the awkward “it works locally but fails in production” situation.

Since HagiCode is built on Docusaurus (a very popular React static site generator), we can use GitHub Actions to achieve this goal.

GitHub Actions is the CI/CD service provided by GitHub. By defining workflow files in YAML format inside the repository, we can customize a variety of automation tasks.

We need to create a new configuration file in the .github/workflows folder under the project root, for example deploy.yml. If the folder does not exist, remember to create it manually first.

The core logic of this configuration file is as follows:

  1. Trigger condition: Listen for push events on the main branch.
  2. Runtime environment: The latest Ubuntu.
  3. Build steps:
    • Check out the code
    • Install Node.js
    • Install dependencies (npm install)
    • Build the static files (npm run build)
  4. Deployment step: Use the official action-gh-pages to push the build artifacts to the gh-pages branch.

Below is the configuration template we ultimately adopted:

name: Deploy to GitHub Pages
# Trigger condition: when pushing to the main branch
on:
push:
branches:
- main
# You can add path filters as needed, for example only build when docs change
# paths:
# - 'docs/**'
# - 'package.json'
# Set permissions, which are important for deploying to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Concurrency control: cancel older builds on the same branch
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
# Note: you must set fetch-depth: 0, otherwise the build version may be inaccurate
with:
fetch-depth: 0
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20 # Recommended to match your local development environment
cache: 'npm' # Enabling cache can speed up the build process
- name: Install dependencies
run: npm ci
# Use npm ci instead of npm install because it is faster, stricter, and better suited for CI
- name: Build website
run: npm run build
env:
# If your site build requires environment variables, configure them here
# NODE_ENV: production
# PUBLIC_URL: /your-repo-name
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./build # Default Docusaurus output directory
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4

Pitfalls Encountered During Implementation

Section titled “Pitfalls Encountered During Implementation”

In practice, we ran into a few issues. I am sharing them here in the hope that everyone can avoid them, or at least prepare solutions in advance.

When we first set things up, deployment kept failing with a 403 (Forbidden) error. After a long investigation, we discovered that GitHub’s default GITHUB_TOKEN did not have permission to write to Pages.

Solution: In the repository Settings -> Actions -> General -> Workflow permissions, make sure to choose “Read and write permissions”.

By default, Docusaurus puts the built static files in the build directory. However, some projects may use different configurations. For example, Create React App defaults to build, while Vite defaults to dist. If Actions reports that it cannot find files, remember to check the output path configuration in docusaurus.config.js.

If your repository is not a user homepage (that is, not username.github.io) but instead a project page (such as username.github.io/project-name), you need to configure baseUrl.

In docusaurus.config.js:

module.exports = {
// ...
url: 'https://hagicode.com', // Your Hagicode URL
baseUrl: '/', // Deploy at the root path
// ...
};

This detail is easy to overlook. If it is configured incorrectly, the page may load as a blank screen because the resource paths cannot be resolved.

After configuring everything and pushing the code, we can head to the Actions tab in the GitHub repository and enjoy the show.

You will see a yellow circle while the workflow is running. When it turns green, it means success. If it turns red, click into the logs to inspect the issue. Usually, you can track it down there, and most of the time it is a typo or an incorrect path configuration.

Once the build succeeds, visit https://<your-username>.github.io/<repo-name>/ and you should see your brand-new site.

By introducing GitHub Actions, we successfully implemented automated deployment for the HagiCode documentation site. This not only saves the time previously spent on manual operations, but more importantly standardizes the release process. Now, no matter which teammate updates the documentation, as long as the changes are merged into the main branch, the latest content will appear online a few minutes later.

Key benefits:

  • Higher efficiency: from “manual packaging and manual upload” to “code is the release”.
  • Fewer errors: removes the possibility of human operational mistakes.
  • Better experience: lets developers focus more on content quality instead of being distracted by tedious deployment steps.

Although setting up CI/CD can be a bit troublesome at first, especially with all the permissions and path issues, it is a one-time investment with huge long-term returns. I strongly recommend that every static site project adopt a similar automated workflow.


Thank you for reading. If you found this article useful, click the like button below 👍 so more people can discover it.

This content was created with AI-assisted collaboration, reviewed by me, and reflects my own views and position.