Implementasi Workflow untuk Docusaurus
Pengenalan
Pada bagian ini, kita akan membahas implementasi workflow Gitea Actions untuk project Docusaurus. Workflow ini mencakup proses build, test, containerization, dan deployment ke Kubernetes.
Struktur Workflow
Directory Structure
.gitea/
└── workflows/
├── build.yml # Build dan test aplikasi
├── docker.yml # Build dan push Docker image
└── deploy.yml # Deploy ke Kubernetes
1. Build Workflow
File: .gitea/workflows/build.yml
Workflow ini bertanggung jawab untuk:
- Checkout source code
- Install dependencies
- Build aplikasi Docusaurus
- Upload build artifacts
name: Build and Test
on:
push:
branches:
- main
- develop
pull_request:
branches:
- main
- develop
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run type check
run: npm run typecheck
- name: Build application
run: npm run build
env:
NODE_ENV: production
- name: Upload build artifacts
uses: actions/upload-artifact@v3
with:
name: docusaurus-build
path: build/
retention-days: 7
- name: Build size report
run: |
echo "## Build Size Report" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "```" >> $GITHUB_STEP_SUMMARY
du -sh build/ >> $GITHUB_STEP_SUMMARY
echo "```" >> $GITHUB_STEP_SUMMARY
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run ESLint
run: npm run lint --if-present
continue-on-error: true
Penjelasan Build Workflow
Triggers
on:
push:
branches:
- main
- develop
- Workflow berjalan otomatis saat ada push ke branch
mainataudevelop - Juga berjalan pada pull request
Build Job
- Checkout code: Mengambil source code dari repository
- Setup Node.js: Install Node.js 20 dengan caching npm
- Install dependencies:
npm ciuntuk clean install - Type check: Validasi TypeScript
- Build: Compile aplikasi Docusaurus
- Upload artifacts: Simpan hasil build untuk job berikutnya
Environment Variables
NODE_ENV=production: Optimize build untuk production
2. Docker Workflow
File: .gitea/workflows/docker.yml
Workflow untuk build dan push Docker image ke container registry.
name: Docker Build and Push
on:
push:
branches:
- main
tags:
- 'v*'
workflow_dispatch:
env:
REGISTRY: docker.io
IMAGE_NAME: ${{ gitea.repository_owner }}/gitea-docs
jobs:
docker:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Log in to Container Registry
uses: docker/login-action@v2
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v4
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha,prefix={{branch}}-
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
context: .
file: ./Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache
cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max
platforms: linux/amd64,linux/arm64
- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}
- name: Scan image for vulnerabilities
uses: aquasecurity/trivy-action@master
with:
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
format: 'sarif'
output: 'trivy-results.sarif'
continue-on-error: true
- name: Upload scan results
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-results.sarif'
continue-on-error: true
Penjelasan Docker Workflow
Multi-platform Build
platforms: linux/amd64,linux/arm64
Build image untuk multiple architectures (AMD64 dan ARM64)
Image Tagging Strategy
branch name: Untuk tracking per branchsha: Unique identifier dari commitsemver: Semantic versioning untuk releaseslatest: Tag untuk main branch
Docker Layer Caching
cache-from: type=registry,ref=...
cache-to: type=registry,ref=...
Mempercepat build dengan cache layers di registry
Security Scanning
- Trivy scan untuk detect vulnerabilities
- Output SARIF format untuk integration dengan security tools
3. Deployment Workflow
File: .gitea/workflows/deploy.yml
Workflow untuk deploy aplikasi ke Kubernetes cluster.
name: Deploy to Kubernetes
on:
workflow_run:
workflows: ["Docker Build and Push"]
types:
- completed
branches:
- main
workflow_dispatch:
inputs:
environment:
description: 'Deployment environment'
required: true
default: 'staging'
type: choice
options:
- staging
- production
env:
REGISTRY: docker.io
IMAGE_NAME: ${{ gitea.repository_owner }}/gitea-docs
jobs:
deploy:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
environment:
name: ${{ inputs.environment || 'staging' }}
url: https://${{ inputs.environment || 'staging' }}.example.com
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup kubectl
uses: azure/setup-kubectl@v3
with:
version: 'v1.28.0'
- name: Configure kubectl
run: |
mkdir -p $HOME/.kube
echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > $HOME/.kube/config
chmod 600 $HOME/.kube/config
- name: Verify cluster connection
run: |
kubectl cluster-info
kubectl get nodes
- name: Set image tag
id: image
run: |
if [ "${{ github.ref }}" == "refs/heads/main" ]; then
echo "tag=latest" >> $GITHUB_OUTPUT
else
echo "tag=${{ github.sha }}" >> $GITHUB_OUTPUT
fi
- name: Update deployment image
run: |
kubectl set image deployment/gitea-docs \
gitea-docs=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.image.outputs.tag }} \
-n gitea-docs-${{ inputs.environment || 'staging' }}
- name: Apply Kubernetes manifests
run: |
kubectl apply -f k8s/ \
-n gitea-docs-${{ inputs.environment || 'staging' }}
- name: Wait for rollout
run: |
kubectl rollout status deployment/gitea-docs \
-n gitea-docs-${{ inputs.environment || 'staging' }} \
--timeout=5m
- name: Verify deployment
run: |
kubectl get pods -n gitea-docs-${{ inputs.environment || 'staging' }}
kubectl get services -n gitea-docs-${{ inputs.environment || 'staging' }}
- name: Run smoke tests
run: |
ENDPOINT="https://${{ inputs.environment || 'staging' }}.example.com"
echo "Testing endpoint: $ENDPOINT"
# Health check
curl -f $ENDPOINT/health || exit 1
# Homepage check
STATUS=$(curl -o /dev/null -s -w "%{http_code}" $ENDPOINT)
if [ $STATUS -ne 200 ]; then
echo "Smoke test failed with status: $STATUS"
exit 1
fi
echo "Smoke tests passed!"
- name: Rollback on failure
if: failure()
run: |
echo "Deployment failed, initiating rollback..."
kubectl rollout undo deployment/gitea-docs \
-n gitea-docs-${{ inputs.environment || 'staging' }}
kubectl rollout status deployment/gitea-docs \
-n gitea-docs-${{ inputs.environment || 'staging' }}
notify:
runs-on: ubuntu-latest
needs: deploy
if: always()
steps:
- name: Send notification
run: |
STATUS="${{ needs.deploy.result }}"
ENV="${{ inputs.environment || 'staging' }}"
if [ "$STATUS" == "success" ]; then
MESSAGE="✅ Deployment to $ENV succeeded!"
else
MESSAGE="❌ Deployment to $ENV failed!"
fi
# Send to webhook (Slack, Discord, etc.)
curl -X POST ${{ secrets.WEBHOOK_URL }} \
-H 'Content-Type: application/json' \
-d "{\"text\":\"$MESSAGE\"}"
Penjelasan Deployment Workflow
Trigger Conditions
workflow_run:
workflows: ["Docker Build and Push"]
types: [completed]
- Otomatis berjalan setelah Docker workflow selesai
- Manual trigger dengan
workflow_dispatch
Environment Strategy
- Staging: Auto-deploy dari main branch
- Production: Manual approval required
Deployment Steps
- Setup kubectl: Install Kubernetes CLI
- Configure access: Setup kubeconfig dari secrets
- Update image: Set image tag terbaru
- Apply manifests: Deploy Kubernetes resources
- Wait rollout: Monitor deployment progress
- Smoke tests: Basic health checks
- Rollback: Auto-rollback jika gagal
Rollback Strategy
kubectl rollout undo deployment/gitea-docs
Automatic rollback ke revision sebelumnya jika deployment gagal
4. Complete Pipeline Workflow
File: .gitea/workflows/pipeline.yml
Workflow lengkap yang menggabungkan semua tahapan.
name: Complete CI/CD Pipeline
on:
push:
branches:
- main
- develop
pull_request:
branches:
- main
jobs:
# Stage 1: Build dan Test
build:
name: Build Application
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '20'
cache: 'npm'
- name: Get version
id: version
run: |
VERSION=$(node -p "require('./package.json').version")
echo "version=$VERSION" >> $GITHUB_OUTPUT
- run: npm ci
- run: npm run typecheck
- run: npm run build
- uses: actions/upload-artifact@v3
with:
name: build-${{ github.sha }}
path: build/
# Stage 2: Security Scan
security:
name: Security Scan
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/checkout@v3
- name: Run dependency check
run: npm audit --audit-level=moderate
continue-on-error: true
- name: Run SAST scan
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: '.'
format: 'sarif'
output: 'trivy-results.sarif'
# Stage 3: Docker Build
docker:
name: Build Docker Image
runs-on: ubuntu-latest
needs: [build, security]
if: github.ref == 'refs/heads/main'
outputs:
image-tag: ${{ steps.meta.outputs.tags }}
steps:
- uses: actions/checkout@v3
- uses: docker/setup-buildx-action@v2
- uses: docker/login-action@v2
with:
registry: docker.io
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push
id: docker_build
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: |
docker.io/${{ gitea.repository_owner }}/gitea-docs:latest
docker.io/${{ gitea.repository_owner }}/gitea-docs:${{ needs.build.outputs.version }}
docker.io/${{ gitea.repository_owner }}/gitea-docs:${{ github.sha }}
# Stage 4: Deploy to Staging
deploy-staging:
name: Deploy to Staging
runs-on: ubuntu-latest
needs: docker
if: github.ref == 'refs/heads/main'
environment:
name: staging
url: https://staging.example.com
steps:
- uses: actions/checkout@v3
- name: Deploy to Kubernetes
run: |
# Setup kubectl
mkdir -p $HOME/.kube
echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > $HOME/.kube/config
# Deploy
kubectl set image deployment/gitea-docs \
gitea-docs=docker.io/${{ gitea.repository_owner }}/gitea-docs:${{ github.sha }} \
-n gitea-docs-staging
# Wait for rollout
kubectl rollout status deployment/gitea-docs -n gitea-docs-staging
# Stage 5: Integration Tests
integration-tests:
name: Integration Tests
runs-on: ubuntu-latest
needs: deploy-staging
steps:
- uses: actions/checkout@v3
- name: Run integration tests
run: |
# Wait for application to be ready
sleep 30
# Run tests against staging
curl -f https://staging.example.com/health
curl -f https://staging.example.com/
echo "✅ Integration tests passed"
# Stage 6: Deploy to Production
deploy-production:
name: Deploy to Production
runs-on: ubuntu-latest
needs: [integration-tests]
if: github.ref == 'refs/heads/main'
environment:
name: production
url: https://docs.example.com
steps:
- uses: actions/checkout@v3
- name: Deploy to Production
run: |
# Setup kubectl
mkdir -p $HOME/.kube
echo "${{ secrets.KUBE_CONFIG_PROD }}" | base64 -d > $HOME/.kube/config
# Deploy with canary strategy
kubectl set image deployment/gitea-docs \
gitea-docs=docker.io/${{ gitea.repository_owner }}/gitea-docs:${{ github.sha }} \
-n gitea-docs-production
# Wait and monitor
kubectl rollout status deployment/gitea-docs -n gitea-docs-production
- name: Smoke tests
run: |
curl -f https://docs.example.com/health
curl -f https://docs.example.com/
Secrets Configuration
Required Secrets
Tambahkan secrets di Gitea Repository Settings → Secrets:
| Secret Name | Description | Example |
|---|---|---|
DOCKER_USERNAME | Docker Hub username | myusername |
DOCKER_PASSWORD | Docker Hub password/token | dckr_pat_xxxxx |
KUBE_CONFIG | Kubernetes config (base64) | base64 encoded kubeconfig |
KUBE_CONFIG_PROD | Production K8s config | base64 encoded kubeconfig |
WEBHOOK_URL | Notification webhook | https://hooks.slack.com/... |
Generate base64 kubeconfig
cat ~/.kube/config | base64 -w 0
Workflow Best Practices
1. Job Dependencies
needs: [build, test]
Ensure proper execution order
2. Conditional Execution
if: github.ref == 'refs/heads/main'
Control when jobs run
3. Matrix Testing
strategy:
matrix:
node-version: [18, 20, 22]
Test multiple versions
4. Caching
- uses: actions/cache@v3
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
Speed up builds
5. Artifacts
- uses: actions/upload-artifact@v3
with:
name: build-artifacts
path: build/
Share data between jobs
Monitoring Workflows
View Workflow Runs
- Navigate ke repository di Gitea
- Click tab Actions
- View workflow runs, logs, dan artifacts
Workflow Status Badge
Tambahkan di README.md:

Troubleshooting
Workflow Tidak Berjalan
Cek:
- Gitea Actions enabled di repository settings
- Runner tersedia dan online
- Workflow file syntax valid
- Branch protection rules
Build Failures
Debug steps:
- name: Debug
run: |
echo "GitHub context:"
echo "${{ toJSON(github) }}"
echo "Environment variables:"
env | sort
Permission Issues
Fix:
permissions:
contents: read
packages: write
Kesimpulan
Implementasi workflow Gitea Actions untuk Docusaurus mencakup:
- ✅ Automated build dan testing
- ✅ Docker image creation
- ✅ Multi-stage deployment
- ✅ Security scanning
- ✅ Automatic rollback
- ✅ Notification system
Pipeline ini memberikan foundation yang solid untuk continuous delivery dengan reliability dan security yang tinggi.
Next: Konfigurasi Kubernetes manifests untuk deployment.