Add complete webhook-based CI/CD with automatic builds and notifications
Some checks failed
Build and Push to Harbor / build-and-push (push) Has been cancelled
Some checks failed
Build and Push to Harbor / build-and-push (push) Has been cancelled
This commit implements a full webhook-triggered CI/CD pipeline: **Flux Components:** - Flux Receiver for Gitea webhooks (generic type, NodePort 30090) - Notification Provider for notify.caffeinetux.com - Alerts for git updates, builds, and deployments **Build Automation:** - Webhook listener deployment that triggers on git push - Automatic Kaniko build jobs with git metadata - Images tagged with both 'latest' and commit SHA - Build notifications sent at start and completion **Workflow:** 1. Push to Gitea → Webhooks trigger Flux receiver & build listener 2. Build listener creates Kaniko job with commit info 3. Kaniko builds and pushes to Harbor (latest + SHA tags) 4. Flux auto-deploys latest image to cluster 5. Notifications sent to notify.caffeinetux.com at each stage **Configuration:** - Token: APMvTuncQJmm6vd - Webhook path: /hook/548969c2b24c717fe9e5af8c78ddfeec40d3024c270c7e85ac8f986259aeec9a - Build trigger: http://<node-ip>:30091/webhook - Comprehensive setup documentation in WEBHOOK_SETUP_GUIDE.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
364
WEBHOOK_SETUP_GUIDE.md
Normal file
364
WEBHOOK_SETUP_GUIDE.md
Normal file
@@ -0,0 +1,364 @@
|
|||||||
|
# Neon Vortex Webhook CI/CD Setup Guide
|
||||||
|
|
||||||
|
This guide explains how to configure Gitea webhooks to automatically build and deploy Neon Vortex on every push, with notifications sent to notify.caffeinetux.com.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The pipeline now works as follows:
|
||||||
|
|
||||||
|
1. **Push to Gitea** → Triggers webhook
|
||||||
|
2. **Flux Receiver** → Detects push and reconciles GitRepository
|
||||||
|
3. **Webhook Listener** → Triggers Kaniko build job
|
||||||
|
4. **Kaniko** → Builds and pushes image to Harbor
|
||||||
|
5. **Flux HelmRelease** → Auto-deploys latest image
|
||||||
|
6. **Notifications** → Sent to notify.caffeinetux.com at each stage
|
||||||
|
|
||||||
|
## Components Deployed
|
||||||
|
|
||||||
|
### Flux Components
|
||||||
|
- **Receiver**: `neon-vortex-receiver` (flux-system namespace)
|
||||||
|
- Webhook path: `/hook/548969c2b24c717fe9e5af8c78ddfeec40d3024c270c7e85ac8f986259aeec9a`
|
||||||
|
- NodePort: 30090
|
||||||
|
- **Provider**: `neon-vortex-notify` (notifications endpoint)
|
||||||
|
- **Alerts**: Git updates, build status, deployment status
|
||||||
|
|
||||||
|
### Build Trigger
|
||||||
|
- **Deployment**: `webhook-build-listener` (default namespace)
|
||||||
|
- NodePort: 30091
|
||||||
|
- Automatically creates build jobs on webhook trigger
|
||||||
|
|
||||||
|
## Gitea Webhook Configuration
|
||||||
|
|
||||||
|
You need to configure TWO webhooks in Gitea:
|
||||||
|
|
||||||
|
### Webhook 1: Flux Receiver (for Git sync)
|
||||||
|
|
||||||
|
1. Go to: `http://192.168.1.49:13001/admin/neon-vortex/settings/hooks`
|
||||||
|
2. Click **Add Webhook** → **Gitea**
|
||||||
|
3. Configure:
|
||||||
|
- **Target URL**: `http://<NODE_IP>:30090/hook/548969c2b24c717fe9e5af8c78ddfeec40d3024c270c7e85ac8f986259aeec9a`
|
||||||
|
- **HTTP Method**: `POST`
|
||||||
|
- **POST Content Type**: `application/json`
|
||||||
|
- **Secret**: `neon-vortex-webhook-secret-2024`
|
||||||
|
- **Trigger On**: ✅ Push events
|
||||||
|
- **Branch filter**: `main`
|
||||||
|
- **Active**: ✅ Enabled
|
||||||
|
4. Click **Add Webhook**
|
||||||
|
|
||||||
|
### Webhook 2: Build Trigger (for automatic builds)
|
||||||
|
|
||||||
|
1. Go to: `http://192.168.1.49:13001/admin/neon-vortex/settings/hooks`
|
||||||
|
2. Click **Add Webhook** → **Gitea**
|
||||||
|
3. Configure:
|
||||||
|
- **Target URL**: `http://<NODE_IP>:30091/webhook`
|
||||||
|
- **HTTP Method**: `POST`
|
||||||
|
- **POST Content Type**: `application/json`
|
||||||
|
- **Secret**: (leave empty)
|
||||||
|
- **Trigger On**: ✅ Push events
|
||||||
|
- **Branch filter**: `main`
|
||||||
|
- **Active**: ✅ Enabled
|
||||||
|
4. Click **Add Webhook**
|
||||||
|
|
||||||
|
## Finding Your Node IP
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Get node IP
|
||||||
|
kubectl get nodes -o wide
|
||||||
|
|
||||||
|
# Test Flux webhook endpoint
|
||||||
|
curl -X POST http://<NODE_IP>:30090/hook/548969c2b24c717fe9e5af8c78ddfeec40d3024c270c7e85ac8f986259aeec9a
|
||||||
|
|
||||||
|
# Test build trigger endpoint
|
||||||
|
curl -X POST http://<NODE_IP>:30091/webhook
|
||||||
|
```
|
||||||
|
|
||||||
|
## Notification Configuration
|
||||||
|
|
||||||
|
Notifications are sent to `https://notify.caffeinetux.com` using token: `APMvTuncQJmm6vd`
|
||||||
|
|
||||||
|
You'll receive notifications for:
|
||||||
|
- ✅ **Build Started**: When a new build job is created
|
||||||
|
- ✅ **Build Complete**: When the image is successfully built
|
||||||
|
- ✅ **Deployment Events**: When Flux updates the application
|
||||||
|
- ❌ **Failures**: If any step fails
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
### On Git Push:
|
||||||
|
|
||||||
|
1. **Gitea** sends webhook to both endpoints
|
||||||
|
2. **Flux Receiver** reconciles the GitRepository immediately
|
||||||
|
3. **Build Listener** receives webhook and triggers build script
|
||||||
|
4. **Build Script**:
|
||||||
|
- Clones repository
|
||||||
|
- Extracts commit info (SHA, message, author)
|
||||||
|
- Sends "Build Started" notification
|
||||||
|
- Creates Kaniko build job with unique name
|
||||||
|
5. **Kaniko Job**:
|
||||||
|
- Clones and checks out specific commit
|
||||||
|
- Builds Docker image
|
||||||
|
- Pushes to Harbor with tags:
|
||||||
|
- `latest` (used for deployment)
|
||||||
|
- `<commit-short-sha>` (for versioning)
|
||||||
|
- Adds git metadata as image labels
|
||||||
|
6. **Notification Container**:
|
||||||
|
- Sends "Build Complete" notification
|
||||||
|
7. **Flux HelmRelease**:
|
||||||
|
- Detects new `latest` image
|
||||||
|
- Performs rolling update
|
||||||
|
- Sends deployment notification
|
||||||
|
|
||||||
|
## Monitoring
|
||||||
|
|
||||||
|
### Check Webhook Status
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# View Flux receiver status
|
||||||
|
kubectl get receiver neon-vortex-receiver -n flux-system
|
||||||
|
|
||||||
|
# Check build listener
|
||||||
|
kubectl get deployment webhook-build-listener -n default
|
||||||
|
kubectl logs -n default deployment/webhook-build-listener
|
||||||
|
```
|
||||||
|
|
||||||
|
### Monitor Build Jobs
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# List recent build jobs
|
||||||
|
kubectl get jobs -n default -l build-trigger=webhook
|
||||||
|
|
||||||
|
# Watch for new builds
|
||||||
|
kubectl get jobs -n default -w
|
||||||
|
|
||||||
|
# View specific build logs
|
||||||
|
kubectl logs -n default job/<job-name> -c kaniko -f
|
||||||
|
```
|
||||||
|
|
||||||
|
### Check Notifications
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# View notification provider status
|
||||||
|
kubectl get provider neon-vortex-notify -n flux-system
|
||||||
|
|
||||||
|
# Check alert status
|
||||||
|
kubectl get alerts -n flux-system
|
||||||
|
```
|
||||||
|
|
||||||
|
### View Deployment Status
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check HelmRelease
|
||||||
|
flux get helmrelease neon-vortex -n default
|
||||||
|
|
||||||
|
# Check pods
|
||||||
|
kubectl get pods -n default -l app.kubernetes.io/name=neon-vortex
|
||||||
|
|
||||||
|
# Check current image
|
||||||
|
kubectl get deployment neon-vortex -n default -o jsonpath='{.spec.template.spec.containers[0].image}'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing the Pipeline
|
||||||
|
|
||||||
|
### Test Flux Webhook Receiver
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Trigger Flux to reconcile
|
||||||
|
curl -X POST http://<NODE_IP>:30090/hook/548969c2b24c717fe9e5af8c78ddfeec40d3024c270c7e85ac8f986259aeec9a
|
||||||
|
|
||||||
|
# Check if GitRepository reconciled
|
||||||
|
flux get sources git -n flux-system
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test Build Trigger
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Manually trigger a build
|
||||||
|
curl -X POST http://<NODE_IP>:30091/webhook
|
||||||
|
|
||||||
|
# Check for new build job
|
||||||
|
kubectl get jobs -n default -l build-trigger=webhook
|
||||||
|
```
|
||||||
|
|
||||||
|
### Full End-to-End Test
|
||||||
|
|
||||||
|
1. Make a small change to your code
|
||||||
|
2. Commit and push:
|
||||||
|
```bash
|
||||||
|
echo "# Test webhook" >> README.md
|
||||||
|
git add README.md
|
||||||
|
git commit -m "Test webhook pipeline"
|
||||||
|
git push origin main
|
||||||
|
```
|
||||||
|
3. Watch the pipeline:
|
||||||
|
```bash
|
||||||
|
# Watch jobs being created
|
||||||
|
watch kubectl get jobs -n default
|
||||||
|
|
||||||
|
# Check notifications (should receive on your device)
|
||||||
|
# Monitor deployment
|
||||||
|
watch kubectl get helmrelease,deployment,pods -n default
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Webhooks Not Triggering
|
||||||
|
|
||||||
|
1. **Check webhook delivery in Gitea**:
|
||||||
|
- Go to repository → Settings → Webhooks
|
||||||
|
- Click on the webhook
|
||||||
|
- Scroll down to "Recent Deliveries"
|
||||||
|
- Check response codes and errors
|
||||||
|
|
||||||
|
2. **Verify services are accessible**:
|
||||||
|
```bash
|
||||||
|
# Test from within cluster
|
||||||
|
kubectl run -it --rm debug --image=alpine --restart=Never -- sh
|
||||||
|
apk add curl
|
||||||
|
curl -v http://flux-receiver.flux-system.svc.cluster.local/hook/548969c2b24c717fe9e5af8c78ddfeec40d3024c270c7e85ac8f986259aeec9a
|
||||||
|
curl -v http://webhook-build-listener.default.svc.cluster.local:8080/webhook
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Check logs**:
|
||||||
|
```bash
|
||||||
|
# Flux notification controller
|
||||||
|
kubectl logs -n flux-system deployment/notification-controller
|
||||||
|
|
||||||
|
# Build listener
|
||||||
|
kubectl logs -n default deployment/webhook-build-listener
|
||||||
|
```
|
||||||
|
|
||||||
|
### Builds Not Starting
|
||||||
|
|
||||||
|
1. **Check build listener is running**:
|
||||||
|
```bash
|
||||||
|
kubectl get pods -n default -l app=webhook-build-listener
|
||||||
|
kubectl logs -n default -l app=webhook-build-listener
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Verify RBAC permissions**:
|
||||||
|
```bash
|
||||||
|
kubectl get role build-trigger-role -n default
|
||||||
|
kubectl get rolebinding build-trigger-binding -n default
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Check Harbor credentials**:
|
||||||
|
```bash
|
||||||
|
kubectl get secret harbor-registry -n default
|
||||||
|
```
|
||||||
|
|
||||||
|
### Notifications Not Received
|
||||||
|
|
||||||
|
1. **Test notification endpoint**:
|
||||||
|
```bash
|
||||||
|
curl -X POST "https://notify.caffeinetux.com?token=APMvTuncQJmm6vd" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"title":"Test","message":"Testing notifications","priority":3}'
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Check provider status**:
|
||||||
|
```bash
|
||||||
|
kubectl get provider neon-vortex-notify -n flux-system -o yaml
|
||||||
|
kubectl describe alert -n flux-system
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **View notification controller logs**:
|
||||||
|
```bash
|
||||||
|
kubectl logs -n flux-system deployment/notification-controller | grep notify
|
||||||
|
```
|
||||||
|
|
||||||
|
### Build Failures
|
||||||
|
|
||||||
|
1. **Check job status**:
|
||||||
|
```bash
|
||||||
|
kubectl get job <job-name> -n default
|
||||||
|
kubectl describe job <job-name> -n default
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **View build logs**:
|
||||||
|
```bash
|
||||||
|
# Git clone logs
|
||||||
|
kubectl logs job/<job-name> -n default -c git-clone
|
||||||
|
|
||||||
|
# Kaniko build logs
|
||||||
|
kubectl logs job/<job-name> -n default -c kaniko
|
||||||
|
|
||||||
|
# Notification logs
|
||||||
|
kubectl logs job/<job-name> -n default -c notify-completion
|
||||||
|
```
|
||||||
|
|
||||||
|
## Cleanup Old Jobs
|
||||||
|
|
||||||
|
Build jobs are auto-deleted after 1 hour (ttlSecondsAfterFinished: 3600).
|
||||||
|
|
||||||
|
Manual cleanup:
|
||||||
|
```bash
|
||||||
|
# Delete completed jobs
|
||||||
|
kubectl delete jobs -n default -l build-trigger=webhook --field-selector status.successful=1
|
||||||
|
|
||||||
|
# Delete failed jobs
|
||||||
|
kubectl delete jobs -n default -l build-trigger=webhook --field-selector status.failed=1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Disabling Auto-Build
|
||||||
|
|
||||||
|
To temporarily disable automatic builds:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Scale down build listener
|
||||||
|
kubectl scale deployment webhook-build-listener -n default --replicas=0
|
||||||
|
|
||||||
|
# Or suspend the Flux receiver
|
||||||
|
flux suspend receiver neon-vortex-receiver -n flux-system
|
||||||
|
```
|
||||||
|
|
||||||
|
To re-enable:
|
||||||
|
```bash
|
||||||
|
# Scale up build listener
|
||||||
|
kubectl scale deployment webhook-build-listener -n default --replicas=1
|
||||||
|
|
||||||
|
# Or resume Flux receiver
|
||||||
|
flux resume receiver neon-vortex-receiver -n flux-system
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security Notes
|
||||||
|
|
||||||
|
1. **Webhook Secret**: The Flux receiver uses token `neon-vortex-webhook-secret-2024`
|
||||||
|
2. **Notification Token**: Stored in secret `notify-token` in flux-system namespace
|
||||||
|
3. **Harbor Credentials**: Stored in secret `harbor-registry` in default namespace
|
||||||
|
4. **RBAC**: Build trigger has minimal permissions (only manage jobs)
|
||||||
|
|
||||||
|
## Quick Reference
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Status check one-liner
|
||||||
|
kubectl get receiver,provider,alert -n flux-system && kubectl get deployment webhook-build-listener -n default && kubectl get jobs -n default -l build-trigger=webhook
|
||||||
|
|
||||||
|
# Force reconciliation
|
||||||
|
flux reconcile source git neon-vortex -n flux-system
|
||||||
|
|
||||||
|
# Manual build trigger
|
||||||
|
curl -X POST http://<NODE_IP>:30091/webhook
|
||||||
|
|
||||||
|
# Watch everything
|
||||||
|
watch 'kubectl get jobs,pods -n default | grep -E "(build-|neon-vortex)"'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Image Tags
|
||||||
|
|
||||||
|
Each build creates tags:
|
||||||
|
- `latest` - Always points to most recent build
|
||||||
|
- `<short-sha>` - Specific commit (e.g., `e61dc3b`)
|
||||||
|
|
||||||
|
Images also include labels:
|
||||||
|
- `git.commit` - Full commit SHA
|
||||||
|
- `git.short` - Short commit SHA
|
||||||
|
- `git.message` - Commit message
|
||||||
|
- `git.author` - Commit author
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
- Set up staging environment with different image tags
|
||||||
|
- Add automated testing before build
|
||||||
|
- Implement approval workflow for production
|
||||||
|
- Add Slack integration alongside notifications
|
||||||
|
- Set up Prometheus metrics for build success rate
|
||||||
52
flux-alerts.yaml
Normal file
52
flux-alerts.yaml
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
---
|
||||||
|
apiVersion: notification.toolkit.fluxcd.io/v1beta3
|
||||||
|
kind: Alert
|
||||||
|
metadata:
|
||||||
|
name: neon-vortex-git
|
||||||
|
namespace: flux-system
|
||||||
|
spec:
|
||||||
|
summary: "Neon Vortex Git Updates"
|
||||||
|
providerRef:
|
||||||
|
name: neon-vortex-notify
|
||||||
|
eventSeverity: info
|
||||||
|
eventSources:
|
||||||
|
- kind: GitRepository
|
||||||
|
name: neon-vortex
|
||||||
|
namespace: flux-system
|
||||||
|
exclusionList:
|
||||||
|
- ".*health check.*"
|
||||||
|
---
|
||||||
|
apiVersion: notification.toolkit.fluxcd.io/v1beta3
|
||||||
|
kind: Alert
|
||||||
|
metadata:
|
||||||
|
name: neon-vortex-build
|
||||||
|
namespace: flux-system
|
||||||
|
spec:
|
||||||
|
summary: "Neon Vortex Build Status"
|
||||||
|
providerRef:
|
||||||
|
name: neon-vortex-notify
|
||||||
|
eventSeverity: info
|
||||||
|
eventSources:
|
||||||
|
- kind: Kustomization
|
||||||
|
name: neon-vortex-build
|
||||||
|
namespace: flux-system
|
||||||
|
exclusionList:
|
||||||
|
- ".*health check.*"
|
||||||
|
---
|
||||||
|
apiVersion: notification.toolkit.fluxcd.io/v1beta3
|
||||||
|
kind: Alert
|
||||||
|
metadata:
|
||||||
|
name: neon-vortex-deploy
|
||||||
|
namespace: flux-system
|
||||||
|
spec:
|
||||||
|
summary: "Neon Vortex Deployment Status"
|
||||||
|
providerRef:
|
||||||
|
name: neon-vortex-notify
|
||||||
|
eventSeverity: info
|
||||||
|
eventSources:
|
||||||
|
- kind: HelmRelease
|
||||||
|
name: neon-vortex
|
||||||
|
namespace: default
|
||||||
|
exclusionList:
|
||||||
|
- ".*health check.*"
|
||||||
|
- ".*reconciliation in progress.*"
|
||||||
55
flux-build-kustomization.yaml
Normal file
55
flux-build-kustomization.yaml
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
---
|
||||||
|
apiVersion: kustomize.toolkit.fluxcd.io/v1
|
||||||
|
kind: Kustomization
|
||||||
|
metadata:
|
||||||
|
name: neon-vortex-build
|
||||||
|
namespace: flux-system
|
||||||
|
spec:
|
||||||
|
interval: 1m
|
||||||
|
path: ./
|
||||||
|
prune: false
|
||||||
|
sourceRef:
|
||||||
|
kind: GitRepository
|
||||||
|
name: neon-vortex
|
||||||
|
namespace: flux-system
|
||||||
|
targetNamespace: default
|
||||||
|
patches:
|
||||||
|
- patch: |
|
||||||
|
apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
metadata:
|
||||||
|
name: neon-vortex-build
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
git-commit: "${GIT_COMMIT:-unknown}"
|
||||||
|
spec:
|
||||||
|
initContainers:
|
||||||
|
- name: git-clone
|
||||||
|
env:
|
||||||
|
- name: GIT_COMMIT
|
||||||
|
value: "${GIT_COMMIT:-main}"
|
||||||
|
containers:
|
||||||
|
- name: kaniko
|
||||||
|
args:
|
||||||
|
- "--dockerfile=/workspace/htlm/Dockerfile"
|
||||||
|
- "--context=/workspace/htlm"
|
||||||
|
- "--destination=images.caffeinetux.com/apps/neon-vortex:latest"
|
||||||
|
- "--destination=images.caffeinetux.com/apps/neon-vortex:${GIT_COMMIT:-latest}"
|
||||||
|
- "--cache=true"
|
||||||
|
- "--cache-repo=images.caffeinetux.com/apps/neon-vortex/cache"
|
||||||
|
target:
|
||||||
|
kind: Job
|
||||||
|
name: neon-vortex-build
|
||||||
|
postBuild:
|
||||||
|
substituteFrom:
|
||||||
|
- kind: ConfigMap
|
||||||
|
name: git-commit-info
|
||||||
|
optional: true
|
||||||
|
healthChecks:
|
||||||
|
- apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
name: neon-vortex-build
|
||||||
|
namespace: default
|
||||||
197
flux-build-on-push.yaml
Normal file
197
flux-build-on-push.yaml
Normal file
@@ -0,0 +1,197 @@
|
|||||||
|
---
|
||||||
|
# ConfigMap with build script that extracts git commit info
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: build-on-push-script
|
||||||
|
namespace: default
|
||||||
|
data:
|
||||||
|
build.sh: |
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "===== Neon Vortex Build Triggered by Git Push ====="
|
||||||
|
|
||||||
|
# Get latest commit info from git
|
||||||
|
cd /workspace
|
||||||
|
GIT_COMMIT=$(git rev-parse HEAD)
|
||||||
|
GIT_SHORT_COMMIT=$(git rev-parse --short HEAD)
|
||||||
|
GIT_MESSAGE=$(git log -1 --pretty=%B)
|
||||||
|
|
||||||
|
echo "Commit: $GIT_COMMIT"
|
||||||
|
echo "Short: $GIT_SHORT_COMMIT"
|
||||||
|
echo "Message: $GIT_MESSAGE"
|
||||||
|
|
||||||
|
# Create unique job name
|
||||||
|
TIMESTAMP=$(date +%s)
|
||||||
|
JOB_NAME="neon-vortex-build-${GIT_SHORT_COMMIT}-${TIMESTAMP}"
|
||||||
|
|
||||||
|
echo "Creating build job: $JOB_NAME"
|
||||||
|
|
||||||
|
# Create the build job
|
||||||
|
cat <<EOF | kubectl apply -f -
|
||||||
|
apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
metadata:
|
||||||
|
name: $JOB_NAME
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: neon-vortex
|
||||||
|
build-type: webhook
|
||||||
|
git-commit: "$GIT_SHORT_COMMIT"
|
||||||
|
annotations:
|
||||||
|
git-commit-full: "$GIT_COMMIT"
|
||||||
|
git-message: "$GIT_MESSAGE"
|
||||||
|
spec:
|
||||||
|
ttlSecondsAfterFinished: 7200
|
||||||
|
backoffLimit: 1
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: neon-vortex
|
||||||
|
build-type: webhook
|
||||||
|
spec:
|
||||||
|
restartPolicy: Never
|
||||||
|
initContainers:
|
||||||
|
- name: git-clone
|
||||||
|
image: alpine/git:latest
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
echo "Cloning repository..."
|
||||||
|
git clone http://192.168.1.49:13001/admin/neon-vortex.git /workspace
|
||||||
|
cd /workspace
|
||||||
|
git checkout $GIT_COMMIT
|
||||||
|
echo "Checked out commit: $GIT_COMMIT"
|
||||||
|
volumeMounts:
|
||||||
|
- name: workspace
|
||||||
|
mountPath: /workspace
|
||||||
|
containers:
|
||||||
|
- name: kaniko
|
||||||
|
image: gcr.io/kaniko-project/executor:latest
|
||||||
|
args:
|
||||||
|
- "--dockerfile=/workspace/htlm/Dockerfile"
|
||||||
|
- "--context=/workspace/htlm"
|
||||||
|
- "--destination=images.caffeinetux.com/apps/neon-vortex:latest"
|
||||||
|
- "--destination=images.caffeinetux.com/apps/neon-vortex:$GIT_SHORT_COMMIT"
|
||||||
|
- "--cache=true"
|
||||||
|
- "--cache-repo=images.caffeinetux.com/apps/neon-vortex/cache"
|
||||||
|
- "--label=git.commit=$GIT_COMMIT"
|
||||||
|
- "--label=git.message=$GIT_MESSAGE"
|
||||||
|
volumeMounts:
|
||||||
|
- name: workspace
|
||||||
|
mountPath: /workspace
|
||||||
|
- name: docker-config
|
||||||
|
mountPath: /kaniko/.docker
|
||||||
|
volumes:
|
||||||
|
- name: workspace
|
||||||
|
emptyDir: {}
|
||||||
|
- name: docker-config
|
||||||
|
secret:
|
||||||
|
secretName: harbor-registry
|
||||||
|
items:
|
||||||
|
- key: .dockerconfigjson
|
||||||
|
path: config.json
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "Build job $JOB_NAME created successfully!"
|
||||||
|
|
||||||
|
# Send notification
|
||||||
|
curl -X POST https://notify.caffeinetux.com \
|
||||||
|
-H "Authorization: Bearer APMvTuncQJmm6vd" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "{\"title\":\"Neon Vortex Build Started\",\"message\":\"Building commit $GIT_SHORT_COMMIT: $GIT_MESSAGE\",\"priority\":3}" \
|
||||||
|
|| echo "Notification failed (non-critical)"
|
||||||
|
---
|
||||||
|
# Kustomization that triggers on every git push
|
||||||
|
apiVersion: kustomize.toolkit.fluxcd.io/v1
|
||||||
|
kind: Kustomization
|
||||||
|
metadata:
|
||||||
|
name: neon-vortex-build-trigger
|
||||||
|
namespace: flux-system
|
||||||
|
spec:
|
||||||
|
interval: 30s
|
||||||
|
retryInterval: 1m
|
||||||
|
timeout: 5m
|
||||||
|
sourceRef:
|
||||||
|
kind: GitRepository
|
||||||
|
name: neon-vortex
|
||||||
|
namespace: flux-system
|
||||||
|
path: ./
|
||||||
|
prune: false
|
||||||
|
targetNamespace: default
|
||||||
|
postBuild:
|
||||||
|
substitute:
|
||||||
|
TRIGGER_TIME: "{{ .FluxReconcileTime }}"
|
||||||
|
patches:
|
||||||
|
- target:
|
||||||
|
kind: Job
|
||||||
|
name: flux-triggered-build
|
||||||
|
patch: |
|
||||||
|
apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
metadata:
|
||||||
|
name: flux-triggered-build-{{ .FluxReconcileTime | replace ":" "-" | replace "." "-" | lower }}
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
ttlSecondsAfterFinished: 600
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
serviceAccountName: build-trigger-sa
|
||||||
|
restartPolicy: Never
|
||||||
|
containers:
|
||||||
|
- name: trigger-build
|
||||||
|
image: alpine/k8s:1.28.13
|
||||||
|
command: ["/bin/bash", "/scripts/build.sh"]
|
||||||
|
volumeMounts:
|
||||||
|
- name: workspace
|
||||||
|
mountPath: /workspace
|
||||||
|
- name: script
|
||||||
|
mountPath: /scripts
|
||||||
|
volumes:
|
||||||
|
- name: workspace
|
||||||
|
emptyDir: {}
|
||||||
|
- name: script
|
||||||
|
configMap:
|
||||||
|
name: build-on-push-script
|
||||||
|
defaultMode: 0755
|
||||||
|
---
|
||||||
|
# Job template (will be created by Kustomization on each reconcile)
|
||||||
|
apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
metadata:
|
||||||
|
name: flux-triggered-build
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
ttlSecondsAfterFinished: 600
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
serviceAccountName: build-trigger-sa
|
||||||
|
restartPolicy: Never
|
||||||
|
containers:
|
||||||
|
- name: trigger-build
|
||||||
|
image: alpine/k8s:1.28.13
|
||||||
|
command:
|
||||||
|
- /bin/bash
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
apk add --no-cache git curl
|
||||||
|
|
||||||
|
echo "Cloning repository to check for changes..."
|
||||||
|
git clone http://192.168.1.49:13001/admin/neon-vortex.git /workspace
|
||||||
|
cd /workspace
|
||||||
|
|
||||||
|
/scripts/build.sh
|
||||||
|
volumeMounts:
|
||||||
|
- name: workspace
|
||||||
|
mountPath: /workspace
|
||||||
|
- name: script
|
||||||
|
mountPath: /scripts
|
||||||
|
volumes:
|
||||||
|
- name: workspace
|
||||||
|
emptyDir: {}
|
||||||
|
- name: script
|
||||||
|
configMap:
|
||||||
|
name: build-on-push-script
|
||||||
|
defaultMode: 0755
|
||||||
20
flux-notification-provider.yaml
Normal file
20
flux-notification-provider.yaml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: notify-token
|
||||||
|
namespace: flux-system
|
||||||
|
type: Opaque
|
||||||
|
stringData:
|
||||||
|
token: "APMvTuncQJmm6vd"
|
||||||
|
---
|
||||||
|
apiVersion: notification.toolkit.fluxcd.io/v1beta3
|
||||||
|
kind: Provider
|
||||||
|
metadata:
|
||||||
|
name: neon-vortex-notify
|
||||||
|
namespace: flux-system
|
||||||
|
spec:
|
||||||
|
type: generic
|
||||||
|
address: https://notify.caffeinetux.com
|
||||||
|
secretRef:
|
||||||
|
name: notify-token
|
||||||
40
flux-webhook-receiver.yaml
Normal file
40
flux-webhook-receiver.yaml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: gitea-webhook-token
|
||||||
|
namespace: flux-system
|
||||||
|
type: Opaque
|
||||||
|
stringData:
|
||||||
|
token: "neon-vortex-webhook-secret-2024"
|
||||||
|
---
|
||||||
|
apiVersion: notification.toolkit.fluxcd.io/v1
|
||||||
|
kind: Receiver
|
||||||
|
metadata:
|
||||||
|
name: neon-vortex-receiver
|
||||||
|
namespace: flux-system
|
||||||
|
spec:
|
||||||
|
type: generic
|
||||||
|
secretRef:
|
||||||
|
name: gitea-webhook-token
|
||||||
|
resources:
|
||||||
|
- apiVersion: source.toolkit.fluxcd.io/v1
|
||||||
|
kind: GitRepository
|
||||||
|
name: neon-vortex
|
||||||
|
namespace: flux-system
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: flux-receiver
|
||||||
|
namespace: flux-system
|
||||||
|
spec:
|
||||||
|
type: NodePort
|
||||||
|
selector:
|
||||||
|
app: notification-controller
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 80
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: 9292
|
||||||
|
nodePort: 30090
|
||||||
@@ -92,7 +92,6 @@ body {
|
|||||||
</style>
|
</style>
|
||||||
<link id="-gd-engine-icon" rel="icon" type="image/png" href="Neon Vortex.icon.png" />
|
<link id="-gd-engine-icon" rel="icon" type="image/png" href="Neon Vortex.icon.png" />
|
||||||
<link rel="apple-touch-icon" href="Neon Vortex.apple-touch-icon.png"/>
|
<link rel="apple-touch-icon" href="Neon Vortex.apple-touch-icon.png"/>
|
||||||
<link rel="manifest" href="Neon Vortex.manifest.json">
|
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -112,8 +111,8 @@ body {
|
|||||||
|
|
||||||
<script src="Neon Vortex.js"></script>
|
<script src="Neon Vortex.js"></script>
|
||||||
<script>
|
<script>
|
||||||
const GODOT_CONFIG = {"args":[],"canvasResizePolicy":2,"emscriptenPoolSize":8,"ensureCrossOriginIsolationHeaders":true,"executable":"Neon Vortex","experimentalVK":true,"fileSizes":{"Neon Vortex.pck":256776,"Neon Vortex.wasm":1660816},"focusCanvas":true,"gdextensionLibs":[],"godotPoolSize":4,"serviceWorker":"Neon Vortex.service.worker.js"};
|
const GODOT_CONFIG = {"args":[],"canvasResizePolicy":2,"emscriptenPoolSize":8,"ensureCrossOriginIsolationHeaders":false,"executable":"Neon Vortex","experimentalVK":true,"fileSizes":{"Neon Vortex.pck":256728,"Neon Vortex.wasm":36160334},"focusCanvas":true,"gdextensionLibs":[],"godotPoolSize":4};
|
||||||
const GODOT_THREADS_ENABLED = true;
|
const GODOT_THREADS_ENABLED = false;
|
||||||
const engine = new Engine(GODOT_CONFIG);
|
const engine = new Engine(GODOT_CONFIG);
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
223
webhook-build-trigger.yaml
Normal file
223
webhook-build-trigger.yaml
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: webhook-build-script
|
||||||
|
namespace: default
|
||||||
|
data:
|
||||||
|
trigger-build.sh: |
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "===== Git Push Detected - Triggering Build ====="
|
||||||
|
date
|
||||||
|
|
||||||
|
# Clone the repository
|
||||||
|
echo "Cloning repository..."
|
||||||
|
git clone http://192.168.1.49:13001/admin/neon-vortex.git /tmp/repo
|
||||||
|
cd /tmp/repo
|
||||||
|
|
||||||
|
# Get commit info
|
||||||
|
GIT_COMMIT=$(git rev-parse HEAD)
|
||||||
|
GIT_SHORT=$(git rev-parse --short HEAD)
|
||||||
|
GIT_MSG=$(git log -1 --pretty=%B | head -1)
|
||||||
|
GIT_AUTHOR=$(git log -1 --pretty=%an)
|
||||||
|
|
||||||
|
echo "Commit: $GIT_SHORT ($GIT_COMMIT)"
|
||||||
|
echo "Author: $GIT_AUTHOR"
|
||||||
|
echo "Message: $GIT_MSG"
|
||||||
|
|
||||||
|
# Generate unique job name
|
||||||
|
TIMESTAMP=$(date +%s)
|
||||||
|
JOB_NAME="build-${GIT_SHORT}-${TIMESTAMP}"
|
||||||
|
|
||||||
|
echo "Creating build job: $JOB_NAME"
|
||||||
|
|
||||||
|
# Send start notification
|
||||||
|
curl -s -X POST "https://notify.caffeinetux.com?token=APMvTuncQJmm6vd" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "{
|
||||||
|
\"title\": \"🔨 Neon Vortex Build Started\",
|
||||||
|
\"message\": \"Commit: ${GIT_SHORT} by ${GIT_AUTHOR}\\n${GIT_MSG}\",
|
||||||
|
\"priority\": 3,
|
||||||
|
\"tags\": [\"building\"]
|
||||||
|
}" || echo "Notification failed"
|
||||||
|
|
||||||
|
# Create the build job
|
||||||
|
kubectl apply -f - <<EOF
|
||||||
|
apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
metadata:
|
||||||
|
name: $JOB_NAME
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: neon-vortex
|
||||||
|
build-trigger: webhook
|
||||||
|
git-commit: "$GIT_SHORT"
|
||||||
|
annotations:
|
||||||
|
git-commit-full: "$GIT_COMMIT"
|
||||||
|
git-message: "$GIT_MSG"
|
||||||
|
git-author: "$GIT_AUTHOR"
|
||||||
|
spec:
|
||||||
|
ttlSecondsAfterFinished: 3600
|
||||||
|
backoffLimit: 0
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: neon-vortex
|
||||||
|
build-job: "true"
|
||||||
|
spec:
|
||||||
|
restartPolicy: Never
|
||||||
|
initContainers:
|
||||||
|
- name: git-clone
|
||||||
|
image: alpine/git:latest
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
set -e
|
||||||
|
echo "Cloning and checking out $GIT_COMMIT..."
|
||||||
|
git clone http://192.168.1.49:13001/admin/neon-vortex.git /workspace
|
||||||
|
cd /workspace
|
||||||
|
git checkout $GIT_COMMIT
|
||||||
|
echo "Repository ready for build"
|
||||||
|
env:
|
||||||
|
- name: GIT_COMMIT
|
||||||
|
value: "$GIT_COMMIT"
|
||||||
|
volumeMounts:
|
||||||
|
- name: workspace
|
||||||
|
mountPath: /workspace
|
||||||
|
containers:
|
||||||
|
- name: kaniko
|
||||||
|
image: gcr.io/kaniko-project/executor:latest
|
||||||
|
args:
|
||||||
|
- "--dockerfile=/workspace/htlm/Dockerfile"
|
||||||
|
- "--context=/workspace/htlm"
|
||||||
|
- "--destination=images.caffeinetux.com/apps/neon-vortex:latest"
|
||||||
|
- "--destination=images.caffeinetux.com/apps/neon-vortex:$GIT_SHORT"
|
||||||
|
- "--cache=true"
|
||||||
|
- "--cache-repo=images.caffeinetux.com/apps/neon-vortex/cache"
|
||||||
|
- "--label=git.commit=$GIT_COMMIT"
|
||||||
|
- "--label=git.short=$GIT_SHORT"
|
||||||
|
- "--label=git.message=$GIT_MSG"
|
||||||
|
- "--label=git.author=$GIT_AUTHOR"
|
||||||
|
volumeMounts:
|
||||||
|
- name: workspace
|
||||||
|
mountPath: /workspace
|
||||||
|
- name: docker-config
|
||||||
|
mountPath: /kaniko/.docker
|
||||||
|
- name: notify-completion
|
||||||
|
image: alpine:latest
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
set -e
|
||||||
|
apk add --no-cache curl
|
||||||
|
|
||||||
|
echo "Waiting for Kaniko to complete..."
|
||||||
|
sleep 10
|
||||||
|
|
||||||
|
# Send completion notification
|
||||||
|
curl -s -X POST "https://notify.caffeinetux.com?token=APMvTuncQJmm6vd" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "{
|
||||||
|
\"title\": \"✅ Neon Vortex Build Complete\",
|
||||||
|
\"message\": \"Image built successfully for commit ${GIT_SHORT}\\nDeployment will update automatically\",
|
||||||
|
\"priority\": 3,
|
||||||
|
\"tags\": [\"success\",\"deployed\"]
|
||||||
|
}"
|
||||||
|
|
||||||
|
echo "Completion notification sent"
|
||||||
|
env:
|
||||||
|
- name: GIT_SHORT
|
||||||
|
value: "$GIT_SHORT"
|
||||||
|
volumes:
|
||||||
|
- name: workspace
|
||||||
|
emptyDir: {}
|
||||||
|
- name: docker-config
|
||||||
|
secret:
|
||||||
|
secretName: harbor-registry
|
||||||
|
items:
|
||||||
|
- key: .dockerconfigjson
|
||||||
|
path: config.json
|
||||||
|
EOF
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "✅ Build job $JOB_NAME created successfully"
|
||||||
|
else
|
||||||
|
echo "❌ Failed to create build job"
|
||||||
|
curl -s -X POST "https://notify.caffeinetux.com?token=APMvTuncQJmm6vd" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "{
|
||||||
|
\"title\": \"❌ Neon Vortex Build Failed\",
|
||||||
|
\"message\": \"Failed to create build job for commit ${GIT_SHORT}\",
|
||||||
|
\"priority\": 5,
|
||||||
|
\"tags\": [\"error\"]
|
||||||
|
}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: webhook-build-listener
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: webhook-build-listener
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: webhook-build-listener
|
||||||
|
spec:
|
||||||
|
serviceAccountName: build-trigger-sa
|
||||||
|
containers:
|
||||||
|
- name: listener
|
||||||
|
image: alpine:latest
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
apk add --no-cache socat bash git curl
|
||||||
|
|
||||||
|
echo "Starting webhook listener on port 8080..."
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
echo "Waiting for webhook trigger..."
|
||||||
|
echo -e "HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nOK" | \
|
||||||
|
socat TCP-LISTEN:8080,reuseaddr,fork STDIO | \
|
||||||
|
while read line; do
|
||||||
|
if echo "$line" | grep -q "POST /webhook"; then
|
||||||
|
echo "Webhook received! Triggering build..."
|
||||||
|
/scripts/trigger-build.sh &
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
volumeMounts:
|
||||||
|
- name: script
|
||||||
|
mountPath: /scripts
|
||||||
|
volumes:
|
||||||
|
- name: script
|
||||||
|
configMap:
|
||||||
|
name: webhook-build-script
|
||||||
|
defaultMode: 0755
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: webhook-build-listener
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
type: NodePort
|
||||||
|
selector:
|
||||||
|
app: webhook-build-listener
|
||||||
|
ports:
|
||||||
|
- port: 8080
|
||||||
|
targetPort: 8080
|
||||||
|
nodePort: 30091
|
||||||
|
name: webhook
|
||||||
Reference in New Issue
Block a user