provisioning-platform/prov-ecosystem/crates/gitops/WOODPECKER_FORGEJO.md

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 branch
  • pull_request: PR opened, closed, merged
  • tag_create: New tag created
  • release: Release published

Woodpecker Event Source

Listens to Woodpecker pipeline events:

use gitops::event::WoodpeckerEventSource;

let source = WoodpeckerEventSource::new();

Supported events:

  • pipeline_started: Pipeline execution started
  • pipeline_success: Pipeline completed successfully
  • pipeline_failure: Pipeline failed
  • pipeline_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

  1. Go to Repository → Settings → Webhooks
  2. 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

Woodpecker Webhook Setup

  1. Go to Repository → Settings → Integrations
  2. Add webhook:
    • Webhook URL: https://gitops.internal/webhooks/woodpecker
    • Trigger on: Pipeline events
    • Secret: Set to WOODPECKER_WEBHOOK_SECRET

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

  1. Check webhook delivery in Forgejo: Settings → Webhooks → Recent Deliveries
  2. Verify firewall allows gitops.internal from Forgejo
  3. Check GitOps logs: RUST_LOG=debug cargo run

Pipeline Not Triggering

  1. Verify Woodpecker token has API access
  2. Check Woodpecker repository settings are enabled
  3. Ensure webhook secret is correctly configured

Permission Errors

  1. Verify token has necessary scopes:
    • Forgejo: repo, admin:org (if managing organizations)
    • Woodpecker: repo, pipeline
  2. Check repository permissions in Forgejo

Best Practices

  1. Token Rotation: Rotate API tokens regularly
  2. Webhook Secrets: Always use webhook secrets for security
  3. Rule Ordering: Order rules by priority (higher first)
  4. Approval Gates: Require approval for production deployments
  5. Monitoring: Enable metrics and alerts for GitOps engine
  6. Backups: Backup Forgejo repositories regularly
  7. Testing: Test rules in staging before production

Performance Considerations

  • Woodpecker pipelines run in parallel by default
  • Use depends_on in .woodpecker.yaml to control dependency
  • GitOps processes events sequentially (configurable concurrency)
  • Webhook delivery is retried 3 times with exponential backoff

Security Considerations

  1. Secrets Management: Never commit tokens; use environment variables
  2. Webhook Validation: Always validate webhook signatures
  3. RBAC: Use Forgejo and Woodpecker RBAC features
  4. Network Isolation: Keep internal services behind VPN/firewall
  5. Audit Logs: Enable audit logging in Forgejo and Woodpecker

See Also