11 KiB
11 KiB
GitOps: Woodpecker CI & Forgejo Integration
This document describes how to use the gitops crate with Woodpecker CI and Forgejo for event-driven CI/CD orchestration.
Overview
Woodpecker CI and Forgejo form a powerful, self-hosted CI/CD stack that pairs perfectly with declarative GitOps automation:
- Forgejo: Self-hosted Git repository management (fork of Gitea)
- Woodpecker CI: Lightweight, open-source CI/CD platform
- GitOps: Declarative rules engine for orchestrating both
Architecture
┌─────────────────┐
│ Forgejo │
│ (Git Host) │
└────────┬────────┘
│ Webhook
│ (push, PR, tag)
▼
┌──────────────────────────┐
│ GitOps Engine │
│ (Rule Processor) │
└────────┬────────────────┘
│ Triggers
│ Pipelines
▼
┌─────────────────┐
│ Woodpecker CI │
│ (CI/CD Runs) │
└────────┬────────┘
│ Webhook
│ (success, failure)
▼
┌──────────────────────────┐
│ Deploy/Notify │
│ (Actions) │
└──────────────────────────┘
Providers
Forgejo Provider
Forgejo is Gitea-compatible and supports the same API structure.
Configuration
use gitops::provider::{ForgejoProvider, GitProvider};
// Create provider
let provider = ForgejoProvider::with_token(
"https://git.company.internal/api/v1".to_string(),
"your-access-token".to_string(),
);
// Or use environment variable
let provider = ForgejoProvider::new("https://git.company.internal/api/v1".to_string());
Environment Variables
FORGEJO_TOKEN: API access token for Forgejo- Supports both PAT (Personal Access Token) and OAuth tokens
Supported Operations
- Get repository information
- List repositories
- Register/delete webhooks
- Create commit status checks
- Read/list files from repository
- Create and manage releases
- Sync organization members (LDAP integration available)
Woodpecker Provider
Woodpecker provides a RESTful API for pipeline orchestration.
Configuration
use gitops::provider::WoodpeckerProvider;
// Create provider
let provider = WoodpeckerProvider::with_token(
"https://ci.company.internal/api".to_string(),
"your-api-token".to_string(),
);
// Or use environment variable
let provider = WoodpeckerProvider::new("https://ci.company.internal/api".to_string());
Environment Variables
WOODPECKER_TOKEN: API token for Woodpecker
Supported Operations
- Get repository information
- List repositories
- Trigger pipeline runs
- Get pipeline status and logs
- Create commit status checks
- Register webhooks for pipeline events
Event Sources
Forgejo Event Source
Listens to Forgejo webhook events:
use gitops::event::ForgejoEventSource;
let source = ForgejoEventSource::new();
Supported events:
push: Code push to any branchpull_request: PR opened, closed, mergedtag_create: New tag createdrelease: Release published
Woodpecker Event Source
Listens to Woodpecker pipeline events:
use gitops::event::WoodpeckerEventSource;
let source = WoodpeckerEventSource::new();
Supported events:
pipeline_started: Pipeline execution startedpipeline_success: Pipeline completed successfullypipeline_failure: Pipeline failedpipeline_killed: Pipeline was manually stopped
Usage Examples
Example 1: Auto-Deploy on Tag Push
rules:
- name: "deploy-on-tag"
when:
event: "git"
type: "tag_create"
provider: "forgejo"
matches:
tag: "v[0-9]+(\\.[0-9]+){2}"
then:
action: "deploy"
environment: "production"
params:
deployment_method: "kubernetes"
version: "${GIT_TAG}"
Example 2: Trigger Woodpecker Pipeline
rules:
- name: "trigger-ci-on-push"
when:
event: "git"
type: "push"
provider: "forgejo"
matches:
branch: "main"
then:
action: "trigger-pipeline"
provider: "woodpecker"
params:
repo: "${GIT_REPO}"
branch: "${GIT_BRANCH}"
commit: "${GIT_COMMIT}"
Example 3: Deploy After Successful Pipeline
rules:
- name: "deploy-after-build"
when:
event: "woodpecker"
type: "pipeline_success"
matches:
branch: "develop"
then:
action: "deploy"
environment: "staging"
params:
deployment_method: "kubernetes"
namespace: "staging"
Example 4: Auto-Merge PR on CI Success
rules:
- name: "auto-merge-develop-pr"
when:
event: "woodpecker"
type: "pipeline_success"
matches:
trigger_event: "pull_request"
target_branch: "develop"
then:
action: "merge-pr"
params:
provider: "forgejo"
merge_method: "squash"
delete_source_branch: true
Webhook Configuration
Forgejo Webhook Setup
- Go to Repository → Settings → Webhooks
- Add webhook:
- Payload URL:
https://gitops.internal/webhooks/forgejo - Content Type:
application/json - Events: Push, Pull Request, Tag Creation, Release
- Secret: Set to
FORGEJO_WEBHOOK_SECRET
- Payload URL:
Woodpecker Webhook Setup
- Go to Repository → Settings → Integrations
- Add webhook:
- Webhook URL:
https://gitops.internal/webhooks/woodpecker - Trigger on: Pipeline events
- Secret: Set to
WOODPECKER_WEBHOOK_SECRET
- Webhook URL:
Complete Workflow Example
Repository Structure
myrepo/
├── .woodpecker.yaml # Woodpecker CI configuration
├── .forgejo/ # Forgejo-specific files
│ └── issue_template/ # Issue templates
├── src/
├── tests/
└── README.md
.woodpecker.yaml
pipeline:
build:
image: rust:1.75
commands:
- cargo build --release
when:
event: [push, pull_request]
test:
image: rust:1.75
commands:
- cargo test --all
when:
event: [push, pull_request]
deploy-staging:
image: alpine/k8s:latest
commands:
- kubectl set image deployment/app app=myrepo:${CI_COMMIT_SHA} -n staging
when:
event: push
branch: develop
deploy-production:
image: alpine/k8s:latest
commands:
- kubectl set image deployment/app app=myrepo:${CI_COMMIT_SHA} -n production
secrets: [KUBECONFIG]
when:
event: push
branch: main
GitOps Rules
rules:
# Build on push
- name: "build-on-push"
when:
event: "git"
type: "push"
provider: "forgejo"
then:
action: "trigger-pipeline"
provider: "woodpecker"
# Deploy staging
- name: "deploy-staging"
when:
event: "woodpecker"
type: "pipeline_success"
matches:
branch: "develop"
then:
action: "deploy"
environment: "staging"
# Deploy production (with approval)
- name: "deploy-production"
when:
event: "git"
type: "tag_create"
provider: "forgejo"
then:
action: "deploy"
environment: "production"
requires_approval: true
approvers:
- "product-owner@company.com"
Environment Variables
Required environment variables:
# Forgejo
export FORGEJO_TOKEN="your-access-token"
export FORGEJO_WEBHOOK_SECRET="webhook-secret"
# Woodpecker
export WOODPECKER_TOKEN="your-api-token"
export WOODPECKER_WEBHOOK_SECRET="webhook-secret"
# Notifications
export SLACK_WEBHOOK="https://hooks.slack.com/services/..."
# Kubernetes (for deployments)
export KUBECONFIG="/path/to/kubeconfig"
Advanced Features
1. Repository Mirroring
Mirror Forgejo repositories to backup or public providers:
rules:
- name: "mirror-to-github"
when:
event: "git"
type: "push"
provider: "forgejo"
matches:
branch: "main"
then:
action: "mirror"
params:
destination: "github"
repo: "myorg/myrepo"
force_update: false
2. Automatic Dependency Updates
rules:
- name: "auto-update-deps"
when:
event: "schedule"
matches:
cron: "0 2 * * 0" # Weekly
then:
action: "create-pr"
params:
title: "[Chore] Update dependencies"
branch: "chore/deps-update"
3. Security Scanning
rules:
- name: "security-scan"
when:
event: "schedule"
matches:
cron: "0 3 * * 1" # Weekly on Monday
then:
action: "trigger-pipeline"
provider: "woodpecker"
params:
pipeline: "security-scan"
4. LDAP/Active Directory Sync
// Automatic synchronization of Forgejo users from LDAP
let provider = ForgejoProvider::with_token(
"https://git.company.internal/api/v1".to_string(),
token,
);
// Configure LDAP sync in Forgejo settings
// gitops will maintain organization membership in sync
Troubleshooting
Webhook Not Firing
- Check webhook delivery in Forgejo: Settings → Webhooks → Recent Deliveries
- Verify firewall allows
gitops.internalfrom Forgejo - Check GitOps logs:
RUST_LOG=debug cargo run
Pipeline Not Triggering
- Verify Woodpecker token has API access
- Check Woodpecker repository settings are enabled
- Ensure webhook secret is correctly configured
Permission Errors
- Verify token has necessary scopes:
- Forgejo:
repo,admin:org(if managing organizations) - Woodpecker:
repo,pipeline
- Forgejo:
- Check repository permissions in Forgejo
Best Practices
- Token Rotation: Rotate API tokens regularly
- Webhook Secrets: Always use webhook secrets for security
- Rule Ordering: Order rules by priority (higher first)
- Approval Gates: Require approval for production deployments
- Monitoring: Enable metrics and alerts for GitOps engine
- Backups: Backup Forgejo repositories regularly
- Testing: Test rules in staging before production
Performance Considerations
- Woodpecker pipelines run in parallel by default
- Use
depends_onin .woodpecker.yaml to control dependency - GitOps processes events sequentially (configurable concurrency)
- Webhook delivery is retried 3 times with exponential backoff
Security Considerations
- Secrets Management: Never commit tokens; use environment variables
- Webhook Validation: Always validate webhook signatures
- RBAC: Use Forgejo and Woodpecker RBAC features
- Network Isolation: Keep internal services behind VPN/firewall
- Audit Logs: Enable audit logging in Forgejo and Woodpecker