470 lines
11 KiB
Markdown
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)
|