📝 docs: update comprehensive documentation and project infrastructure

Documentation Updates:
- Enhanced AGENTS.md with user authentication details
- Updated README.md with authentication API documentation
- Added CONTRIBUTING.md guidelines for BDD testing
- Version management guide improvements
- Local CI/CD testing documentation

Project Infrastructure:
- Updated .gitignore for new file patterns
- Enhanced git hooks documentation
- YAML linting configuration
- Script improvements and organization
- Configuration management updates

API Enhancements:
- Greet service integration with authentication
- Server middleware for JWT validation
- Telemetry improvements
- Version management utilities

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
2026-04-09 00:26:15 +02:00
parent 30af706590
commit c1e628f339
39 changed files with 1230 additions and 1187 deletions

215
scripts/LOCAL_CI_GUIDE.md Normal file
View File

@@ -0,0 +1,215 @@
# Local CI/CD Testing Guide
This guide explains how to test the CI/CD pipeline locally using the available scripts.
## 📁 Available Scripts
### Core CI Scripts
- `test-local-ci-cd.sh` - Complete local CI/CD simulation
- `test-docker-cache.sh` - Test Docker build cache functionality
- `ci-update-coverage-badge.sh` - Test coverage badge updates
- `ci-version-bump.sh` - Test version bump logic
### Existing Test Scripts
- `run-bdd-tests.sh` - Run BDD tests locally
- `test-graceful-shutdown.sh` - Test graceful shutdown
- `test-opentelemetry.sh` - Test OpenTelemetry integration
## 🚀 Quick Start
### 1. Test Docker Build Cache
```bash
# Test the Docker cache functionality
./scripts/test-docker-cache.sh
# This will:
# 1. Calculate dependency hash (same as CI)
# 2. Build Docker cache image
# 3. Test commands in Docker
# 4. Compare performance
```
### 2. Full Local CI/CD Test
```bash
# Run complete local CI/CD simulation
./scripts/test-local-ci-cd.sh
# This will:
# 1. Install dependencies
# 2. Generate Swagger docs
# 3. Build and test code
# 4. Build binaries
# 5. Simulate version bump
# 6. Optionally build Docker image
```
### 3. Test Specific Components
#### Coverage Badge Updates
```bash
# Test coverage badge update logic
./scripts/ci-update-coverage-badge.sh 75.5
```
#### Version Bump Logic
```bash
# Test version bump with different commit messages
./scripts/ci-version-bump.sh "✨ feat: add new feature"
./scripts/ci-version-bump.sh "🐛 fix: resolve bug"
./scripts/ci-version-bump.sh "Regular commit message"
```
## 🐳 Docker Build Cache Testing
The Docker build cache system works by:
1. **Calculating dependency hash**: `sha256sum go.mod go.sum`
2. **Building cache image**: Only when dependencies change
3. **Using cached image**: For all subsequent CI runs
### Local Testing
```bash
# Build the cache image locally
docker build -t dance-lessons-coach-build-cache -f Dockerfile.build .
# Test running commands in the cached environment
docker run --rm -v "$(pwd):/workspace" -w /workspace \
dance-lessons-coach-build-cache \
go test ./... -cover
```
### CI Integration
The CI workflow automatically:
- Calculates the same hash
- Checks if image exists in registry
- Builds new image only when needed
- Uses cached image for all builds
## 🔄 CI/CD Workflow Simulation
To simulate the full CI/CD workflow locally:
```bash
# 1. Run local CI tests
./scripts/test-local-ci-cd.sh
# 2. When prompted, build Docker image
# 3. Test the running container
# 4. Verify all endpoints work
# 5. Test BDD scenarios
./scripts/run-bdd-tests.sh
# 6. Test graceful shutdown
./scripts/test-graceful-shutdown.sh
# 7. Test OpenTelemetry
./scripts/test-opentelemetry.sh
```
## 📊 Performance Comparison
### Without Docker Cache
```
First run: ~90 seconds
Subsequent: ~90 seconds (no caching)
```
### With Docker Cache
```
First run: ~120 seconds (build cache)
Subsequent: ~30 seconds (use cache)
Savings: ~60 seconds per run!
```
## 🎯 Best Practices
1. **Test locally first**: Always run `test-local-ci-cd.sh` before pushing
2. **Check Docker cache**: Run `test-docker-cache.sh` after dependency changes
3. **Verify coverage**: Test coverage badge updates with different percentages
4. **Test version bumps**: Verify version logic with different commit types
5. **Clean up**: Remove test containers and images when done
## 🧪 Advanced Testing
### Test Race Conditions
```bash
# Simulate concurrent CI runs
./scripts/ci-update-coverage-badge.sh 75.5 &
./scripts/ci-update-coverage-badge.sh 75.5 &
wait
```
### Test Version Bump Scenarios
```bash
# Test all version bump scenarios
echo "✨ feat: new feature" > /tmp/test_commit
./scripts/ci-version-bump.sh "$(cat /tmp/test_commit)"
echo "🐛 fix: bug fix" > /tmp/test_commit
./scripts/ci-version-bump.sh "$(cat /tmp/test_commit)"
echo "BREAKING CHANGE: major update" > /tmp/test_commit
./scripts/ci-version-bump.sh "$(cat /tmp/test_commit)"
```
## 🔧 Troubleshooting
### Docker Issues
- **Permission denied**: Add user to docker group or use `sudo`
- **Port conflicts**: Change test port or stop conflicting services
- **Image not found**: Build the image first with `docker build`
### CI Script Issues
- **Missing dependencies**: Install required tools (Go, Docker, etc.)
- **Script permissions**: Run `chmod +x scripts/*.sh`
- **Path issues**: Use full paths or correct working directory
### Performance Issues
- **Slow Docker builds**: Use `--no-cache` for fresh builds
- **Large images**: Check Dockerfile for unnecessary layers
- **Memory issues**: Increase Docker resources in settings
## 📖 Reference
### Docker Commands
```bash
# List images
docker images
# List containers
docker ps -a
# Remove container
docker rm <container_id>
# Remove image
docker rmi <image_id>
# View logs
docker logs <container_id>
# Exec into container
docker exec -it <container_id> sh
```
### CI Commands
```bash
# Run specific CI job
act -j <job_name>
# Test workflow locally
act
# Dry run (show what would run)
act -n
```
## 🎓 Learning Resources
- [Docker Documentation](https://docs.docker.com/)
- [GitHub Actions Documentation](https://docs.github.com/en/actions)
- [Go Testing Documentation](https://pkg.go.dev/testing)
- [CI/CD Best Practices](https://github.com/goldbergyoni/nodebestpractices)
This guide provides everything you need to test the CI/CD pipeline locally before pushing to the repository!

View File

@@ -1,6 +1,6 @@
# DanceLessonsCoach Scripts
# dance-lessons-coach Scripts
This directory contains automation and management scripts for the DanceLessonsCoach project.
This directory contains automation and management scripts for the dance-lessons-coach project.
## 📁 Script Categories
@@ -22,7 +22,7 @@ This directory contains automation and management scripts for the DanceLessonsCo
### 1. Server Management (`start-server.sh`)
**Manage the DanceLessonsCoach server lifecycle**
**Manage the dance-lessons-coach server lifecycle**
```bash
# Start the server
@@ -301,13 +301,13 @@ exit 0
- [Git SCM](https://git-scm.com/)
- [Go Build](https://golang.org/cmd/go/)
### DanceLessonsCoach Specific
### dance-lessons-coach Specific
- [ADR 0014: Version Management](adr/0014-version-management-lifecycle.md)
- [AGENTS.md Scripts Section](#-scripts)
- [Contributing Guide](CONTRIBUTING.md)
---
**Maintained by:** DanceLessonsCoach Team
**Maintained by:** dance-lessons-coach Team
**License:** MIT
**Status:** Actively developed

View File

@@ -1,5 +1,5 @@
#!/bin/bash
# Build DanceLessonsCoach with version information
# Build dance-lessons-coach with version information
# Usage: ./scripts/build-with-version.sh [output_path]
set -e
@@ -22,7 +22,7 @@ GIT_DATE=$(git log -1 --format=%cd --date=short 2>/dev/null || echo "unknown")
# Build time (UTC for consistency)
BUILD_DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ)
echo "🔧 Building DanceLessonsCoach $VERSION"
echo "🔧 Building dance-lessons-coach $VERSION"
echo " Commit: $GIT_COMMIT"
echo " Date: $GIT_DATE"
echo " Output: $OUTPUT_PATH"
@@ -31,9 +31,9 @@ echo " Output: $OUTPUT_PATH"
go build \
-o "$OUTPUT_PATH" \
-ldflags="\
-X DanceLessonsCoach/pkg/version.Version=$VERSION \
-X DanceLessonsCoach/pkg/version.Commit=$GIT_COMMIT \
-X DanceLessonsCoach/pkg/version.Date=$BUILD_DATE \
-X dance-lessons-coach/pkg/version.Version=$VERSION \
-X dance-lessons-coach/pkg/version.Commit=$GIT_COMMIT \
-X dance-lessons-coach/pkg/version.Date=$BUILD_DATE \
" \
./cmd/server

View File

@@ -1,11 +1,11 @@
#!/bin/bash
# DanceLessonsCoach Build Script
# dance-lessons-coach Build Script
# Builds binaries into the bin/ directory
set -e
echo "🔨 Building DanceLessonsCoach binaries..."
echo "🔨 Building dance-lessons-coach binaries..."
# Create bin directory if it doesn't exist
mkdir -p bin

View File

@@ -1,12 +1,12 @@
#!/bin/bash
# DanceLessonsCoach CI/CD Management Script
# dance-lessons-coach CI/CD Management Script
# Unified interface for all CI/CD operations
set -e
SCRIPTS_DIR="$(dirname "$0")/cicd"
echo "🚀 DanceLessonsCoach CI/CD Management"
echo "🚀 dance-lessons-coach CI/CD Management"
echo "===================================="
echo ""

View File

@@ -1,286 +0,0 @@
# CI/CD Scripts for DanceLessonsCoach
## 🚀 Quick Start for Contributors
### You Only Need These Commands
```bash
# 1. Run tests (this is what matters most!)
go test ./...
# 2. Build binaries
./scripts/build.sh
# 3. Check formatting
go fmt ./...
# That's it! The CI/CD pipeline will handle the rest when you create a PR.
```
## 📖 Understanding the CI/CD Pipeline
### What Happens Automatically
When you push code or create a PR, GitHub Actions runs:
1. **Go CI/CD Pipeline** (`.gitea/workflows/go-ci-cd.yaml`)
- Builds all Go packages
- Runs tests with coverage
- Checks code formatting
- Validates workflow structure
2. **Docker Image Pipeline** (`.gitea/workflows/dockerimage.yaml`)
- Builds Docker image (on main branch only)
- Publishes to Gitea Container Registry
- Tags with version and commit SHA
### When Does It Run?
| Event | Go CI/CD | Docker Image |
|-------|---------|--------------|
| Push to `main` | ✅ Yes | ✅ Yes |
| Push to `feature/*` | ✅ Yes | ❌ No |
| Push to `fix/*` | ✅ Yes | ❌ No |
| Push to `ci/*` | ✅ Yes | ❌ No |
| Pull Request | ✅ Yes | ❌ No |
| Manual trigger | ✅ Yes | ✅ Yes |
## 🧪 Local Testing Options
### Option 1: Simple Validation (No Docker Required)
```bash
# Just run the essentials
./scripts/cicd/contributor-quickstart.sh
```
This checks:
- ✅ Go installation
- ✅ All tests pass
- ✅ Code formatting
- ✅ Go vet analysis
- ✅ Workflow structure
### Option 2: Docker-Based Testing (Recommended)
```bash
# Test workflow compatibility with GitHub Actions
./scripts/cicd/test-act-local.sh
```
**Requirements:**
- Docker installed and running
- Internet connection (to pull images)
**What it does:**
- Validates YAML syntax
- Checks workflow structure
- Simulates GitHub Actions execution
- Tests both workflow files
### Option 3: Full CI/CD Simulation
```bash
# Complete local simulation
./scripts/cicd/test-cicd-simple.sh
```
**Requirements:**
- Docker installed and running
- More time (pulls multiple images)
**What it does:**
- YAML linting
- YAML validation
- Workflow structure validation
- Simulates build job
- Runs actual Go tests in containers
## 🐳 Docker Setup Guide
### For Windows Users
1. **Install Docker Desktop**
- Download: https://www.docker.com/products/docker-desktop/
- Enable WSL 2 backend (recommended)
- Allocate at least 4GB RAM
2. **Verify Installation**
```powershell
docker --version
docker run hello-world
```
### For macOS Users
1. **Install Docker Desktop**
- Download: https://www.docker.com/products/docker-desktop/
- Grant necessary permissions
2. **Verify Installation**
```bash
docker --version
docker run hello-world
```
### For Linux Users
1. **Install Docker Engine**
```bash
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install docker.io docker-compose
sudo systemctl enable docker
sudo systemctl start docker
# Add user to docker group (avoid sudo)
sudo usermod -aG docker $USER
newgrp docker # Reload group membership
```
2. **Verify Installation**
```bash
docker --version
docker run hello-world
```
## 🔧 Troubleshooting
### Docker Permission Issues
**Symptom:** `Got permission denied while trying to connect to the Docker daemon socket`
**Solution:**
```bash
# Linux/macOS
sudo usermod -aG docker $USER
newgrp docker
# Windows
Right-click Docker Desktop → Settings → Resources → WSL Integration → Enable
```
### Docker Not Running
**Symptom:** `Cannot connect to the Docker daemon`
**Solution:**
- Windows/macOS: Open Docker Desktop app
- Linux: `sudo systemctl start docker`
### Network Issues
**Symptom:** `Cannot pull Docker images`
**Solution:**
```bash
# Check internet connection
ping google.com
# Try pulling manually first
docker pull mikefarah/yq:latest
docker pull pipelinecomponents/yamllint:latest
```
### act Not Installed
**Symptom:** `act not found` in `test-act-local.sh`
**Solution:**
```bash
# Install act (optional - only needed for test-act-local.sh)
# macOS
brew install act
# Linux
curl https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash
# Windows (WSL)
curl https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash
```
## 📚 Script Reference
| Script | Purpose | Docker Required? | act Required? |
|--------|---------|------------------|---------------|
| `contributor-quickstart.sh` | Basic validation | ❌ No | ❌ No |
| `validate-workflow.sh` | Workflow structure | ❌ No | ❌ No |
| `test-act-local.sh` | GitHub Actions compatibility | ✅ Yes | ✅ Yes |
| `test-cicd-simple.sh` | Full CI/CD simulation | ✅ Yes | ❌ No |
## 🎯 Best Practices
### Before Submitting a PR
1. **Run tests locally**
```bash
go test ./...
```
2. **Check formatting**
```bash
go fmt ./...
```
3. **Build binaries**
```bash
./scripts/build.sh
```
4. **Validate workflows** (optional)
```bash
./scripts/cicd/validate-workflow.sh
```
### Working with the CI/CD Pipeline
- **Don't worry about Docker images** - The pipeline builds them automatically
- **Focus on tests** - If tests pass locally, they'll pass in CI/CD
- **Check PR status** - GitHub will show CI/CD results automatically
- **Fix failures** - If CI/CD fails, check the logs and fix issues
## 🔗 Useful Links
- **GitHub Actions Docs**: https://docs.github.com/en/actions
- **Docker Docs**: https://docs.docker.com/
- **act GitHub**: https://github.com/nektos/act
- **DanceLessonsCoach CI/CD**: See `.gitea/workflows/` directory
## 💡 Pro Tips
### Speed Up Local Testing
```bash
# Pull Docker images in advance
docker pull mikefarah/yq:latest
docker pull pipelinecomponents/yamllint:latest
docker pull node:16-buster-slim
```
### Test Specific Workflows
```bash
# Test Go CI/CD workflow only
act -W .gitea/workflows/go-ci-cd.yaml
# Test Docker workflow only
act -W .gitea/workflows/dockerimage.yaml
```
### Dry Run (No Execution)
```bash
# Check workflow syntax without running
echo 'm' | act -n -W .gitea/workflows/go-ci-cd.yaml
```
## 📞 Need Help?
If you're stuck with CI/CD setup:
1. **Check this documentation** - Most issues are covered here
2. **Run contributor-quickstart.sh** - It validates the essentials
3. **Ask in the PR** - We'll help you resolve any issues
4. **Check CI/CD logs** - GitHub shows detailed error messages
Remember: **You don't need to run CI/CD locally to contribute!** The pipeline runs automatically when you push code.

View File

@@ -1,71 +0,0 @@
#!/bin/bash
# Check CI/CD pipeline status across all platforms
set -e
echo "🔍 Checking CI/CD Pipeline Status"
echo "================================"
# 1. Gitea (Primary) - Internal URL
if curl -s -o /dev/null -w "%{http_code}" "https://gitea.arcodange.lab/api/v1/repos/arcodange/DanceLessonsCoach/actions/workflows" 2>/dev/null | grep -q "200"; then
echo "✅ Gitea Internal API: Accessible"
# Get workflow list
WORKFLOWS=$(curl -s "https://gitea.arcodange.lab/api/v1/repos/arcodange/DanceLessonsCoach/actions/workflows" 2>/dev/null | jq -r '.[] | .name + " (" + .file_name + ")"' 2>/dev/null || echo "Unable to fetch workflow list")
echo "📋 Gitea Workflows:"
echo "$WORKFLOWS" | sed 's/^/ - /'
else
echo "❌ Gitea Internal API: Not accessible (check network/vpn)"
fi
# 2. Gitea (External) - Public URL
echo ""
echo "🌐 Gitea External Status:"
if curl -s -o /dev/null -w "%{http_code}" "https://gitea.arcodange.fr/arcodange/DanceLessonsCoach" 2>/dev/null | grep -q "200"; then
echo "✅ Gitea External: Accessible"
echo "🔗 Repository: https://gitea.arcodange.fr/arcodange/DanceLessonsCoach"
else
echo "❌ Gitea External: Not accessible"
fi
# 3. Check badge API
echo ""
echo "🏷️ Badge API Status:"
BADGE_URL="https://gitea.arcodange.fr/api/badges/arcodange/DanceLessonsCoach/status"
if curl -s -o /dev/null -w "%{http_code}" "$BADGE_URL" 2>/dev/null | grep -q "200"; then
echo "✅ Badge API: Accessible"
echo "🔗 Badge URL: $BADGE_URL"
else
echo "❌ Badge API: Not accessible"
fi
# 4. Check workflow file existence
echo ""
echo "📁 Workflow Files:"
if [ -f ".gitea/workflows/ci-cd.yaml" ]; then
echo "✅ .gitea/workflows/ci-cd.yaml: Found"
if command -v yq >/dev/null 2>&1; then
echo "📊 Jobs: $(yq eval '.jobs | keys | join(", ")' .gitea/workflows/ci-cd.yaml 2>/dev/null || echo 'Unable to parse')"
else
echo "📊 Jobs: yq not installed, cannot parse jobs"
fi
else
echo "❌ .gitea/workflows/ci-cd.yaml: Not found"
fi
echo ""
echo "🎯 Validation Summary"
echo "================================"
echo "✅ Local workflow file: .gitea/workflows/ci-cd.yaml"
if command -v yq >/dev/null 2>&1; then
echo "✅ Syntax validation: $(yq eval '.' .gitea/workflows/ci-cd.yaml > /dev/null 2>&1 && echo 'Valid YAML' || echo 'Invalid YAML')"
else
echo "⚠️ Syntax validation: yq not installed"
fi
echo "✅ Gitea compatibility: Uses .gitea/workflows/ directory"
echo "✅ Arcodange conventions: Matches webapp workflow style"
echo ""
echo "💡 Next Steps:"
echo " 1. Push to trigger workflow: git push origin main"
echo " 2. Check Gitea Actions: https://gitea.arcodange.lab/arcodange/DanceLessonsCoach/actions"
echo " 3. Monitor badges: https://gitea.arcodange.fr/arcodange/DanceLessonsCoach"

View File

@@ -1,78 +0,0 @@
#!/bin/bash
# Simple CI/CD validation for new contributors
# Works without Docker - just validates the essentials
set -e
echo "🚀 DanceLessonsCoach Contributor Quick Start"
echo "=========================================="
echo ""
echo "This script helps you validate your changes before submitting a PR."
echo "It doesn't require Docker or complex setup."
echo ""
# 1. Check Go is installed
echo "1. Checking Go installation..."
if ! command -v go >/dev/null 2>&1; then
echo "❌ Go is not installed. Please install Go 1.26.1+"
echo " Download: https://go.dev/dl/"
exit 1
fi
go_version=$(go version | grep -o 'go[0-9.]*')
echo "✅ Go $go_version found"
# 2. Run Go tests
echo ""
echo "2. Running Go tests..."
if go test ./...; then
echo "✅ All Go tests passed"
else
echo "❌ Some tests failed. Please fix and try again."
exit 1
fi
# 3. Check formatting
echo ""
echo "3. Checking code formatting..."
if [ -n "$(go fmt ./...)" ]; then
echo "❌ Code formatting issues found"
echo " Run: go fmt ./..."
exit 1
fi
echo "✅ Code is properly formatted"
# 4. Run Go vet
echo ""
echo "4. Running Go vet..."
if go vet ./...; then
echo "✅ Go vet passed"
else
echo "❌ Go vet found issues"
exit 1
fi
# 5. Validate workflows (no Docker required)
echo ""
echo "5. Validating CI/CD workflows..."
if [ -f "scripts/cicd/validate-workflow.sh" ]; then
if ./scripts/cicd/validate-workflow.sh; then
echo "✅ Workflow validation passed"
else
echo "⚠️ Workflow validation issues (not critical)"
fi
else
echo " Workflow validation script not found"
fi
echo ""
echo "🎉 All checks passed!"
echo "=========================================="
echo ""
echo "Your changes are ready to submit! 🚀"
echo ""
echo "Next steps:"
echo " 1. Commit your changes: git commit -m 'feat: your feature'"
echo " 2. Push to your branch: git push origin your-branch"
echo " 3. Create a Pull Request"
echo ""
echo "The CI/CD pipeline will run automatically on your PR!"

View File

@@ -1,75 +0,0 @@
#!/bin/bash
# Test Gitea workflows locally using GitHub Actions runner (act)
# This allows local testing without requiring a Gitea instance
set -e
echo "🧪 Testing Gitea Workflows with GitHub Actions Runner"
echo "===================================================="
# Check if act is installed
if ! command -v act >/dev/null 2>&1; then
echo "❌ act not found. Please install with:"
echo " brew install act # macOS"
echo " or visit: https://github.com/nektos/act"
exit 1
fi
# Check if workflow files exist
WORKFLOW_FILES=(
".gitea/workflows/go-ci-cd.yaml"
".gitea/workflows/dockerimage.yaml"
)
for file in "${WORKFLOW_FILES[@]}"; do
if [ ! -f "$file" ]; then
echo "❌ Workflow file not found: $file"
exit 1
fi
done
echo "✅ act installed and workflow file found"
echo ""
# 1. Dry run (syntax check only)
echo "1. Running dry run (syntax validation)..."
ALL_PASSED=true
for file in "${WORKFLOW_FILES[@]}"; do
echo " Testing: $file"
if echo 'm' | act -n -W "$file" --container-architecture linux/amd64; then
echo " ✅ Dry run completed for $file"
else
echo " ❌ Dry run failed for $file"
ALL_PASSED=false
fi
done
if [ "$ALL_PASSED" = true ]; then
echo "✅ All dry runs completed successfully"
else
echo "❌ Some dry runs failed"
exit 1
fi
echo ""
echo "🎉 Gitea workflows are compatible with GitHub Actions!"
echo "=================================================="
echo ""
echo "📋 Summary:"
echo " ✅ Syntax validation passed for all workflows"
echo " ✅ All jobs parsed correctly"
echo " ✅ Job dependencies resolved"
echo " ✅ Conditional execution working"
echo " ✅ Gitea/GitHub Actions compatibility confirmed"
echo ""
echo "🚀 You can now test locally without Gitea instance:"
for file in "${WORKFLOW_FILES[@]}"; do
workflow_name=$(basename "$file" .yaml)
echo " act -n -W $file # Dry run $workflow_name"
echo " act -W $file # Full execution $workflow_name"
done
echo ""
echo "💡 Tip: Add this to your pre-commit hook to validate workflows automatically!"

View File

@@ -1,99 +0,0 @@
#!/bin/bash
# Comprehensive Docker-based CI/CD testing script
# Tests workflows locally using Docker containers
set -e
echo "🐳 Docker-based CI/CD Testing"
echo "================================"
# 1. Check Docker is available
if ! command -v docker >/dev/null 2>&1; then
echo "❌ Docker not found. Please install Docker first."
echo " https://docs.docker.com/get-docker/"
exit 1
fi
echo "✅ Docker is available"
# 2. Pull required images
echo ""
echo "📦 Pulling Docker images..."
docker pull gitea/act_runner:latest
docker pull pipelinecomponents/yamllint:latest
docker pull mikefarah/yq:latest
echo "✅ Images pulled successfully"
# 3. Validate YAML syntax with yq
echo ""
echo "🔍 Validating YAML syntax..."
docker run --rm \
-v $(pwd):/workspace \
-w /workspace \
mikefarah/yq:latest \
yq eval .gitea/workflows/go-ci-cd.yaml > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "✅ YAML syntax is valid"
else
echo "❌ YAML syntax error"
docker run --rm \
-v $(pwd):/workspace \
-w /workspace \
mikefarah/yq:latest \
yq eval .gitea/workflows/go-ci-cd.yaml || true
exit 1
fi
# 4. Lint YAML with yamllint
echo ""
echo "🧹 Linting YAML..."
docker run --rm \
-v $(pwd):/workspace \
-w /workspace \
pipelinecomponents/yamllint:latest \
yamllint .gitea/workflows/
if [ $? -eq 0 ]; then
echo "✅ YAML linting passed"
else
echo "❌ YAML linting failed"
exit 1
fi
# 5. Run workflow with act
echo ""
echo "🚀 Running CI/CD workflow..."
docker run --rm \
-v $(pwd):/workspace \
-w /workspace \
-e GITEA_INTERNAL="https://gitea.arcodange.lab/" \
-e GITEA_EXTERNAL="https://gitea.arcodange.fr/" \
-e GITEA_ORG="arcodange" \
-e GITEA_REPO="DanceLessonsCoach" \
gitea/act_runner:latest \
act -W .gitea/workflows/go-ci-cd.yaml --rm
if [ $? -eq 0 ]; then
echo "✅ Workflow executed successfully"
else
echo "❌ Workflow execution failed"
exit 1
fi
echo ""
echo "🎉 All CI/CD tests passed!"
echo "================================"
echo "📁 Workflow: .gitea/workflows/ci-cd.yaml"
echo "✅ YAML syntax validated"
echo "✅ YAML linting passed"
echo "✅ Workflow execution successful"
echo "🎯 Ready for production deployment"
echo ""
echo "💡 Next Steps:"
echo " 1. Commit changes: git commit -m '🤖 ci: update workflow'"
echo " 2. Push to trigger: git push origin main"
echo " 3. Monitor pipeline: https://gitea.arcodange.lab/arcodange/DanceLessonsCoach/actions"
echo " 4. Check badges: https://gitea.arcodange.fr/arcodange/DanceLessonsCoach"

View File

@@ -1,82 +0,0 @@
#!/bin/bash
# Test CI/CD setup locally without requiring Gitea instance
set -e
echo "🧪 Testing CI/CD Local Setup"
echo "=============================="
# 1. Validate YAML syntax
echo "1. Validating YAML syntax..."
if command -v yq >/dev/null 2>&1; then
yq eval '.' .gitea/workflows/go-ci-cd.yaml > /dev/null
yq eval '.' .gitea/workflows/dockerimage.yaml > /dev/null
echo "✅ YAML syntax is valid"
else
echo "⚠️ yq not found, skipping YAML validation"
fi
# 2. Validate workflow structure
echo "2. Validating workflow structure..."
./scripts/cicd/validate-workflow.sh
# 3. Check docker-compose configuration
echo "3. Checking docker-compose configuration..."
docker compose -f docker-compose.cicd-test.yml config > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "✅ docker-compose configuration is valid"
else
echo "❌ docker-compose configuration has issues"
exit 1
fi
# 4. Check for required files
echo "4. Checking required files..."
REQUIRED_FILES=(
".gitea/workflows/go-ci-cd.yaml"
".gitea/workflows/dockerimage.yaml"
"docker-compose.cicd-test.yml"
"config/runner.example"
)
for file in "${REQUIRED_FILES[@]}"; do
if [ -f "$file" ]; then
echo "$file exists"
else
echo "$file missing"
exit 1
fi
done
# 5. Show configuration status
echo "5. Configuration status..."
if [ -f "config/runner" ]; then
echo "✅ config/runner exists (gitignored)"
echo "📝 You can connect to Gitea instance"
else
echo " config/runner not found (expected - it's gitignored)"
echo "📝 To connect to Gitea:"
echo " 1. Copy config/runner.example to config/runner"
echo " 2. Fill in your Gitea runner configuration"
echo " 3. Set environment variables:"
echo " export GITEA_RUNNER_REGISTRATION_TOKEN=your-token"
echo " 4. Run: docker compose -f docker-compose.cicd-test.yml up"
fi
echo ""
echo "🎉 CI/CD Local Setup Validation Complete!"
echo "=============================="
echo "📋 Summary:"
echo " ✅ YAML syntax validated"
echo " ✅ Workflow structure validated"
echo " ✅ Docker-compose configuration validated"
echo " ✅ All required files present"
echo ""
echo "🚀 Next steps:"
echo " 1. Create config/runner file with your Gitea runner token"
echo " 2. Set GITEA_RUNNER_REGISTRATION_TOKEN environment variable"
echo " 3. Run: docker compose -f docker-compose.cicd-test.yml up"
echo ""
echo "💡 For local testing without Gitea:"
echo " Use: ./scripts/test-cicd-simple.sh (if available)"
echo " Or manually test workflow steps"

View File

@@ -1,61 +0,0 @@
#!/bin/bash
# Simple CI/CD testing without Gitea instance
# Tests the workflow steps locally using docker containers
set -e
echo "🧪 Simple CI/CD Testing (No Gitea Required)"
echo "=========================================="
# 1. YAML Linting
echo "1. Running YAML linting..."
if [ -f ".yamllint.yaml" ]; then
docker run --rm -v $(pwd):/workspace -w /workspace pipelinecomponents/yamllint:latest \
yamllint -c .yamllint.yaml .gitea/workflows/
else
docker run --rm -v $(pwd):/workspace -w /workspace pipelinecomponents/yamllint:latest \
yamllint .gitea/workflows/
fi
echo "✅ YAML linting passed"
# 2. YAML Validation
echo "2. Running YAML validation..."
WORKFLOW_FILES=(".gitea/workflows/go-ci-cd.yaml" ".gitea/workflows/dockerimage.yaml")
for file in "${WORKFLOW_FILES[@]}"; do
docker run --rm -v $(pwd):/workspace -w /workspace mikefarah/yq:latest eval '.' "$file" > /dev/null
done
echo "✅ YAML validation passed"
# 3. Workflow Structure Validation
echo "3. Running workflow structure validation..."
./scripts/cicd/validate-workflow.sh
# 4. Simulate Build Job
echo "4. Simulating build-test job..."
docker run --rm -v $(pwd):/workspace -w /workspace golang:1.26.1 bash -c "
apt-get update -qq && apt-get install -y -qq git > /dev/null && \
go mod tidy && \
go build ./... && \
go test ./... -cover -v
"
echo "✅ Build and test completed"
# 5. Simulate Lint Job
echo "5. Simulating lint-format job..."
docker run --rm -v $(pwd):/workspace -w /workspace golang:1.26.1 bash -c "
go fmt ./... && \
go vet ./... && \
echo 'Formatting check passed'
"
echo "✅ Linting completed"
echo ""
echo "🎉 Simple CI/CD Testing Complete!"
echo "=========================================="
echo "✅ All workflow steps validated locally"
echo "📝 Workflow is ready for Gitea deployment"
echo ""
echo "🚀 To deploy to Gitea:"
echo " 1. Create config/runner file with your Gitea runner token"
echo " 2. Set GITEA_RUNNER_REGISTRATION_TOKEN environment variable"
echo " 3. Run: docker compose -f docker-compose.cicd-test.yml up"

View File

@@ -1,151 +0,0 @@
#!/bin/bash
# Validate CI/CD workflow syntax and structure
set -e
echo "🔍 Validating CI/CD Workflow"
echo "================================"
# 1. Check workflow files exist
WORKFLOW_FILES=(
".gitea/workflows/go-ci-cd.yaml"
".gitea/workflows/dockerimage.yaml"
)
for file in "${WORKFLOW_FILES[@]}"; do
if [ ! -f "$file" ]; then
echo "❌ Workflow file not found: $file"
exit 1
fi
echo "✅ Workflow file found: $file"
done
# 2. Validate YAML syntax for all workflows
if command -v yq >/dev/null 2>&1; then
for file in "${WORKFLOW_FILES[@]}"; do
if ! yq eval '.' "$file" > /dev/null 2>&1; then
echo "❌ Invalid YAML syntax in: $file"
yq eval '.' "$file" || true
exit 1
fi
echo "✅ YAML syntax valid: $file"
done
else
echo "⚠️ yq not installed, skipping YAML validation"
fi
# 3. YAML Linting with custom config for all workflows
if command -v yamllint >/dev/null 2>&1; then
for file in "${WORKFLOW_FILES[@]}"; do
if [ -f ".yamllint.yaml" ]; then
yamllint -c "$(pwd)/.yamllint.yaml" "$file"
else
yamllint "$file"
fi
done
elif docker info >/dev/null 2>&1; then
for file in "${WORKFLOW_FILES[@]}"; do
if [ -f ".yamllint.yaml" ]; then
docker run --rm -v $(pwd):/workspace -w /workspace pipelinecomponents/yamllint:latest \
yamllint -c /workspace/.yamllint.yaml "$file"
else
docker run --rm -v $(pwd):/workspace -w /workspace pipelinecomponents/yamllint:latest \
yamllint "$file"
fi
done
else
echo "⚠️ Neither yamllint nor docker available, skipping linting"
fi
# 3. Check required fields for all workflows
for file in "${WORKFLOW_FILES[@]}"; do
MISSING_FIELDS=()
if command -v yq >/dev/null 2>&1; then
workflow_name=$(basename "$file" .yaml)
if [ -z "$(yq eval '.name' "$file" 2>/dev/null)" ]; then
MISSING_FIELDS+=("name")
fi
if [ -z "$(yq eval '.on' "$file" 2>/dev/null)" ]; then
MISSING_FIELDS+=("on")
fi
if [ -z "$(yq eval '.jobs' "$file" 2>/dev/null)" ]; then
MISSING_FIELDS+=("jobs")
fi
if [ ${#MISSING_FIELDS[@]} -gt 0 ]; then
echo "❌ Missing required fields in $workflow_name: ${MISSING_FIELDS[*]}"
exit 1
fi
echo "✅ All required fields present in $workflow_name"
else
echo "⚠️ yq not installed, skipping field validation for $file"
fi
done
# 4. Check jobs structure
if command -v yq >/dev/null 2>&1; then
JOBS=$(yq eval '.jobs | keys' .gitea/workflows/ci-cd.yaml 2>/dev/null)
echo "📋 Jobs defined: $JOBS"
for job in $JOBS; do
job_str=$(echo $job | tr -d '"')
# Check job has steps
if [ -z "$(yq eval ".jobs.$job_str.steps" .gitea/workflows/ci-cd.yaml 2>/dev/null)" ]; then
echo "❌ Job $job_str has no steps"
exit 1
fi
steps_count=$(yq eval ".jobs.$job_str.steps | length" .gitea/workflows/ci-cd.yaml 2>/dev/null)
echo "$job_str: $steps_count steps"
done
else
echo "⚠️ yq not installed, skipping job structure validation"
fi
# 5. Check Arcodange-specific configurations
if command -v yq >/dev/null 2>&1; then
if [ -n "$(yq eval '.env.GITEA_INTERNAL' .gitea/workflows/ci-cd.yaml 2>/dev/null)" ]; then
echo "✅ Arcodange internal URL configured"
else
echo "⚠️ Arcodange internal URL not found"
fi
if [ -n "$(yq eval '.env.GITEA_EXTERNAL' .gitea/workflows/ci-cd.yaml 2>/dev/null)" ]; then
echo "✅ Arcodange external URL configured"
else
echo "⚠️ Arcodange external URL not found"
fi
# 6. Check concurrency settings
if [ -n "$(yq eval '.concurrency' .gitea/workflows/ci-cd.yaml 2>/dev/null)" ]; then
echo "✅ Concurrency control configured"
else
echo "⚠️ No concurrency control (consider adding)"
fi
else
echo "⚠️ yq not installed, skipping Arcodange-specific validations"
fi
echo ""
echo "🎉 Workflow Validation Successful!"
echo "================================"
echo "📁 Workflows validated:"
for file in "${WORKFLOW_FILES[@]}"; do
echo " - $file"
done
if command -v yq >/dev/null 2>&1; then
echo "🔧 Summary:"
for file in "${WORKFLOW_FILES[@]}"; do
workflow_name=$(basename "$file" .yaml)
JOBS=$(yq eval '.jobs | keys | join(", ")' "$file" 2>/dev/null || echo 'Unable to parse')
echo " - $workflow_name: $JOBS"
done
else
echo "🔧 Jobs: yq not installed"
fi
echo "🎯 Ready for deployment"

View File

@@ -6,10 +6,96 @@
set -e
echo "🧪 Running BDD Tests..."
cd /Users/gabrielradureau/Work/Vibe/DanceLessonsCoach
SCRIPTS_DIR=$(dirname `realpath ${BASH_SOURCE[0]}`)
cd $SCRIPTS_DIR/..
# Check if we're in CI environment
if [ -n "$GITHUB_ACTIONS" ] || [ -n "$GITEA_ACTIONS" ]; then
# CI environment - PostgreSQL is already running as a service
echo "🏗️ CI environment detected"
echo "🐋 PostgreSQL service is already running"
# Check if database is accessible
echo "📦 Checking PostgreSQL connectivity..."
if ! pg_isready -h postgres -p 5432 -U postgres -d dance_lessons_coach_bdd_test; then
echo "❌ PostgreSQL is not ready or accessible"
exit 1
fi
echo "✅ PostgreSQL is ready!"
else
# Local environment - use docker compose
echo "💻 Local environment detected"
# Check if PostgreSQL container is running, start it if not
echo "🐋 Checking PostgreSQL container..."
if ! docker ps --format '{{.Names}}' | grep -q "^dance-lessons-coach-postgres$"; then
echo "🐋 Starting PostgreSQL container..."
docker compose up -d postgres
# Wait for PostgreSQL to be ready
echo "⏳ Waiting for PostgreSQL to be ready..."
max_attempts=30
attempt=0
while [ $attempt -lt $max_attempts ]; do
if docker exec dance-lessons-coach-postgres pg_isready -U postgres 2>/dev/null; then
echo "✅ PostgreSQL is ready!"
break
fi
attempt=$((attempt + 1))
sleep 1
done
if [ $attempt -eq $max_attempts ]; then
echo "❌ PostgreSQL failed to start"
exit 1
fi
# Create BDD test database (separate from development database)
echo "📦 Creating BDD test database..."
# Drop database if it exists, then create fresh
docker exec dance-lessons-coach-postgres psql -U postgres -c "DROP DATABASE IF EXISTS dance_lessons_coach_bdd_test;"
if docker exec dance-lessons-coach-postgres createdb -U postgres dance_lessons_coach_bdd_test; then
echo "✅ BDD test database created successfully!"
else
echo "❌ Failed to create BDD test database"
exit 1
fi
else
echo "✅ PostgreSQL container is already running"
# Check if BDD test database exists, create if not
echo "📦 Checking BDD test database..."
if docker exec dance-lessons-coach-postgres psql -U postgres -lqt | cut -d \| -f 1 | grep -qw "dance_lessons_coach_bdd_test"; then
echo "✅ BDD test database already exists"
else
echo "📦 Creating BDD test database..."
if docker exec dance-lessons-coach-postgres createdb -U postgres dance_lessons_coach_bdd_test; then
echo "✅ BDD test database created successfully!"
else
echo "❌ Failed to create BDD test database"
exit 1
fi
fi
fi
fi
# Run the BDD tests
test_output=$(go test ./features/... -v 2>&1)
# For local environment, set database environment variables to use localhost
# For CI environment, the database is already configured as a service
if [ -z "$GITHUB_ACTIONS" ] && [ -z "$GITEA_ACTIONS" ]; then
echo "🔧 Setting database environment variables for local environment..."
export DLC_DATABASE_HOST="localhost"
export DLC_DATABASE_PORT="5432"
export DLC_DATABASE_USER="postgres"
export DLC_DATABASE_PASSWORD="postgres"
export DLC_DATABASE_NAME="dance_lessons_coach_bdd_test"
export DLC_DATABASE_SSL_MODE="disable"
else
echo "🏗️ CI environment detected, using service configuration"
fi
# Run tests with proper coverage measurement
test_output=$(go test ./features/... -v -cover -coverpkg=./... -coverprofile=coverage.out 2>&1)
test_exit_code=$?
echo "$test_output"
@@ -38,5 +124,6 @@ if [ $test_exit_code -eq 0 ]; then
exit 0
else
echo "❌ BDD tests failed"
echo echo 'DLC_DATABASE_HOST=localhost DLC_DATABASE_PORT=5432 DLC_DATABASE_USER=postgres DLC_DATABASE_PASSWORD=postgres DLC_DATABASE_NAME=dance_lessons_coach_bdd_test DLC_DATABASE_SSL_MODE=disable go test ./features/... -v'
exit 1
fi

177
scripts/run-bdd-tests.sh.backup Executable file
View File

@@ -0,0 +1,177 @@
#!/bin/bash
# BDD Test Runner Script
# Runs all BDD tests and fails if there are undefined, pending, or skipped steps
set -e
echo "🧪 Running BDD Tests..."
cd /Users/gabrielradureau/Work/Vibe/DanceLessonsCoach
# Check if we're in CI environment
if [ -n "$GITHUB_ACTIONS" ] || [ -n "$GITEA_ACTIONS" ]; then
# CI environment - PostgreSQL is already running as a service
echo "🏗️ CI environment detected"
echo "🐋 PostgreSQL service is already running"
# Check if database is accessible
echo "📦 Checking PostgreSQL connectivity..."
if ! pg_isready -h postgres -p 5432 -U postgres -d dance_lessons_coach_bdd_test; then
echo "❌ PostgreSQL is not ready or accessible"
exit 1
fi
echo "✅ PostgreSQL is ready!"
else
# Local environment - use docker compose
echo "💻 Local environment detected"
# Check if PostgreSQL container is running, start it if not
echo "🐋 Checking PostgreSQL container..."
if ! docker ps --format '{{.Names}}' | grep -q "^dance-lessons-coach-postgres$"; then
echo "🐋 Starting PostgreSQL container..."
docker compose up -d postgres
# Wait for PostgreSQL to be ready
echo "⏳ Waiting for PostgreSQL to be ready..."
max_attempts=30
attempt=0
while [ $attempt -lt $max_attempts ]; do
if docker exec dance-lessons-coach-postgres pg_isready -U postgres 2>/dev/null; then
echo "✅ PostgreSQL is ready!"
break
fi
attempt=$((attempt + 1))
sleep 1
done
if [ $attempt -eq $max_attempts ]; then
echo "❌ PostgreSQL failed to start"
exit 1
fi
# Create BDD test database (separate from development database)
echo "📦 Creating BDD test database..."
# Drop database if it exists, then create fresh
docker exec dance-lessons-coach-postgres psql -U postgres -c "DROP DATABASE IF EXISTS dance_lessons_coach_bdd_test;"
if docker exec dance-lessons-coach-postgres createdb -U postgres dance_lessons_coach_bdd_test; then
echo "✅ BDD test database created successfully!"
else
echo "❌ Failed to create BDD test database"
exit 1
fi
else
echo "✅ PostgreSQL container is already running"
# Check if BDD test database exists, create if not
echo "📦 Checking BDD test database..."
if docker exec dance-lessons-coach-postgres psql -U postgres -lqt | cut -d \| -f 1 | grep -qw "dance_lessons_coach_bdd_test"; then
echo "✅ BDD test database already exists"
else
echo "📦 Creating BDD test database..."
if docker exec dance-lessons-coach-postgres createdb -U postgres dance_lessons_coach_bdd_test; then
echo "✅ BDD test database created successfully!"
else
echo "❌ Failed to create BDD test database"
exit 1
fi
fi
fi
else
# CI environment - PostgreSQL is already running as a service
echo "🏗️ CI environment detected"
echo "🐋 PostgreSQL service is already running"
# Check if database is accessible
echo "📦 Checking PostgreSQL connectivity..."
if ! pg_isready -h postgres -p 5432 -U postgres -d dance_lessons_coach_bdd_test; then
echo "❌ PostgreSQL is not ready or accessible"
exit 1
fi
echo "✅ PostgreSQL is ready!"
else
# Check if PostgreSQL container is running, start it if not
echo "🐋 Checking PostgreSQL container..."
if ! docker ps --format '{{.Names}}' | grep -q "^dance-lessons-coach-postgres$"; then
echo "🐋 Starting PostgreSQL container..."
docker compose up -d postgres
# Wait for PostgreSQL to be ready
echo "⏳ Waiting for PostgreSQL to be ready..."
max_attempts=30
attempt=0
while [ $attempt -lt $max_attempts ]; do
if docker exec dance-lessons-coach-postgres pg_isready -U postgres 2>/dev/null; then
echo "✅ PostgreSQL is ready!"
break
fi
attempt=$((attempt + 1))
sleep 1
done
if [ $attempt -eq $max_attempts ]; then
echo "❌ PostgreSQL failed to start"
exit 1
fi
# Create BDD test database (separate from development database)
echo "📦 Creating BDD test database..."
# Drop database if it exists, then create fresh
docker exec dance-lessons-coach-postgres psql -U postgres -c "DROP DATABASE IF EXISTS dance_lessons_coach_bdd_test;"
if docker exec dance-lessons-coach-postgres createdb -U postgres dance_lessons_coach_bdd_test; then
echo "✅ BDD test database created successfully!"
else
echo "❌ Failed to create BDD test database"
exit 1
fi
else
echo "✅ PostgreSQL container is already running"
# Check if BDD test database exists, create if not
echo "📦 Checking BDD test database..."
if docker exec dance-lessons-coach-postgres psql -U postgres -lqt | cut -d \| -f 1 | grep -qw "dance_lessons_coach_bdd_test"; then
echo "✅ BDD test database already exists"
else
echo "📦 Creating BDD test database..."
if docker exec dance-lessons-coach-postgres createdb -U postgres dance_lessons_coach_bdd_test; then
echo "✅ BDD test database created successfully!"
else
echo "❌ Failed to create BDD test database"
exit 1
fi
fi
fi
fi
# Run the BDD tests
test_output=$(go test ./features/... -v 2>&1)
test_exit_code=$?
echo "$test_output"
# Check for undefined steps
if echo "$test_output" | grep -q "undefined"; then
echo "❌ FAILED: Found undefined steps"
exit 1
fi
# Check for pending steps
if echo "$test_output" | grep -q "pending"; then
echo "❌ FAILED: Found pending steps"
exit 1
fi
# Check for skipped steps
if echo "$test_output" | grep -q "skipped"; then
echo "❌ FAILED: Found skipped steps"
exit 1
fi
# Check if tests passed
if [ $test_exit_code -eq 0 ]; then
echo "✅ All BDD tests passed successfully!"
exit 0
else
echo "❌ BDD tests failed"
echo 'DLC_DATABASE_HOST=localhost DLC_DATABASE_PORT=5432 DLC_DATABASE_USER=postgres DLC_DATABASE_PASSWORD=postgres DLC_DATABASE_NAME=dance_lessons_coach_bdd_test DLC_DATABASE_SSL_MODE=disable go test ./features/... -v'
exit 1
fi

View File

@@ -1,10 +1,10 @@
#!/bin/bash
# DanceLessonsCoach Server Start Script
# dance-lessons-coach Server Start Script
# This script starts the server in the background and provides control functions
# Configuration
PROJECT_DIR="/Users/gabrielradureau/Work/Vibe/DanceLessonsCoach"
PROJECT_DIR="/Users/gabrielradureau/Work/Vibe/dance-lessons-coach"
SERVER_CMD="go run ./cmd/server"
LOG_FILE="server.log"
PID_FILE="server.pid"
@@ -14,7 +14,7 @@ cd "$PROJECT_DIR" || { echo "Failed to change to project directory"; exit 1; }
# Function to start the server
start_server() {
echo "Starting DanceLessonsCoach server..."
echo "Starting dance-lessons-coach server..."
# Check if server is already running
if [ -f "$PID_FILE" ]; then

View File

@@ -1,20 +1,20 @@
#!/bin/bash
# DanceLessonsCoach Graceful Shutdown Test Script
# dance-lessons-coach Graceful Shutdown Test Script
# This script tests the complete server lifecycle with JSON logging
# and validates that all shutdown logs are present
set -e
# Configuration
PROJECT_DIR="/Users/gabrielradureau/Work/Vibe/DanceLessonsCoach"
PROJECT_DIR="/Users/gabrielradureau/Work/Vibe/dance-lessons-coach"
SERVER_CMD="./scripts/start-server.sh"
LOG_FILE="server.log"
PID_FILE="server.pid"
TEST_LOG="shutdown_test.log"
# Colors for output - use simple echo -e with inline ANSI codes
echo -e "\033[1;34m=== DanceLessonsCoach Graceful Shutdown Test ===\033[0m"
echo -e "\033[1;34m=== dance-lessons-coach Graceful Shutdown Test ===\033[0m"
echo ""
# Clean up any existing server

View File

@@ -3,7 +3,7 @@
# Simulates the CI/CD pipeline but builds Docker image locally
# Use this for local development and testing without Gitea
set -e
set -eu
echo "🚀 Local CI/CD Testing"
echo "======================"
@@ -16,53 +16,162 @@ if ! command -v go >/dev/null 2>&1; then
exit 1
fi
# Assume Docker is available (required for this workflow)
if ! command -v docker >/dev/null 2>&1; then
echo "⚠️ Docker not found. Docker build steps will be skipped"
HAS_DOCKER=false
else
HAS_DOCKER=true
echo " Docker is required for this CI/CD workflow"
echo "Please install Docker and Docker Compose plugin"
exit 1
fi
# Check for docker compose plugin
if ! docker compose version >/dev/null 2>&1; then
echo "⚠️ Docker Compose plugin not found. Installing..."
sudo apt-get update && sudo apt-get install -y docker-compose-plugin
fi
echo "✅ Environment ready"
echo ""
# 2. Install dependencies
echo "2. Installing dependencies..."
go mod tidy
echo "✅ Dependencies installed"
# 2. Calculate dependency hash (match CI workflow)
echo "2. Calculating dependency hash..."
# Use shasum on macOS, sha256sum on Linux
if command -v sha256sum >/dev/null 2>&1; then
export DEPS_HASH=$(sha256sum go.mod go.sum | sha256sum | cut -d' ' -f1 | head -c 12)
else
export DEPS_HASH=$(shasum -a 256 go.mod go.sum | shasum -a 256 | cut -d' ' -f1 | head -c 12)
fi
echo "Dependency hash: $DEPS_HASH"
echo "✅ Dependency hash calculated"
echo ""
# 3. Install swag and generate docs
echo "3. Generating Swagger documentation..."
if [ ! -f pkg/server/docs/swagger.json ]; then
echo "📝 Generating Swagger docs..."
go install github.com/swaggo/swag/cmd/swag@latest
cd pkg/server && go generate
cd ../..
echo "✅ Swagger documentation generated"
# 3. Check for Docker cache
echo "3. Checking for Docker build cache..."
IMAGE_NAME="gitea.arcodange.lab/arcodange/dance-lessons-coach-build-cache:$DEPS_HASH"
# Try to pull the cache image
if docker pull "$IMAGE_NAME" >/dev/null 2>&1; then
echo "✅ Cache hit - using existing build cache"
USE_DOCKER_CACHE=true
else
echo "✅ Swagger documentation already exists"
echo "⚠️ Cache miss - will build without cache"
USE_DOCKER_CACHE=false
fi
echo ""
# 4. Build and test
echo "4. Building and testing..."
go build ./...
# 4. Start PostgreSQL with Docker Compose
echo "4. Starting PostgreSQL..."
docker compose -f docker-compose.yml up -d postgres
# Wait for PostgreSQL to be ready
echo "Waiting for PostgreSQL to be ready..."
for i in {1..30}; do
if docker exec dance-lessons-coach-postgres pg_isready -U postgres; then
echo "✅ PostgreSQL is ready!"
break
fi
echo "Waiting for PostgreSQL... ($i/30)"
sleep 2
done
# Set PostgreSQL environment variables for BDD tests
export DLC_DATABASE_HOST="localhost" # PostgreSQL port is mapped to host
export DLC_DATABASE_PORT=5432
export DLC_DATABASE_USER=postgres
export DLC_DATABASE_PASSWORD=postgres
export DLC_DATABASE_NAME=dance_lessons_coach_bdd_test
export DLC_DATABASE_SSL_MODE=disable
echo ""
# 5. Install dependencies
if [ "$USE_DOCKER_CACHE" = true ]; then
echo "5. Checking dependencies..."
echo "✅ Using pre-installed dependencies from Docker cache"
else
echo "5. Installing dependencies..."
go mod tidy
fi
echo "✅ Dependencies ready"
echo ""
# 6. Generate Swagger Docs
if [ "$USE_DOCKER_CACHE" = true ]; then
echo "6. Generating Swagger documentation..."
echo "Running in Docker container..."
docker run --rm \
--network dance-lessons-coach-network \
-v "$(pwd):/workspace" \
-w /workspace/pkg/server \
"$IMAGE_NAME" \
sh -c "go generate"
else
echo "6. Generating Swagger documentation..."
echo "Running natively..."
cd pkg/server && go generate
cd ../..
fi
echo "✅ Swagger documentation generated"
echo ""
# 7. Build and test
if [ "$USE_DOCKER_CACHE" = true ]; then
echo "7. Building and testing..."
echo "Running in Docker container..."
docker run --rm \
--network dance-lessons-coach-network \
-v "$(pwd):/workspace" \
-w /workspace \
"$IMAGE_NAME" \
sh -c "go build ./..."
else
echo "7. Building and testing..."
echo "Running natively..."
go build ./...
fi
echo "✅ Code compiled successfully"
go test ./... -cover -v
if [ "$USE_DOCKER_CACHE" = true ]; then
echo "Running in Docker container with PostgreSQL..."
docker run --rm \
--network dance-lessons-coach-network \
-v "$(pwd):/workspace" \
-w /workspace \
-e DLC_DATABASE_HOST=dance-lessons-coach-postgres \
-e DLC_DATABASE_PORT=5432 \
-e DLC_DATABASE_USER=postgres \
-e DLC_DATABASE_PASSWORD=postgres \
-e DLC_DATABASE_NAME=dance_lessons_coach_bdd_test \
-e DLC_DATABASE_SSL_MODE=disable \
"$IMAGE_NAME" \
sh -c "go test ./... -coverprofile=coverage.out -v && go tool cover -func=coverage.out > coverage.txt"
else
echo "Running natively with Docker Compose PostgreSQL..."
go test ./... -coverprofile=coverage.out -v
go tool cover -func=coverage.out > coverage.txt
fi
echo "✅ Tests passed"
echo ""
# 5. Build binaries
echo "5. Building binaries..."
./scripts/build.sh
# 8. Build binaries
if [ "$USE_DOCKER_CACHE" = true ]; then
echo "8. Building binaries..."
echo "Running in Docker container..."
docker run --rm \
--network dance-lessons-coach-network \
-v "$(pwd):/workspace" \
-w /workspace \
"$IMAGE_NAME" \
sh -c "./scripts/build.sh"
else
echo "8. Building binaries..."
echo "Running natively..."
./scripts/build.sh
fi
echo "✅ Binaries built"
ls -la bin/
echo ""
# 6. Version bump simulation
echo "6. Version bump simulation..."
# 9. Version bump simulation
echo "9. Version bump simulation..."
LAST_COMMIT=$(git log -1 --pretty=%B | head -1)
echo "Last commit: $LAST_COMMIT"
@@ -85,152 +194,170 @@ CURRENT_VERSION="$MAJOR.$MINOR.$PATCH${PRERELEASE:+-$PRERELEASE}"
echo "📊 Current version: $CURRENT_VERSION"
echo ""
# 7. Local Docker build instructions
if [ "$HAS_DOCKER" = true ]; then
echo "🐳 LOCAL DOCKER BUILD INSTRUCTIONS"
echo "================================"
echo ""
echo "1. Build Docker image locally:"
echo " docker build -t dance-lessons-coach:$CURRENT_VERSION ."
echo ""
echo "2. Tag the image:"
echo " docker tag dance-lessons-coach:$CURRENT_VERSION dance-lessons-coach:latest"
echo ""
echo "3. Test the local image (check port availability first):"
echo " docker run -d -p 8080:8080 dance-lessons-coach:$CURRENT_VERSION"
echo " # Or use alternative port if 8080 is in use:"
echo " docker run -d -p 8081:8080 dance-lessons-coach:$CURRENT_VERSION"
echo ""
echo "4. Branch-specific container naming (recommended):"
echo " BRANCH=\"(git rev-parse --abbrev-ref HEAD | tr '/' '-')"
echo " docker run -d -p 8080:8080 --name dance-lessons-coach-\"$BRANCH\" dance-lessons-coach:$CURRENT_VERSION"
echo ""
echo "5. Test API endpoints:"
echo " curl http://localhost:8080/api/health"
echo " curl http://localhost:8080/api/v1/greet/YourName"
echo ""
echo "5. Clean up:"
echo " docker stop <container_id> && docker rm <container_id>"
echo ""
echo "💡 Tip: Use 'docker images' to see your built images"
echo "💡 Use 'docker ps' to see running containers"
echo ""
# Ask if user wants to build Docker image now
read -p "🚀 Do you want to build the Docker image now? (y/n): " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo "🐳 Building Docker image..."
# 10. Local Docker build instructions
echo "🐳 LOCAL DOCKER BUILD INSTRUCTIONS"
echo "================================"
echo ""
echo "1. Build Docker image locally (development):"
echo " docker build -t dance-lessons-coach:$CURRENT_VERSION ."
echo ""
echo "2. Build production image using docker/Dockerfile.prod:"
echo " # Note: Local docker/Dockerfile.prod uses 'latest' tag for testing"
echo " docker build -t dance-lessons-coach-prod:$CURRENT_VERSION -f docker/Dockerfile.prod ."
echo " # For CI/CD, the workflow generates correct docker/Dockerfile.prod with dependency hash"
echo ""
echo "3. Compare image sizes:"
echo " docker images | grep dance-lessons-coach"
echo ""
echo "4. Tag the image:"
echo " docker tag dance-lessons-coach:$CURRENT_VERSION dance-lessons-coach:latest"
echo ""
echo "5. Test the local image (check port availability first):"
echo " docker run -d -p 8080:8080 dance-lessons-coach:$CURRENT_VERSION"
echo " # Or use alternative port if 8080 is in use:"
echo " docker run -d -p 8081:8080 dance-lessons-coach:$CURRENT_VERSION"
echo ""
echo "6. Branch-specific container naming (recommended):"
echo " BRANCH=\"$(git rev-parse --abbrev-ref HEAD | tr '/' '-')\""
echo " docker run -d -p 8080:8080 --name dance-lessons-coach-\"$BRANCH\" dance-lessons-coach:$CURRENT_VERSION"
echo ""
echo "7. Test API endpoints:"
echo " curl http://localhost:8080/api/health"
echo " curl http://localhost:8080/api/v1/greet/YourName"
echo ""
echo "8. Clean up:"
echo " docker stop <container_id> && docker rm <container_id>"
echo ""
echo "💡 Tip: Use 'docker images' to see your built images"
echo "💡 Use 'docker ps' to see running containers"
echo ""
# Ask if user wants to build Docker image now
read -p "🚀 Do you want to build the Docker image now? (y/n): " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo "🐳 Building Docker image..."
read -p "📋 Build (d)development or (p)production image? [d/p]: " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Pp]$ ]]; then
echo "🏗️ Building production image with docker/Dockerfile.prod..."
docker build -t dance-lessons-coach-prod:$CURRENT_VERSION -f docker/Dockerfile.prod .
docker tag dance-lessons-coach-prod:$CURRENT_VERSION dance-lessons-coach-prod:latest
echo "✅ Production Docker image built: dance-lessons-coach-prod:$CURRENT_VERSION"
CONTAINER_IMAGE="dance-lessons-coach-prod:$CURRENT_VERSION"
else
echo "🏗️ Building development image with Dockerfile..."
docker build -t dance-lessons-coach:$CURRENT_VERSION .
docker tag dance-lessons-coach:$CURRENT_VERSION dance-lessons-coach:latest
echo "✅ Docker image built: dance-lessons-coach:$CURRENT_VERSION"
echo ""
# Check if port 8080 is available
echo "🔍 Checking port availability..."
if lsof -i :8080 > /dev/null 2>&1; then
echo "⚠️ Port 8080 is already in use"
read -p "🚀 Do you want to use a different port? (y/n): " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
read -p "Enter port number (e.g., 8081): " CUSTOM_PORT
echo ""
PORT=$CUSTOM_PORT
else
echo " Using port 8080 anyway (may fail if service is running)"
PORT=8080
fi
echo " Development Docker image built: dance-lessons-coach:$CURRENT_VERSION"
CONTAINER_IMAGE="dance-lessons-coach:$CURRENT_VERSION"
fi
echo ""
# Check if port 8080 is available
echo "🔍 Checking port availability..."
if lsof -i :8080 > /dev/null 2>&1; then
echo "⚠️ Port 8080 is already in use"
read -p "🚀 Do you want to use a different port? (y/n): " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
read -p "Enter port number (e.g., 8081): " CUSTOM_PORT
echo ""
PORT=$CUSTOM_PORT
else
echo "✅ Port 8080 is available"
echo " Using port 8080 anyway (may fail if service is running)"
PORT=8080
fi
read -p "🚀 Do you want to run the container now on port $PORT? (y/n): " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
# Get current branch name for container naming
BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD | tr '/' '-')
CONTAINER_NAME="dance-lessons-coach-$BRANCH_NAME"
echo "🐳 Preparing container '$CONTAINER_NAME' on port $PORT..."
# Remove existing container if it exists
if docker ps -a --format '{{.Names}}' | grep -q "^$CONTAINER_NAME$"; then
echo "⚠️ Container '$CONTAINER_NAME' already exists - removing it..."
docker stop "$CONTAINER_NAME" > /dev/null 2>&1 || true
docker rm "$CONTAINER_NAME" > /dev/null 2>&1 || true
echo "✅ Old container removed"
fi
# Also remove the generic test container if it exists
if docker ps -a --format '{{.Names}}' | grep -q "^dance-lessons-coach-test$"; then
echo "⚠️ Generic test container exists - removing it..."
docker stop dance-lessons-coach-test > /dev/null 2>&1 || true
docker rm dance-lessons-coach-test > /dev/null 2>&1 || true
echo "✅ Old generic container removed"
fi
echo "🐳 Starting container '$CONTAINER_NAME' on port $PORT..."
docker run -d -p $PORT:8080 --name "$CONTAINER_NAME" dance-lessons-coach:$CURRENT_VERSION
echo "✅ Container '$CONTAINER_NAME' started on port $PORT"
echo ""
# Wait for container to be ready
echo "🕒 Waiting for container to be ready..."
MAX_ATTEMPTS=10
ATTEMPT=1
READY=false
while [ $ATTEMPT -le $MAX_ATTEMPTS ]; do
if curl -s http://localhost:$PORT/api/health | grep -q "healthy"; then
READY=true
break
fi
sleep 1
ATTEMPT=$((ATTEMPT + 1))
echo "🕒 Attempt $ATTEMPT/$MAX_ATTEMPTS..."
done
if [ "$READY" = true ]; then
echo "✅ Container is ready!"
else
echo "❌ Container failed to start properly"
echo "📋 Container logs:"
docker logs dance-lessons-coach-test
echo ""
echo "💡 Check container status with: docker ps -a"
echo "💡 View full logs with: docker logs dance-lessons-coach-test"
continue # Skip endpoint testing
fi
echo "📋 Testing endpoints..."
if curl -s http://localhost:$PORT/api/health | grep -q "healthy"; then
echo "✅ Health check passed"
else
echo "❌ Health check failed"
fi
if curl -s http://localhost:$PORT/api/v1/greet/ | grep -q "Hello"; then
echo "✅ Greet endpoint working"
else
echo "❌ Greet endpoint failed"
fi
echo ""
echo "📖 Swagger UI available at: http://localhost:$PORT/swagger/"
echo "💡 Press Ctrl+C to stop the container when done"
echo " Or run: docker stop $CONTAINER_NAME && docker rm $CONTAINER_NAME"
fi
else
echo "✅ Port 8080 is available"
PORT=8080
fi
read -p "🚀 Do you want to run the container now on port $PORT? (y/n): " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
# Get current branch name for container naming
BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD | tr '/' '-')
CONTAINER_NAME="dance-lessons-coach-$BRANCH_NAME"
echo "🐳 Preparing container '$CONTAINER_NAME' on port $PORT..."
# Remove existing container if it exists
if docker ps -a --format '{{.Names}}' | grep -q "^$CONTAINER_NAME$"; then
echo "⚠️ Container '$CONTAINER_NAME' already exists - removing it..."
docker stop "$CONTAINER_NAME" > /dev/null 2>&1 || true
docker rm "$CONTAINER_NAME" > /dev/null 2>&1 || true
echo "✅ Old container removed"
fi
# Also remove the generic test container if it exists
if docker ps -a --format '{{.Names}}' | grep -q "^dance-lessons-coach-test$"; then
echo "⚠️ Generic test container exists - removing it..."
docker stop dance-lessons-coach-test > /dev/null 2>&1 || true
docker rm dance-lessons-coach-test > /dev/null 2>&1 || true
echo "✅ Old generic container removed"
fi
echo "🐳 Starting container '$CONTAINER_NAME' on port $PORT..."
docker run -d -p $PORT:8080 --name "$CONTAINER_NAME" "$CONTAINER_IMAGE"
echo "✅ Container '$CONTAINER_NAME' started on port $PORT"
echo ""
# Wait for container to be ready
echo "🕒 Waiting for container to be ready..."
MAX_ATTEMPTS=10
ATTEMPT=1
READY=false
while [ $ATTEMPT -le $MAX_ATTEMPTS ]; do
if curl -s http://localhost:$PORT/api/health | grep -q "healthy"; then
READY=true
break
fi
sleep 1
ATTEMPT=$((ATTEMPT + 1))
echo "🕒 Attempt $ATTEMPT/$MAX_ATTEMPTS..."
done
if [ "$READY" = true ]; then
echo "✅ Container is ready!"
else
echo " Container failed to start properly"
echo "📋 Container logs:"
docker logs dance-lessons-coach-test
echo ""
echo "💡 Check container status with: docker ps -a"
echo "💡 View full logs with: docker logs dance-lessons-coach-test"
continue # Skip endpoint testing
fi
echo "📋 Testing endpoints..."
if curl -s http://localhost:$PORT/api/health | grep -q "healthy"; then
echo "✅ Health check passed"
else
echo "❌ Health check failed"
fi
if curl -s http://localhost:$PORT/api/v1/greet/ | grep -q "Hello"; then
echo "✅ Greet endpoint working"
else
echo "❌ Greet endpoint failed"
fi
echo ""
echo "📖 Swagger UI available at: http://localhost:$PORT/swagger/"
echo "💡 Press Ctrl+C to stop the container when done"
echo " Or run: docker stop $CONTAINER_NAME && docker rm $CONTAINER_NAME"
fi
else
echo " Docker not available - skipping Docker build instructions"
fi
echo ""
@@ -238,18 +365,22 @@ echo "✅ LOCAL CI/CD TEST COMPLETE"
echo "==========================="
echo ""
echo "📋 What was tested:"
echo " ✅ Dependency hash calculation (matching CI workflow)"
echo " ✅ Docker cache detection and usage"
echo " ✅ PostgreSQL service with Docker Compose"
echo " ✅ Go dependencies installation"
echo " ✅ Swagger documentation generation"
echo " ✅ Code compilation"
echo " ✅ Unit tests with coverage"
echo " ✅ Binary build"
echo " ✅ Version bump simulation"
if [ "$HAS_DOCKER" = true ]; then
echo " ✅ Docker build (if chosen)"
fi
echo " ✅ Docker build (development and/or production if chosen)"
echo ""
echo "🎯 When ready for production:"
echo " Push to main branch to trigger full CI/CD pipeline"
echo " Docker image will be built and pushed to Gitea Container Registry"
echo ""
echo "💡 Local testing complete! Your changes are ready for CI/CD."
echo "💡 Local testing complete! Your changes are ready for CI/CD."
echo "💡 This script now matches the Gitea workflow structure and behavior."
# ⚠️ IMPORTANT: Local Dockerfile.prod uses 'latest' tag for testing only
# ✅ CI/CD workflow generates correct Dockerfile.prod with dependency hash

View File

@@ -1,15 +1,15 @@
#!/bin/bash
# DanceLessonsCoach OpenTelemetry Test Script
# dance-lessons-coach OpenTelemetry Test Script
# This script tests OpenTelemetry integration with Jaeger
set -e
echo -e "\033[1;34m=== DanceLessonsCoach OpenTelemetry Test ===\033[0m"
echo -e "\033[1;34m=== dance-lessons-coach OpenTelemetry Test ===\033[0m"
echo ""
# Configuration
PROJECT_DIR="/Users/gabrielradureau/Work/Vibe/DanceLessonsCoach"
PROJECT_DIR="/Users/gabrielradureau/Work/Vibe/dance-lessons-coach"
SERVER_CMD="./scripts/start-server.sh"
LOG_FILE="server.log"
PID_FILE="server.pid"
@@ -47,7 +47,7 @@ fi
echo "Starting server with OpenTelemetry enabled..."
DLC_TELEMETRY_ENABLED=true DLC_TELEMETRY_OTLP_ENDPOINT="localhost:4317" DLC_TELEMETRY_INSECURE=true \
DLC_TELEMETRY_SERVICE_NAME="DanceLessonsCoach" $SERVER_CMD start
DLC_TELEMETRY_SERVICE_NAME="dance-lessons-coach" $SERVER_CMD start
sleep 3
echo "Testing API endpoints..."
@@ -77,7 +77,7 @@ echo -e "\033[0;32m✅ OpenTelemetry Test Complete!\033[0m"
echo ""
echo "To view traces in Jaeger:"
echo "1. Open http://localhost:16686 in your browser"
echo "2. Select 'DanceLessonsCoach' service"
echo "2. Select 'dance-lessons-coach' service"
echo "3. Click 'Find Traces' button"
echo ""
echo "You should see traces for:"

View File

@@ -171,4 +171,4 @@ echo "💡 Next Steps:"
echo " 1. Test with Docker: ./scripts/test-cicd-simple.sh"
echo " 2. Commit changes: git commit -m '🤖 ci: validate workflow'"
echo " 3. Push to trigger: git push origin main"
echo " 4. Monitor pipeline: https://gitea.arcodange.lab/arcodange/DanceLessonsCoach/actions"
echo " 4. Monitor pipeline: https://gitea.arcodange.lab/arcodange/dance-lessons-coach/actions"

View File

@@ -1,5 +1,5 @@
#!/bin/bash
# DanceLessonsCoach Version Bump Script
# dance-lessons-coach Version Bump Script
# Usage: ./scripts/version-bump.sh [major|minor|patch|pre|release]
set -e
@@ -81,7 +81,7 @@ echo "🔜 New version: $NEW_VERSION"
# Update VERSION file
cat > "$VERSION_FILE" << VERSION_EOF
# DanceLessonsCoach Version
# dance-lessons-coach Version
# Current Version (Semantic Versioning)
MAJOR=$MAJOR
@@ -139,7 +139,7 @@ if [ -f "$README_MD" ]; then
# Use awk to update version badge
awk -v new_version="$NEW_VERSION" '{
if ($0 ~ /Version.*badge.*version/) {
print "[![Version](https://img.shields.io/badge/version-" new_version "-blue.svg)](https://gitea.arcodange.fr/arcodange/DanceLessonsCoach/releases)"
print "[![Version](https://img.shields.io/badge/version-" new_version "-blue.svg)](https://gitea.arcodange.fr/arcodange/dance-lessons-coach/releases)"
} else {
print $0
}