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

470 lines
11 KiB
Markdown

# 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
```rust
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
```rust
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:
```rust
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:
```rust
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
```yaml
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
```yaml
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
```yaml
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
```yaml
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
```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
```yaml
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:
```bash
# 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:
```yaml
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
```yaml
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
```yaml
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
```rust
// 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
- [Examples](../../examples/gitops-woodpecker.yaml)
- [Examples](../../examples/gitops-forgejo.yaml)
- [Examples](../../examples/gitops-woodpecker-forgejo.yaml)
- [Main GitOps Documentation](README.md)