🤖 feat: simplify CI/CD structure and add Docker workflow
Some checks failed
Some checks failed
- Rename ci-cd.yaml to go-ci-cd.yaml for clarity - Add dockerimage.yaml workflow for Docker builds - Create Dockerfile for production deployment - Add comprehensive CI/CD documentation - Create contributor-quickstart.sh for easy validation - Update all scripts to handle both workflow files - Fix event triggers to run on all relevant pushes - Remove redundant YAML syntax validation - Improve workflow validation for Arcodange conventions BREAKING CHANGE: ci-cd.yaml renamed to go-ci-cd.yaml See scripts/cicd/README.md for complete documentation. Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
83
.gitea/workflows/dockerimage.yaml
Normal file
83
.gitea/workflows/dockerimage.yaml
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
---
|
||||||
|
# DanceLessonsCoach Docker Image Build Workflow
|
||||||
|
# Based on Arcodange webapp conventions
|
||||||
|
# Builds and publishes Docker images to Gitea Container Registry
|
||||||
|
|
||||||
|
name: Docker Build and Publish
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch: {}
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
tags:
|
||||||
|
- 'v*.*.*'
|
||||||
|
paths-ignore:
|
||||||
|
- 'README.md'
|
||||||
|
- 'doc/**'
|
||||||
|
- 'adr/**'
|
||||||
|
- '.gitea/**'
|
||||||
|
|
||||||
|
# cancel any previously-started, yet still active runs of this workflow on the same branch
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.ref }}-${{ github.workflow }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
# Arcodange-specific environment variables
|
||||||
|
env:
|
||||||
|
GITEA_INTERNAL: "https://gitea.arcodange.lab/"
|
||||||
|
GITEA_EXTERNAL: "https://gitea.arcodange.fr/"
|
||||||
|
GITEA_ORG: "arcodange"
|
||||||
|
GITEA_REPO: "DanceLessonsCoach"
|
||||||
|
CI_REGISTRY: "gitea.arcodange.lab"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-push-image:
|
||||||
|
name: Build and Push Docker Image
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Login to Gitea Container Registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ${{ env.CI_REGISTRY }}
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.PACKAGES_TOKEN }}
|
||||||
|
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Build and push image to Gitea Container Registry
|
||||||
|
run: |-
|
||||||
|
# Determine tags based on event type
|
||||||
|
if [[ "${{ github.ref }}" == refs/tags/* ]]; then
|
||||||
|
# For tags, use the tag name and latest
|
||||||
|
TAGS="${{ github.ref_name }} latest"
|
||||||
|
else
|
||||||
|
# For main branch, use commit SHA and latest
|
||||||
|
TAGS="latest ${{ github.sha }}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Building Docker image with tags: $TAGS"
|
||||||
|
docker build -t dance-lessons-coach .
|
||||||
|
|
||||||
|
for TAG in $TAGS; do
|
||||||
|
IMAGE_NAME="${{ env.CI_REGISTRY }}/${{ env.GITEA_ORG }}/${{ env.GITEA_REPO }}:$TAG"
|
||||||
|
echo "Tagging and pushing: $IMAGE_NAME"
|
||||||
|
docker tag dance-lessons-coach "$IMAGE_NAME"
|
||||||
|
docker push "$IMAGE_NAME"
|
||||||
|
done
|
||||||
|
|
||||||
|
- name: Show published images
|
||||||
|
run: |-
|
||||||
|
echo "📦 Published Docker images:"
|
||||||
|
if [[ "${{ github.ref }}" == refs/tags/* ]]; then
|
||||||
|
echo " - ${{ env.CI_REGISTRY }}/${{ env.GITEA_ORG }}/${{ env.GITEA_REPO }}:${{ github.ref_name }}"
|
||||||
|
echo " - ${{ env.CI_REGISTRY }}/${{ env.GITEA_ORG }}/${{ env.GITEA_REPO }}:latest"
|
||||||
|
else
|
||||||
|
echo " - ${{ env.CI_REGISTRY }}/${{ env.GITEA_ORG }}/${{ env.GITEA_REPO }}:latest"
|
||||||
|
echo " - ${{ env.CI_REGISTRY }}/${{ env.GITEA_ORG }}/${{ env.GITEA_REPO }}:${{ github.sha }}"
|
||||||
|
fi
|
||||||
@@ -3,10 +3,10 @@
|
|||||||
# Follows Arcodange conventions from webapp workflow
|
# Follows Arcodange conventions from webapp workflow
|
||||||
# Uses .gitea/workflows/ directory and internal registry
|
# Uses .gitea/workflows/ directory and internal registry
|
||||||
|
|
||||||
name: DanceLessonsCoach CI/CD
|
name: Go CI/CD Pipeline
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch: true
|
workflow_dispatch: {}
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
@@ -18,10 +18,16 @@ on:
|
|||||||
- 'README.md'
|
- 'README.md'
|
||||||
- 'doc/**'
|
- 'doc/**'
|
||||||
- 'adr/**'
|
- 'adr/**'
|
||||||
|
- '.gitea/**'
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
types: [opened, synchronize, reopened, labeled]
|
types: [opened, synchronize, reopened, labeled]
|
||||||
|
paths-ignore:
|
||||||
|
- 'README.md'
|
||||||
|
- 'doc/**'
|
||||||
|
- 'adr/**'
|
||||||
|
- '.gitea/**'
|
||||||
|
|
||||||
# cancel any previously-started runs of this workflow on the same branch
|
# cancel any previously-started runs of this workflow on the same branch
|
||||||
concurrency:
|
concurrency:
|
||||||
@@ -94,7 +100,7 @@ jobs:
|
|||||||
echo "✅ Code is properly formatted"
|
echo "✅ Code is properly formatted"
|
||||||
|
|
||||||
workflow-validation:
|
workflow-validation:
|
||||||
name: Workflow Validation
|
name: Arcodange Workflow Validation
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: github.event_name == 'pull_request' || contains(github.ref, 'ci/')
|
if: github.event_name == 'pull_request' || contains(github.ref, 'ci/')
|
||||||
|
|
||||||
@@ -102,25 +108,16 @@ jobs:
|
|||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Validate workflow syntax
|
- name: Run Arcodange workflow validation
|
||||||
run: |
|
|
||||||
if command -v yq >/dev/null 2>&1; then
|
|
||||||
yq eval '.' .gitea/workflows/ci-cd.yaml > /dev/null
|
|
||||||
echo "✅ Workflow YAML syntax is valid"
|
|
||||||
else
|
|
||||||
echo "⚠️ yq not installed, skipping YAML validation"
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Run workflow validation script
|
|
||||||
run: ./scripts/cicd/validate-workflow.sh
|
run: ./scripts/cicd/validate-workflow.sh
|
||||||
|
|
||||||
- name: Check for breaking changes
|
- name: Check for workflow changes in PR
|
||||||
if: github.event_name == 'pull_request'
|
if: github.event_name == 'pull_request'
|
||||||
run: |
|
run: |
|
||||||
echo "🔍 Checking workflow changes..."
|
echo "🔍 Checking workflow changes..."
|
||||||
changes=$(git diff origin/main -- .gitea/workflows/ci-cd.yaml | grep -q "^-")
|
changes=$(git diff origin/main -- .gitea/workflows/ | grep -q "^-")
|
||||||
if [ $changes ]; then
|
if [ $changes ]; then
|
||||||
echo "⚠️ Changes detected - review recommended"
|
echo "⚠️ Workflow changes detected - review recommended"
|
||||||
else
|
else
|
||||||
echo "✅ No workflow changes"
|
echo "✅ No workflow changes"
|
||||||
fi
|
fi
|
||||||
47
Dockerfile
Normal file
47
Dockerfile
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
# DanceLessonsCoach Docker Image
|
||||||
|
# Multi-stage build for production deployment
|
||||||
|
|
||||||
|
# Stage 1: Build binary
|
||||||
|
FROM golang:1.26.1-alpine AS builder
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy go mod files
|
||||||
|
COPY go.mod go.sum ./
|
||||||
|
RUN go mod download
|
||||||
|
|
||||||
|
# Copy source code
|
||||||
|
COPY . ./
|
||||||
|
|
||||||
|
# Build binary
|
||||||
|
RUN CGO_ENABLED=0 GOOS=linux go build -o /dance-lessons-coach ./cmd/server
|
||||||
|
|
||||||
|
# Stage 2: Final image
|
||||||
|
FROM alpine:3.18
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN apk add --no-cache ca-certificates tzdata
|
||||||
|
|
||||||
|
# Copy binary from builder
|
||||||
|
COPY --from=builder /dance-lessons-coach /app/dance-lessons-coach
|
||||||
|
|
||||||
|
# Copy configuration
|
||||||
|
COPY config.yaml /app/config.yaml
|
||||||
|
|
||||||
|
# Set permissions
|
||||||
|
RUN chmod +x /app/dance-lessons-coach
|
||||||
|
|
||||||
|
# Set timezone
|
||||||
|
ENV TZ=UTC
|
||||||
|
|
||||||
|
# Expose port
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
# Health check
|
||||||
|
HEALTHCHECK --interval=30s --timeout=3s \
|
||||||
|
CMD wget -q --spider http://localhost:8080/api/health || exit 1
|
||||||
|
|
||||||
|
# Entry point
|
||||||
|
ENTRYPOINT ["/app/dance-lessons-coach"]
|
||||||
286
scripts/cicd/README.md
Normal file
286
scripts/cicd/README.md
Normal file
@@ -0,0 +1,286 @@
|
|||||||
|
# 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.
|
||||||
78
scripts/cicd/contributor-quickstart.sh
Executable file
78
scripts/cicd/contributor-quickstart.sh
Executable file
@@ -0,0 +1,78 @@
|
|||||||
|
#!/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!"
|
||||||
@@ -15,37 +15,61 @@ if ! command -v act >/dev/null 2>&1; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if workflow file exists
|
# Check if workflow files exist
|
||||||
if [ ! -f ".gitea/workflows/ci-cd.yaml" ]; then
|
WORKFLOW_FILES=(
|
||||||
echo "❌ Workflow file not found: .gitea/workflows/ci-cd.yaml"
|
".gitea/workflows/go-ci-cd.yaml"
|
||||||
exit 1
|
".gitea/workflows/dockerimage.yaml"
|
||||||
fi
|
)
|
||||||
|
|
||||||
|
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 "✅ act installed and workflow file found"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# 1. Dry run (syntax check only)
|
# 1. Dry run (syntax check only)
|
||||||
echo "1. Running dry run (syntax validation)..."
|
echo "1. Running dry run (syntax validation)..."
|
||||||
if echo 'm' | act -n -W .gitea/workflows/ci-cd.yaml --container-architecture linux/amd64; then
|
ALL_PASSED=true
|
||||||
echo "✅ Dry run completed successfully"
|
|
||||||
|
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
|
else
|
||||||
echo "❌ Dry run failed"
|
echo "❌ Some dry runs failed"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "🎉 Gitea workflow is compatible with GitHub Actions!"
|
echo "🎉 Gitea workflows are compatible with GitHub Actions!"
|
||||||
echo "================================================"
|
echo "=================================================="
|
||||||
echo ""
|
echo ""
|
||||||
echo "📋 Summary:"
|
echo "📋 Summary:"
|
||||||
echo " ✅ Syntax validation passed"
|
echo " ✅ Syntax validation passed for all workflows"
|
||||||
echo " ✅ All jobs parsed correctly"
|
echo " ✅ All jobs parsed correctly"
|
||||||
echo " ✅ Job dependencies resolved"
|
echo " ✅ Job dependencies resolved"
|
||||||
echo " ✅ Conditional execution working"
|
echo " ✅ Conditional execution working"
|
||||||
echo " ✅ Gitea/GitHub Actions compatibility confirmed"
|
echo " ✅ Gitea/GitHub Actions compatibility confirmed"
|
||||||
echo ""
|
echo ""
|
||||||
echo "🚀 You can now test locally without Gitea instance:"
|
echo "🚀 You can now test locally without Gitea instance:"
|
||||||
echo " act -n -W .gitea/workflows/ci-cd.yaml # Dry run"
|
for file in "${WORKFLOW_FILES[@]}"; do
|
||||||
echo " act -W .gitea/workflows/ci-cd.yaml # Full execution"
|
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 ""
|
||||||
echo "💡 Tip: Add this to your pre-commit hook to validate workflows automatically!"
|
echo "💡 Tip: Add this to your pre-commit hook to validate workflows automatically!"
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ fi
|
|||||||
|
|
||||||
# 2. Validate workflow structure
|
# 2. Validate workflow structure
|
||||||
echo "2. Validating workflow structure..."
|
echo "2. Validating workflow structure..."
|
||||||
./scripts/validate-workflow.sh
|
./scripts/cicd/validate-workflow.sh
|
||||||
|
|
||||||
# 3. Check docker-compose configuration
|
# 3. Check docker-compose configuration
|
||||||
echo "3. Checking docker-compose configuration..."
|
echo "3. Checking docker-compose configuration..."
|
||||||
|
|||||||
@@ -20,7 +20,10 @@ echo "✅ YAML linting passed"
|
|||||||
|
|
||||||
# 2. YAML Validation
|
# 2. YAML Validation
|
||||||
echo "2. Running YAML validation..."
|
echo "2. Running YAML validation..."
|
||||||
docker run --rm -v $(pwd):/workspace -w /workspace mikefarah/yq:latest eval '.' .gitea/workflows/ci-cd.yaml > /dev/null
|
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"
|
echo "✅ YAML validation passed"
|
||||||
|
|
||||||
# 3. Workflow Structure Validation
|
# 3. Workflow Structure Validation
|
||||||
|
|||||||
@@ -6,69 +6,85 @@ set -e
|
|||||||
echo "🔍 Validating CI/CD Workflow"
|
echo "🔍 Validating CI/CD Workflow"
|
||||||
echo "================================"
|
echo "================================"
|
||||||
|
|
||||||
# 1. Check workflow file exists
|
# 1. Check workflow files exist
|
||||||
if [ ! -f ".gitea/workflows/ci-cd.yaml" ]; then
|
WORKFLOW_FILES=(
|
||||||
echo "❌ Workflow file not found: .gitea/workflows/ci-cd.yaml"
|
".gitea/workflows/go-ci-cd.yaml"
|
||||||
exit 1
|
".gitea/workflows/dockerimage.yaml"
|
||||||
fi
|
)
|
||||||
|
|
||||||
echo "✅ Workflow file found"
|
for file in "${WORKFLOW_FILES[@]}"; do
|
||||||
|
if [ ! -f "$file" ]; then
|
||||||
# 2. Validate YAML syntax
|
echo "❌ Workflow file not found: $file"
|
||||||
if command -v yq >/dev/null 2>&1; then
|
|
||||||
if ! yq eval '.' .gitea/workflows/ci-cd.yaml > /dev/null 2>&1; then
|
|
||||||
echo "❌ Invalid YAML syntax"
|
|
||||||
yq eval '.' .gitea/workflows/ci-cd.yaml || true
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
echo "✅ YAML syntax valid"
|
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
|
else
|
||||||
echo "⚠️ yq not installed, skipping YAML validation"
|
echo "⚠️ yq not installed, skipping YAML validation"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 3. YAML Linting with custom config
|
# 3. YAML Linting with custom config for all workflows
|
||||||
if command -v yamllint >/dev/null 2>&1; then
|
if command -v yamllint >/dev/null 2>&1; then
|
||||||
if [ -f ".yamllint.yaml" ]; then
|
for file in "${WORKFLOW_FILES[@]}"; do
|
||||||
yamllint -c .yamllint.yaml .gitea/workflows/ci-cd.yaml
|
if [ -f ".yamllint.yaml" ]; then
|
||||||
else
|
yamllint -c .yamllint.yaml "$file"
|
||||||
yamllint .gitea/workflows/ci-cd.yaml
|
else
|
||||||
fi
|
yamllint "$file"
|
||||||
|
fi
|
||||||
|
done
|
||||||
elif docker info >/dev/null 2>&1; then
|
elif docker info >/dev/null 2>&1; then
|
||||||
if [ -f ".yamllint.yaml" ]; then
|
for file in "${WORKFLOW_FILES[@]}"; do
|
||||||
docker run --rm -v $(pwd):/workspace -w /workspace pipelinecomponents/yamllint:latest \
|
if [ -f ".yamllint.yaml" ]; then
|
||||||
yamllint -c .yamllint.yaml .gitea/workflows/ci-cd.yaml
|
docker run --rm -v $(pwd):/workspace -w /workspace pipelinecomponents/yamllint:latest \
|
||||||
else
|
yamllint -c .yamllint.yaml "$file"
|
||||||
docker run --rm -v $(pwd):/workspace -w /workspace pipelinecomponents/yamllint:latest \
|
else
|
||||||
yamllint .gitea/workflows/ci-cd.yaml
|
docker run --rm -v $(pwd):/workspace -w /workspace pipelinecomponents/yamllint:latest \
|
||||||
fi
|
yamllint "$file"
|
||||||
|
fi
|
||||||
|
done
|
||||||
else
|
else
|
||||||
echo "⚠️ Neither yamllint nor docker available, skipping linting"
|
echo "⚠️ Neither yamllint nor docker available, skipping linting"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 3. Check required fields
|
# 3. Check required fields for all workflows
|
||||||
MISSING_FIELDS=()
|
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 command -v yq >/dev/null 2>&1; then
|
if [ -z "$(yq eval '.on' "$file" 2>/dev/null)" ]; then
|
||||||
if [ -z "$(yq eval '.name' .gitea/workflows/ci-cd.yaml 2>/dev/null)" ]; then
|
MISSING_FIELDS+=("on")
|
||||||
MISSING_FIELDS+=("name")
|
fi
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$(yq eval '.on' .gitea/workflows/ci-cd.yaml 2>/dev/null)" ]; then
|
if [ -z "$(yq eval '.jobs' "$file" 2>/dev/null)" ]; then
|
||||||
MISSING_FIELDS+=("on")
|
MISSING_FIELDS+=("jobs")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$(yq eval '.jobs' .gitea/workflows/ci-cd.yaml 2>/dev/null)" ]; then
|
if [ ${#MISSING_FIELDS[@]} -gt 0 ]; then
|
||||||
MISSING_FIELDS+=("jobs")
|
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
|
fi
|
||||||
|
done
|
||||||
if [ ${#MISSING_FIELDS[@]} -gt 0 ]; then
|
|
||||||
echo "❌ Missing required fields: ${MISSING_FIELDS[*]}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "✅ All required fields present"
|
|
||||||
else
|
|
||||||
echo "⚠️ yq not installed, skipping field validation"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 4. Check jobs structure
|
# 4. Check jobs structure
|
||||||
if command -v yq >/dev/null 2>&1; then
|
if command -v yq >/dev/null 2>&1; then
|
||||||
@@ -118,10 +134,17 @@ fi
|
|||||||
echo ""
|
echo ""
|
||||||
echo "🎉 Workflow Validation Successful!"
|
echo "🎉 Workflow Validation Successful!"
|
||||||
echo "================================"
|
echo "================================"
|
||||||
echo "📁 Location: .gitea/workflows/ci-cd.yaml"
|
echo "📁 Workflows validated:"
|
||||||
|
for file in "${WORKFLOW_FILES[@]}"; do
|
||||||
|
echo " - $file"
|
||||||
|
done
|
||||||
if command -v yq >/dev/null 2>&1; then
|
if command -v yq >/dev/null 2>&1; then
|
||||||
JOBS=$(yq eval '.jobs | keys | join(", ")' .gitea/workflows/ci-cd.yaml 2>/dev/null || echo 'Unable to parse')
|
echo "🔧 Summary:"
|
||||||
echo "🔧 Jobs: $JOBS"
|
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
|
else
|
||||||
echo "🔧 Jobs: yq not installed"
|
echo "🔧 Jobs: yq not installed"
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user