Adds gitea configuration

This commit is contained in:
2026-03-29 05:34:40 -04:00
parent f73aa118ac
commit 2bb1dfa1e4
10 changed files with 656 additions and 209 deletions

View File

@@ -0,0 +1,92 @@
name: Build and Deploy
on:
push:
tags:
- 'v*.*.*'
workflow_dispatch:
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Extract version from tag
id: version
run: |
if [[ "${{ github.ref }}" =~ ^refs/tags/v(.*)$ ]]; then
echo "version=${BASH_REMATCH[1]}" >> $GITHUB_OUTPUT
echo "tag=${BASH_REMATCH[0]#refs/tags/}" >> $GITHUB_OUTPUT
else
echo "version=latest" >> $GITHUB_OUTPUT
echo "tag=latest" >> $GITHUB_OUTPUT
fi
- name: Log in to Gitea Container Registry
uses: docker/login-action@v3
with:
registry: gitea.kazcloud.dev
username: ${{ github.actor }}
password: ${{ secrets.GITEA_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
gitea.kazcloud.dev/ryankazokas/turbovault-app:${{ steps.version.outputs.tag }}
gitea.kazcloud.dev/ryankazokas/turbovault-app:latest
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Deploy to Kubernetes
env:
KUBECONFIG_CONTENT: ${{ secrets.KUBECONFIG }}
run: |
# Setup kubectl
mkdir -p ~/.kube
echo "$KUBECONFIG_CONTENT" | base64 -d > ~/.kube/config
chmod 600 ~/.kube/config
# Deploy
echo "🚀 Deploying version ${{ steps.version.outputs.tag }} to Kubernetes..."
kubectl set image deployment/turbovault \
turbovault=gitea.kazcloud.dev/ryankazokas/turbovault-app:${{ steps.version.outputs.tag }} \
-n turbovault
# Wait for rollout
kubectl rollout status deployment/turbovault -n turbovault --timeout=5m
echo "✅ Deployment complete!"
# Show current pods
kubectl get pods -n turbovault -l app=turbovault
- name: Deployment summary
if: success()
run: |
echo "✅ Build and deployment successful!"
echo ""
echo "📦 Image: gitea.kazcloud.dev/ryankazokas/turbovault-app:${{ steps.version.outputs.tag }}"
echo "🚀 Deployed to: turbovault namespace"
echo ""
echo "View logs:"
echo "kubectl logs -f -l app=turbovault -n turbovault"
- name: Rollback on failure
if: failure()
env:
KUBECONFIG_CONTENT: ${{ secrets.KUBECONFIG }}
run: |
echo "❌ Deployment failed! Rolling back..."
mkdir -p ~/.kube
echo "$KUBECONFIG_CONTENT" | base64 -d > ~/.kube/config
kubectl rollout undo deployment/turbovault -n turbovault || true
echo "⚠️ Attempted rollback. Check cluster status manually."

View File

@@ -1,78 +0,0 @@
name: Build and Push Docker Image
on:
# Trigger on version tags
push:
tags:
- 'v*.*.*'
# Allow manual triggering
workflow_dispatch:
inputs:
tag:
description: 'Image tag (e.g., v1.0.0 or latest)'
required: true
default: 'latest'
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Determine image tag
id: tag
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "tag=${{ github.event.inputs.tag }}" >> $GITHUB_OUTPUT
else
echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
fi
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=ref,event=branch
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Image pushed successfully
run: |
echo "✅ Image built and pushed!"
echo "📦 Image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.tag.outputs.tag }}"
echo ""
echo "🚀 Deploy to Kubernetes:"
echo "kubectl set image deployment/turbovault turbovault=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.tag.outputs.tag }} -n turbovault"

View File

@@ -1,124 +0,0 @@
name: CI
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
jobs:
lint:
name: Linting & Security
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.3'
bundler-cache: true
- name: Run RuboCop (style/linting)
run: bundle exec rubocop --parallel --format progress
- name: Run Brakeman (security scan)
run: bundle exec brakeman -q --no-pager
continue-on-error: true # Security warnings shouldn't block PRs
typecheck:
name: Type Checking
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.3'
bundler-cache: true
- name: Generate Sorbet RBI files
run: |
bundle exec tapioca gems --no-doc --workers 1
bundle exec tapioca dsl
- name: Run Sorbet type checker
run: bundle exec srb tc
test:
name: Tests
runs-on: ubuntu-latest
services:
postgres:
image: postgres:15
env:
POSTGRES_USER: turbovault
POSTGRES_PASSWORD: postgres
POSTGRES_DB: turbovault_test
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
DATABASE_HOST: localhost
DATABASE_USERNAME: turbovault
DATABASE_PASSWORD: postgres
DATABASE_NAME: turbovault_test
RAILS_ENV: test
RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.3'
bundler-cache: true
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y libpq-dev
- name: Setup database
run: |
bundle exec rails db:create
bundle exec rails db:schema:load
- name: Run tests
run: bundle exec rails test
- name: Report test results
if: always()
run: echo "✅ Tests completed"
build-test:
name: Docker Build
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build Docker image (test)
run: docker build -t turbovault:test .
- name: Test Docker image
run: |
docker run --rm turbovault:test bundle exec ruby --version
echo "✅ Docker image builds successfully"

View File

@@ -3,7 +3,7 @@
> Your personal video game collection tracker
[![Rails 8.1](https://img.shields.io/badge/Rails-8.1-red.svg)](https://rubyonrails.org/)
![CI](https://github.com/ryankazokas/turbovault-app/workflows/CI/badge.svg)
[![Gitea](https://img.shields.io/badge/hosted-Gitea-609926.svg)](https://gitea.kazcloud.dev/ryankazokas/turbovault-app)
Track your physical and digital game collection with automatic metadata from IGDB.

202
docs/GITEA_SECRETS.md Normal file
View File

@@ -0,0 +1,202 @@
# Gitea Secrets Configuration
This document explains what secrets you need to configure in Gitea for automatic builds and deployments.
## Required Secrets
### 1. GITEA_TOKEN
**Purpose:** Allows Gitea Actions to push Docker images to Gitea Container Registry
**How to create:**
1. Go to Gitea → **Settings****Applications**
2. Under **"Generate New Token"**, enter name: `gitea-actions`
3. Select scopes:
-`write:package` (push container images)
-`read:package` (pull container images)
4. Click **"Generate Token"**
5. Copy the token (starts with `glpat-...` or similar)
**How to add to repository:**
1. Go to your Gitea repository: `gitea.kazcloud.dev/ryankazokas/turbovault-app`
2. Click **Settings****Secrets**
3. Click **"Add Secret"**
4. Name: `GITEA_TOKEN`
5. Value: Paste the token you copied
6. Click **"Add Secret"**
---
### 2. KUBECONFIG
**Purpose:** Allows Gitea Actions to deploy to your Kubernetes cluster
**How to create:**
```bash
# Export your kubeconfig as base64
cat ~/.kube/config | base64 -w 0 > kubeconfig-base64.txt
# Copy the contents of kubeconfig-base64.txt
cat kubeconfig-base64.txt
```
**How to add to repository:**
1. Go to your Gitea repository: `gitea.kazcloud.dev/ryankazokas/turbovault-app`
2. Click **Settings****Secrets**
3. Click **"Add Secret"**
4. Name: `KUBECONFIG`
5. Value: Paste the base64-encoded kubeconfig
6. Click **"Add Secret"**
**⚠️ Security Note:** This gives Gitea Actions full access to your Kubernetes cluster. Only add this to trusted repositories!
---
## Optional: Scoped Kubeconfig (More Secure)
Instead of using your full kubeconfig, create a limited service account:
```bash
# Create service account for deployments
kubectl create serviceaccount turbovault-deployer -n turbovault
# Create role with deployment permissions
cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: turbovault-deployer
namespace: turbovault
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "patch", "update"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
- apiGroups: ["apps"]
resources: ["deployments/status"]
verbs: ["get"]
EOF
# Bind role to service account
kubectl create rolebinding turbovault-deployer \
--role=turbovault-deployer \
--serviceaccount=turbovault:turbovault-deployer \
-n turbovault
# Get service account token
kubectl create token turbovault-deployer -n turbovault --duration=87600h > token.txt
# Create minimal kubeconfig
cat <<EOF > deployer-kubeconfig.yaml
apiVersion: v1
kind: Config
clusters:
- cluster:
server: https://100.101.31.99:6443
# Add certificate-authority-data from your main kubeconfig if needed
insecure-skip-tls-verify: true
name: k3s
contexts:
- context:
cluster: k3s
namespace: turbovault
user: turbovault-deployer
name: k3s
current-context: k3s
users:
- name: turbovault-deployer
user:
token: $(cat token.txt)
EOF
# Encode for Gitea
cat deployer-kubeconfig.yaml | base64 -w 0 > deployer-kubeconfig-base64.txt
# Use this in KUBECONFIG secret instead
cat deployer-kubeconfig-base64.txt
```
This limits Gitea Actions to only deploying TurboVault, not full cluster access.
---
## Verifying Secrets
After adding secrets, you can verify they're set:
1. Go to repository → **Settings****Secrets**
2. You should see:
- `GITEA_TOKEN`
- `KUBECONFIG`
**Note:** You can't view secret values after creation (security feature).
---
## Testing the Workflow
After secrets are configured:
```bash
# Create a test tag
git tag v0.0.1-test
git push origin v0.0.1-test
```
Watch the workflow at:
`gitea.kazcloud.dev/ryankazokas/turbovault-app/actions`
The workflow should:
1. ✅ Build Docker image
2. ✅ Push to Gitea registry
3. ✅ Deploy to Kubernetes
4. ✅ Wait for rollout to complete
---
## Troubleshooting
### "Error: authentication required"
- Check `GITEA_TOKEN` is set and has `write:package` scope
### "Error: Unable to connect to the server"
- Check `KUBECONFIG` secret is set correctly
- Verify base64 encoding (no line breaks with `-w 0`)
- Test kubeconfig works locally: `kubectl --kubeconfig=<file> get pods -n turbovault`
### "Error: deployment not found"
- Make sure initial deployment is done first: `./scripts/deploy-k8s.sh`
- Workflow only updates existing deployments, doesn't create them
---
## Security Best Practices
**DO:**
- Use service account with minimal permissions (Role, not ClusterRole)
- Rotate tokens regularly
- Only add secrets to repositories you control
**DON'T:**
- Share secrets in code or documentation
- Use admin kubeconfig if possible
- Commit secrets to git
---
## Summary
**Two secrets required:**
1. **GITEA_TOKEN** - For pushing container images
2. **KUBECONFIG** - For deploying to Kubernetes
Both added at: `gitea.kazcloud.dev/ryankazokas/turbovault-app/settings/secrets`
After setup, just push tags to trigger automatic builds and deployments! 🚀

323
docs/GITEA_WORKFLOW.md Normal file
View File

@@ -0,0 +1,323 @@
# Gitea CI/CD Workflow
## Overview
TurboVault uses Gitea Actions for fully automated builds and deployments:
1. **Push code to GitHub** (primary repository)
2. **Gitea mirrors** from GitHub automatically
3. **Gitea Actions** builds Docker image and deploys to Kubernetes
All automatic! 🚀
---
## Setup (One-Time)
### 1. Mirror GitHub Repository to Gitea
In Gitea:
1. Go to `gitea.kazcloud.dev`**New Repository**
2. Choose **"New Migration"** → **"GitHub"**
3. URL: `https://github.com/ryankazokas/turbovault-app`
4. Enable **"This repository will be a mirror"**
5. Set sync interval: **10 minutes** (or setup webhook for instant sync)
6. Click **"Migrate Repository"**
**Webhook for instant sync (optional):**
- In GitHub repo → Settings → Webhooks → Add webhook
- Payload URL: `https://gitea.kazcloud.dev/ryankazokas/turbovault-app/mirror-sync`
- Content type: `application/json`
- Events: Just the push event
### 2. Configure Gitea Secrets
See [GITEA_SECRETS.md](GITEA_SECRETS.md) for detailed instructions.
**Required secrets:**
- `GITEA_TOKEN` - For pushing images to registry
- `KUBECONFIG` - For deploying to Kubernetes
Add at: `gitea.kazcloud.dev/ryankazokas/turbovault-app/settings/secrets`
### 3. Initial Deployment to Kubernetes
Before automation works, do initial deployment:
```bash
# Build and push first image
docker build -t gitea.kazcloud.dev/ryankazokas/turbovault-app:v1.0.0 .
docker login gitea.kazcloud.dev
docker push gitea.kazcloud.dev/ryankazokas/turbovault-app:v1.0.0
# Configure secrets and database
cp k8s/secrets.yaml.example k8s/secrets.yaml
nano k8s/secrets.yaml # Add SECRET_KEY_BASE, DATABASE_PASSWORD, etc.
nano k8s/configmap.yaml # Add DATABASE_HOST, etc.
# Deploy to Kubernetes
./scripts/deploy-k8s.sh
```
When script asks for registry credentials:
- Registry: `gitea.kazcloud.dev`
- Username: `ryankazokas`
- Password: `<your-gitea-token>`
---
## Daily Workflow
After setup, deployments are fully automatic:
```bash
# 1. Make changes in GitHub
git add .
git commit -m "Feature: add new functionality"
git push origin main
# 2. When ready to deploy, create version tag
git tag v1.0.1
git push origin v1.0.1
# 3. That's it! ✅
# Gitea auto-syncs → builds → deploys to Kubernetes
```
**Watch build and deployment:**
`https://gitea.kazcloud.dev/ryankazokas/turbovault-app/actions`
---
## How It Works
```
GitHub (code)
↓ (mirror sync)
Gitea (code mirror)
↓ (on tag push)
Gitea Actions:
1. Build Docker image
2. Push to gitea.kazcloud.dev registry
3. Deploy to Kubernetes (kubectl)
4. Wait for rollout
5. Show status
Kubernetes pulls image and updates deployment ✅
```
---
## Workflow Features
### ✅ Automatic Rollout Status
Workflow waits for rollout to complete before marking as success.
### ✅ Automatic Rollback on Failure
If deployment fails, workflow automatically rolls back to previous version.
### ✅ Multiple Tags
Each version gets two tags:
- `v1.0.0` (specific version)
- `latest` (always points to most recent)
### ✅ Manual Trigger
Can manually trigger builds via Gitea Actions UI if needed.
---
## Manual Deployment (If Needed)
If you want to deploy manually without waiting for Gitea sync:
```bash
# Build and push
docker build -t gitea.kazcloud.dev/ryankazokas/turbovault-app:v1.0.1 .
docker push gitea.kazcloud.dev/ryankazokas/turbovault-app:v1.0.1
# Deploy
./scripts/update-deployment.sh v1.0.1
```
---
## Version Management
### Semantic Versioning
Use semantic versioning for tags:
- `v1.0.0` - Major.Minor.Patch
- `v1.0.1` - Patch update (bug fixes)
- `v1.1.0` - Minor update (new features)
- `v2.0.0` - Major update (breaking changes)
### Viewing Deployed Version
```bash
# Check current image
kubectl get deployment turbovault -n turbovault -o jsonpath='{.spec.template.spec.containers[0].image}'
# Check all pods
kubectl get pods -n turbovault -l app=turbovault
```
---
## Troubleshooting
### Workflow Fails at "Build and push"
**Issue:** Can't push to registry
**Fix:**
- Check `GITEA_TOKEN` secret is set
- Verify token has `write:package` scope
- Test: `docker login gitea.kazcloud.dev` with token
### Workflow Fails at "Deploy to Kubernetes"
**Issue:** Can't connect to Kubernetes
**Fix:**
- Check `KUBECONFIG` secret is set correctly
- Verify base64 encoding: `echo "$SECRET" | base64 -d | kubectl --kubeconfig=/dev/stdin get nodes`
- Check cluster is reachable from Gitea Actions runner
### Deployment Succeeds but Pods Not Starting
**Issue:** Image pull errors or configuration issues
**Check:**
```bash
kubectl get pods -n turbovault
kubectl describe pod <pod-name> -n turbovault
kubectl logs <pod-name> -n turbovault
```
**Common causes:**
- Image pull secret not configured (run `./scripts/deploy-k8s.sh` again)
- Database connection issues (check `k8s/configmap.yaml` and `k8s/secrets.yaml`)
- Missing environment variables
---
## Monitoring Deployments
### Watch Live Deployment
```bash
# Watch pods update
kubectl get pods -n turbovault -w
# Watch rollout status
kubectl rollout status deployment/turbovault -n turbovault
# View logs
kubectl logs -f -l app=turbovault -n turbovault
```
### Deployment History
```bash
# View rollout history
kubectl rollout history deployment/turbovault -n turbovault
# View specific revision
kubectl rollout history deployment/turbovault --revision=2 -n turbovault
```
---
## Rollback
### Automatic Rollback
Workflow automatically rolls back if deployment fails.
### Manual Rollback
```bash
# Rollback to previous version
kubectl rollout undo deployment/turbovault -n turbovault
# Rollback to specific revision
kubectl rollout undo deployment/turbovault --to-revision=3 -n turbovault
```
---
## Security Considerations
### Secrets Management
- All secrets in Gitea are encrypted
- Secrets never appear in logs
- Use service account kubeconfig (not admin)
### Network Security
- Gitea Actions runners on internal network
- Can reach Kubernetes API (not exposed publicly)
- Images pulled from internal registry
### Access Control
- Only repository collaborators can trigger workflows
- Gitea token scoped to package registry only
- Kubeconfig scoped to turbovault namespace only (recommended)
---
## Advanced: Staging vs Production
To add staging environment:
1. Create `v*.*.*-rc*` tags for release candidates
2. Deploy to staging namespace
3. Update workflow to detect RC tags:
```yaml
- name: Determine environment
id: env
run: |
if [[ "${{ github.ref }}" =~ -rc ]]; then
echo "namespace=turbovault-staging" >> $GITHUB_OUTPUT
else
echo "namespace=turbovault" >> $GITHUB_OUTPUT
fi
```
---
## Quick Reference
```bash
# Deploy new version
git tag v1.0.1
git push origin v1.0.1
# Watch deployment
kubectl get pods -n turbovault -w
# View logs
kubectl logs -f -l app=turbovault -n turbovault
# Rollback if needed
kubectl rollout undo deployment/turbovault -n turbovault
# Check current version
kubectl get deployment turbovault -n turbovault -o jsonpath='{.spec.template.spec.containers[0].image}'
```
---
## Summary
**Setup once:**
1. Mirror GitHub → Gitea
2. Add Gitea secrets (GITEA_TOKEN, KUBECONFIG)
3. Initial deployment with `./scripts/deploy-k8s.sh`
**Daily workflow:**
1. Push code to GitHub
2. Create version tag
3. Everything else is automatic! ✅
Questions? Check [GITEA_SECRETS.md](GITEA_SECRETS.md) for secret configuration details.

View File

@@ -9,7 +9,7 @@ data:
RAILS_SERVE_STATIC_FILES: "true"
RAILS_MAX_THREADS: "5"
# Update these values for your environment
DATABASE_HOST: "postgres-service" # Your PostgreSQL service name or external host
DATABASE_HOST: "db.rbeowfzliacsawrziniv.supabase.co" # Your PostgreSQL service name or external host
DATABASE_PORT: "5432"
DATABASE_NAME: "turbovault_production"
DATABASE_USERNAME: "turbovault"
DATABASE_NAME: "postgres"
DATABASE_USERNAME: "postgres"

View File

@@ -28,10 +28,10 @@ spec:
- name: turbovault
# UPDATE THIS: Replace with your registry path
# Examples:
# - Gitea: gitea.kazcloud.dev/ryankazokas/turbovault-app:latest
# - GitHub Container Registry: ghcr.io/ryankazokas/turbovault-app:latest
# - Docker Hub: docker.io/username/turbovault:latest
# - Private registry: registry.example.com/turbovault:latest
image: ghcr.io/ryankazokas/turbovault-app:latest
image: gitea.kazcloud.dev/ryankazokas/turbovault-app:latest
imagePullPolicy: Always
ports:
- containerPort: 3000

View File

@@ -20,7 +20,7 @@ spec:
containers:
- name: migrate
# UPDATE THIS: Replace with your registry path (same as deployment.yaml)
image: ghcr.io/ryankazokas/turbovault-app:latest
image: gitea.kazcloud.dev/ryankazokas/turbovault-app:latest
command: ["bundle", "exec", "rails", "db:migrate"]
env:
# Load from ConfigMap

32
scripts/update-deployment.sh Executable file
View File

@@ -0,0 +1,32 @@
#!/bin/bash
set -e
# Update TurboVault deployment with new image version
# Usage: ./scripts/update-deployment.sh v1.0.1
VERSION=${1:-latest}
IMAGE="gitea.kazcloud.dev/ryankazokas/turbovault-app:${VERSION}"
NAMESPACE="turbovault"
echo "🚀 Updating TurboVault deployment to ${VERSION}..."
echo ""
# Update deployment
kubectl set image deployment/turbovault \
turbovault=${IMAGE} \
-n ${NAMESPACE}
echo "✅ Deployment updated to: ${IMAGE}"
echo ""
echo "⏳ Watching rollout status..."
kubectl rollout status deployment/turbovault -n ${NAMESPACE}
echo ""
echo "✅ Deployment complete!"
echo ""
echo "📊 Current pods:"
kubectl get pods -n ${NAMESPACE} -l app=turbovault
echo ""
echo "📝 View logs:"
echo "kubectl logs -f -l app=turbovault -n ${NAMESPACE}"