mirror of
https://github.com/DRYTRIX/TimeTracker.git
synced 2026-01-14 16:06:38 -06:00
282 lines
9.2 KiB
YAML
282 lines
9.2 KiB
YAML
name: CD - Development Build
|
|
|
|
on:
|
|
push:
|
|
branches: [ develop ]
|
|
workflow_dispatch:
|
|
inputs:
|
|
force_build:
|
|
description: 'Force build even if tests fail'
|
|
required: false
|
|
type: boolean
|
|
default: false
|
|
|
|
env:
|
|
REGISTRY: ghcr.io
|
|
IMAGE_NAME: ${{ github.repository }}
|
|
PYTHON_VERSION: '3.11'
|
|
|
|
jobs:
|
|
# ============================================================================
|
|
# Quick Test Suite for Development
|
|
# ============================================================================
|
|
quick-tests:
|
|
name: Quick Test Suite
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 15
|
|
|
|
services:
|
|
postgres:
|
|
image: postgres:16-alpine
|
|
env:
|
|
POSTGRES_PASSWORD: test_password
|
|
POSTGRES_USER: test_user
|
|
POSTGRES_DB: test_db
|
|
options: >-
|
|
--health-cmd pg_isready
|
|
--health-interval 10s
|
|
--health-timeout 5s
|
|
--health-retries 5
|
|
ports:
|
|
- 5432:5432
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: ${{ env.PYTHON_VERSION }}
|
|
cache: 'pip'
|
|
|
|
- name: Install dependencies
|
|
run: |
|
|
pip install -r requirements.txt
|
|
pip install -r requirements-test.txt
|
|
pip install -e .
|
|
|
|
- name: Run smoke tests
|
|
env:
|
|
PYTHONPATH: ${{ github.workspace }}
|
|
run: |
|
|
pytest -m smoke -v --tb=short --no-cov
|
|
|
|
- name: Run unit tests
|
|
env:
|
|
PYTHONPATH: ${{ github.workspace }}
|
|
run: |
|
|
pytest -m unit -v --no-cov
|
|
|
|
- name: Run critical integration tests
|
|
env:
|
|
DATABASE_URL: postgresql://test_user:test_password@localhost:5432/test_db
|
|
FLASK_APP: app.py
|
|
FLASK_ENV: testing
|
|
PYTHONPATH: ${{ github.workspace }}
|
|
run: |
|
|
pytest -m "integration and not slow" -v --no-cov
|
|
|
|
# ============================================================================
|
|
# Build and Push Development Image
|
|
# ============================================================================
|
|
build-and-push:
|
|
name: Build and Push Development Image
|
|
runs-on: ubuntu-latest
|
|
needs: quick-tests
|
|
if: always() && (needs.quick-tests.result == 'success' || github.event.inputs.force_build == 'true')
|
|
permissions:
|
|
contents: read
|
|
packages: write
|
|
timeout-minutes: 30
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Set up Docker Buildx
|
|
uses: docker/setup-buildx-action@v3
|
|
|
|
- name: Log in to Container Registry
|
|
uses: docker/login-action@v3
|
|
with:
|
|
registry: ${{ env.REGISTRY }}
|
|
username: ${{ github.actor }}
|
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Extract metadata
|
|
id: meta
|
|
uses: docker/metadata-action@v5
|
|
with:
|
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
|
tags: |
|
|
type=raw,value=develop
|
|
type=raw,value=dev-{{date 'YYYYMMDD-HHmmss'}}
|
|
type=sha,prefix=dev-,format=short
|
|
|
|
- name: Determine version
|
|
id: version
|
|
run: |
|
|
BUILD_NUMBER=${{ github.run_number }}
|
|
COMMIT_SHA=${GITHUB_SHA::8}
|
|
VERSION="dev-${BUILD_NUMBER}-${COMMIT_SHA}"
|
|
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
echo "📦 Building version: $VERSION"
|
|
|
|
- name: Build and push Docker image
|
|
uses: docker/build-push-action@v5
|
|
with:
|
|
context: .
|
|
platforms: linux/amd64,linux/arm64
|
|
push: true
|
|
tags: ${{ steps.meta.outputs.tags }}
|
|
labels: ${{ steps.meta.outputs.labels }}
|
|
build-args: |
|
|
APP_VERSION=${{ steps.version.outputs.version }}
|
|
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:develop
|
|
cache-to: type=inline
|
|
|
|
- name: Generate deployment manifest
|
|
run: |
|
|
cat > deployment-dev.yml << EOF
|
|
# TimeTracker Development Deployment
|
|
# Generated: $(date -u +'%Y-%m-%d %H:%M:%S UTC')
|
|
# Version: ${{ steps.version.outputs.version }}
|
|
# Commit: ${{ github.sha }}
|
|
|
|
version: '3.8'
|
|
|
|
services:
|
|
app:
|
|
image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:develop
|
|
container_name: timetracker-dev
|
|
ports:
|
|
- "8080:8080"
|
|
environment:
|
|
- TZ=Europe/Brussels
|
|
- DATABASE_URL=postgresql://timetracker:timetracker@db:5432/timetracker
|
|
- SECRET_KEY=\${SECRET_KEY}
|
|
- FLASK_ENV=development
|
|
- APP_VERSION=${{ steps.version.outputs.version }}
|
|
depends_on:
|
|
- db
|
|
restart: unless-stopped
|
|
|
|
db:
|
|
image: postgres:16-alpine
|
|
container_name: timetracker-dev-db
|
|
environment:
|
|
- POSTGRES_DB=timetracker
|
|
- POSTGRES_USER=timetracker
|
|
- POSTGRES_PASSWORD=\${POSTGRES_PASSWORD}
|
|
volumes:
|
|
- db_data:/var/lib/postgresql/data
|
|
restart: unless-stopped
|
|
|
|
volumes:
|
|
db_data:
|
|
EOF
|
|
|
|
echo "📄 Deployment manifest created"
|
|
cat deployment-dev.yml
|
|
|
|
- name: Upload deployment manifest
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: deployment-manifest-dev
|
|
path: deployment-dev.yml
|
|
|
|
- name: Create GitHub Release (Development)
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const version = '${{ steps.version.outputs.version }}';
|
|
const tagName = `dev-${version}`;
|
|
|
|
try {
|
|
await github.rest.repos.createRelease({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
tag_name: tagName,
|
|
name: `Development Build ${version}`,
|
|
body: `## Development Build
|
|
|
|
**Version:** ${version}
|
|
**Commit:** ${context.sha.substring(0, 7)}
|
|
**Branch:** develop
|
|
**Build:** #${context.runNumber}
|
|
|
|
### Docker Image
|
|
\`\`\`
|
|
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:develop
|
|
\`\`\`
|
|
|
|
### Quick Start
|
|
\`\`\`bash
|
|
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:develop
|
|
docker-compose -f deployment-dev.yml up -d
|
|
\`\`\`
|
|
|
|
### Changes
|
|
${context.payload.head_commit?.message || 'See commit history'}
|
|
|
|
---
|
|
*This is an automated development build. Use at your own risk.*
|
|
`,
|
|
draft: false,
|
|
prerelease: true
|
|
});
|
|
|
|
console.log('✅ Development release created');
|
|
} catch (error) {
|
|
if (error.status === 422) {
|
|
console.log('⚠️ Release already exists, skipping');
|
|
} else {
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
# ============================================================================
|
|
# Notification
|
|
# ============================================================================
|
|
notify:
|
|
name: Send Notifications
|
|
runs-on: ubuntu-latest
|
|
needs: [quick-tests, build-and-push]
|
|
if: always()
|
|
|
|
steps:
|
|
- name: Determine build status
|
|
id: status
|
|
run: |
|
|
if [ "${{ needs.build-and-push.result }}" == "success" ]; then
|
|
echo "status=✅ Success" >> $GITHUB_OUTPUT
|
|
echo "color=28a745" >> $GITHUB_OUTPUT
|
|
else
|
|
echo "status=❌ Failed" >> $GITHUB_OUTPUT
|
|
echo "color=dc3545" >> $GITHUB_OUTPUT
|
|
fi
|
|
|
|
- name: Create summary
|
|
run: |
|
|
echo "## 🚀 Development Build ${{ steps.status.outputs.status }}" >> $GITHUB_STEP_SUMMARY
|
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
echo "**Branch:** develop" >> $GITHUB_STEP_SUMMARY
|
|
echo "**Commit:** ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
|
|
echo "**Build:** #${{ github.run_number }}" >> $GITHUB_STEP_SUMMARY
|
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
echo "### Test Results" >> $GITHUB_STEP_SUMMARY
|
|
echo "- Tests: ${{ needs.quick-tests.result }}" >> $GITHUB_STEP_SUMMARY
|
|
echo "- Build: ${{ needs.build-and-push.result }}" >> $GITHUB_STEP_SUMMARY
|
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
|
|
if [ "${{ needs.build-and-push.result }}" == "success" ]; then
|
|
echo "### 🐳 Docker Image" >> $GITHUB_STEP_SUMMARY
|
|
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
|
echo "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:develop" >> $GITHUB_STEP_SUMMARY
|
|
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
|
fi
|
|
|