CI/CD
Deploy Freestruct with GitHub Actions
Freestruct integrates with any CI/CD. Here’s how with GitHub Actions.
GitHub Actions
Add to your existing workflow:
name: Build and Deploy
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install deps
run: npm install
- name: Build docs
run: npm run docs # your SSG build command
- name: Run freestruct
run: node docs/lib/inject.js docs/_site
- name: Upload build
uses: actions/upload-artifact@v4
with:
name: docs-build
path: docs/_site
Full Example
name: Build
on:
push:
branches: [main]
pull_request:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build Jekyll
run: bundle exec jekyll build
- name: Run freestruct
run: node docs/lib/inject.js _site
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: _site
path: _site
- name: Deploy (main only)
if: github.ref == 'refs/heads/main'
uses: peaceiris/actions-gh-pages@v3
with:
github_token: $
publish_dir: ./_site
Environment Variables
For private sites, use secrets:
- name: Run freestruct
run: node docs/lib/inject.js
env:
SITE_URL: $
API_KEY: $
Access in config:
site:
url: $SITE_URL
Other CI/CD
Netlify
Add to netlify.toml:
[build]
command = "your-ssg-build && node docs/lib/inject.js docs/_site"
publish = "docs/_site"
Vercel
Add to vercel.json:
{
"buildCommand": "your-ssg-build && node docs/lib/inject.js",
"outputDirectory": "docs/_site"
}
GitLab CI
build:
script:
- npm install
- your-ssg-build
- node docs/lib/inject.js docs/_site
artifacts:
paths:
- docs/_site/
Testing in CI
Test without deploying:
# Build + inject to temp folder
mkdir -p /tmp/test-build
cp -r docs/_site/* /tmp/test-build/
node docs/lib/inject.js /tmp/test-build
# Check output
grep freestruct-build /tmp/test-build/index.html
Common Issues
Missing js-yaml
# Ensure package.json has:
"js-yaml": "^4.0.0"
Wrong output path
Always match your SSG output:
# Jekyll
node docs/lib/inject.js docs/_site
# Hugo
node docs/lib/inject.js public
# Docusaurus
node docs/lib/inject.js build