CI/CD Integration
On this page 28
Deploy your BunPress documentation site with various CI/CD platforms and hosting providers.
GitHub Actions
Basic Deployment
name: Deploy Documentation
on:
push:
branches: [main]
jobs:
deploy:
runs ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
- name: Install dependencies
run: bun install
- name: Build documentation
run: bunpress build
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./dist
With Caching
jobs:
deploy:
runs ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- name: Cache dependencies
uses: actions/cache@v4
with:
path: ~/.bun/install/cache
key: bun-${{ hashFiles('bun.lockb') }}
- name: Cache BunPress
uses: actions/cache@v4
with:
path: .bunpress/cache
key: bunpress-${{ hashFiles('docs/**') }}
- run: bun install
- run: bunpress build
Vercel
Configuration
// vercel.json
{
"buildCommand": "bunpress build",
"outputDirectory": "dist",
"framework": null,
"installCommand": "bun install"
}
GitHub Integration
- Connect repository to Vercel
- Configure build settings:
- Build Command:
bunpress build - Output Directory:
dist - Install Command:
bun install
- Build Command:
Netlify
Configuration
# netlify.toml
[build]
command = "bunpress build"
publish = "dist"
[build.environment]
NODE_VERSION = "20"
[[plugins]]
package = "@netlify/plugin-functions-install-core"
Deploy Configuration
# .github/workflows/netlify.yml
name: Deploy to Netlify
on: [push]
jobs:
deploy:
runs ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- run: bun install
- run: bunpress build
- name: Deploy to Netlify
uses: nwtgck/actions-netlify@v2
with:
publish ./dist
production true
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
Cloudflare Pages
Configuration
name: Deploy to Cloudflare Pages
on: [push]
jobs:
deploy:
runs ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- run: bun install
- run: bunpress build
- name: Deploy to Cloudflare Pages
uses: cloudflare/pages-action@v1
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
projectName: my-docs
directory: dist
AWS S3 + CloudFront
name: Deploy to AWS
on:
push:
branches: [main]
jobs:
deploy:
runs ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- run: bun install
- run: bunpress build
- name: Configure AWS
uses: aws-actions/configure-aws-credentials@v4
with:
aws ${{ secrets.AWS_ACCESS_KEY_ID }}
aws ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws us-east-1
- name: Deploy to S3
run: aws s3 sync ./dist s3://my-docs-bucket --delete
- name: Invalidate CloudFront
run: aws cloudfront create-invalidation --distribution-id ${{ secrets.CF_DISTRIBUTION_ID }} --paths "/_"
GitLab CI
stages:
- build
- deploy
build:
stage: build
image: oven/bun:latest
script:
- bun install
- bunpress build
artifacts:
paths:
- dist/
pages:
stage: deploy
dependencies:
- build
script:
- mv dist public
artifacts:
paths:
- public
only:
- main
Docker Deployment
Dockerfile
FROM oven/bun:latest AS builder
WORKDIR /app
COPY package.json bun.lockb ./
RUN bun install
COPY . .
RUN bunpress build
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
nginx.conf
server {
listen 80;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ $uri.html /index.html;
}
location ~_ \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
Preview Deployments
Vercel Preview
name: Preview
on: [pull_request]
jobs:
preview:
runs ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- run: bun install
- run: bunpress build
- name: Deploy Preview
uses: amondnet/vercel-action@v25
with:
vercel ${{ secrets.VERCEL_TOKEN }}
vercel ${{ secrets.VERCEL_ORG_ID }}
vercel ${{ secrets.VERCEL_PROJECT_ID }}
Comment Preview URL
- name: Comment Preview URL
uses: marocchino/sticky-pull-request-comment@v2
with:
message: |
Preview deployed to: ${{ steps.preview.outputs.preview-url }}
Environment Configuration
Production vs Preview
// bunpress.config.ts
const isProd = process.env.NODE_ENV === 'production'
const isPreview = process.env.VERCEL_ENV === 'preview'
export default {
sitemap: {
baseUrl: isProd
? 'https://docs.example.com'
: 'https://preview.docs.example.com',
},
robots: {
enabled: isProd && !isPreview,
},
}
Build Optimization
Parallel Builds
jobs:
build:
runs ubuntu-latest
strategy:
matrix:
shard: [1, 2, 3, 4]
steps:
- run: bunpress build --shard=${{ matrix.shard }}/4
Incremental Builds
- name: Cache build
uses: actions/cache@v4
with:
path: .bunpress/cache
key: bunpress-${{ hashFiles('docs/**') }}
- run: bunpress build --incremental
Monitoring
Build Notifications
- name: Notify Slack
if: always()
uses: slackapi/slack-github-action@v1
with:
payload: |
{
"text": "Docs build ${{ job.status }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
Best Practices
- Cache dependencies: Speed up builds
- Incremental builds: Only rebuild changed content
- Preview deployments: Test before merging
- Environment separation: Different configs per environment
- Monitoring: Track build status and performance
Related
- Configuration - Build options
- Performance - Build optimization
- Theming - Production theming