turash/.gitea/workflows/ci.yml
Damir Mukimov e65b637440
Enhance CI workflow to support conditional Docker testing
- Allow forcing Docker testing with the DOCKER_FORCE environment variable for local development
- Update Docker availability check to accommodate forced testing scenarios
2025-12-26 15:50:18 +01:00

358 lines
12 KiB
YAML

name: CI/CD Pipeline
on:
push:
branches:
- master
paths:
- 'bugulma/**'
- 'k8s/**'
- '.gitea/workflows/**'
pull_request:
branches:
- master
paths:
- 'bugulma/**'
- 'k8s/**'
jobs:
frontend-lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '24'
- name: Enable Corepack (for Yarn)
run: |
# Check if we're in act environment
if [ -n "$ACT" ] || [ -d "/root/.cache/act" ]; then
echo "⚠ Detected 'act' local runner - Node.js may not be fully available"
echo "⚠ Corepack setup may be limited in this environment"
# Skip corepack in act environment as Node.js path may be wrong
echo "✅ Skipping Corepack setup for local runner"
else
corepack enable
fi
- name: Install dependencies
working-directory: bugulma/frontend
run: yarn install --immutable
- name: Lint
working-directory: bugulma/frontend
run: yarn lint
- name: Test
working-directory: bugulma/frontend
run: yarn test --run
frontend-build:
runs-on: ubuntu-latest
needs: frontend-lint
if: gitea.event_name == 'push' && gitea.ref == 'refs/heads/master'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver-opts: |
image=moby/buildkit:latest
- name: Login to Container Registry
uses: docker/login-action@v3
with:
registry: registry.bk.glpx.pro
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push frontend
uses: docker/build-push-action@v5
with:
context: bugulma/frontend
file: bugulma/frontend/Dockerfile
push: true
tags: |
registry.bk.glpx.pro/turash/turash-frontend:latest
registry.bk.glpx.pro/turash/turash-frontend:${{ gitea.sha }}
cache-from: type=registry,ref=registry.bk.glpx.pro/turash/turash-frontend:buildcache
cache-to: type=registry,ref=registry.bk.glpx.pro/turash/turash-frontend:buildcache,mode=max
platforms: linux/amd64
build-args: |
BUILDKIT_INLINE_CACHE=1
backend-lint:
runs-on: ubuntu-latest
env:
POSTGRES_HOST: localhost
POSTGRES_PORT: 5432
POSTGRES_USER: turash
POSTGRES_PASSWORD: turash123
POSTGRES_DB: postgres
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.25.3'
cache: true
- name: Install PostgreSQL
run: |
echo "Installing PostgreSQL for tests..."
# Check if we're running in act (local runner) or real CI
if [ -n "$ACT" ] || [ -d "/root/.cache/act" ]; then
echo "⚠ Detected 'act' local runner environment"
echo "⚠ This workflow is designed for real CI runners (GitHub Actions/Gitea Actions)"
echo "⚠ For local testing, use Docker Compose or install PostgreSQL locally"
echo "SKIP_POSTGRESQL=true" >> $GITHUB_ENV
exit 0
fi
# Update package list
apt-get update
# Install PostgreSQL and PostGIS
DEBIAN_FRONTEND=noninteractive apt-get install -y \
postgresql \
postgresql-contrib \
postgresql-postgis \
postgresql-client \
sudo
# Start PostgreSQL service
systemctl start postgresql || service postgresql start
# Wait for PostgreSQL to be ready
for i in {1..30}; do
if pg_isready -h localhost -p 5432 >/dev/null 2>&1; then
echo "✓ PostgreSQL is ready!"
break
fi
echo "Waiting for PostgreSQL... (attempt $i/30)"
sleep 2
done
# Check if PostgreSQL is actually ready
if ! pg_isready -h localhost -p 5432 >/dev/null 2>&1; then
echo "✗ PostgreSQL failed to start"
systemctl status postgresql || service postgresql status
journalctl -u postgresql -n 20 || true
exit 1
fi
# Create test user and database
sudo -u postgres psql -c "CREATE USER turash WITH PASSWORD 'turash123';" 2>/dev/null || true
sudo -u postgres psql -c "ALTER USER turash CREATEDB;" 2>/dev/null || true
sudo -u postgres psql -c "CREATE DATABASE postgres OWNER turash;" 2>/dev/null || true
# Enable PostGIS
sudo -u postgres psql -d postgres -c "CREATE EXTENSION IF NOT EXISTS postgis;" 2>/dev/null || true
echo "✓ PostgreSQL setup complete"
- name: Install CGO dependencies (for race detector)
id: cgo-setup
run: |
echo "Checking for gcc (required for race detector)..."
CGO_AVAILABLE=0
# Check if gcc is already available
if command -v gcc &> /dev/null; then
echo "✓ gcc is already available"
gcc --version
CGO_AVAILABLE=1
else
echo "gcc not found, attempting to install..."
# Detect package manager and install gcc
if command -v apt-get &> /dev/null; then
echo "Using apt-get (Debian/Ubuntu)..."
if [ "$(id -u)" -eq 0 ]; then
apt-get update -qq && DEBIAN_FRONTEND=noninteractive apt-get install -y -qq build-essential && CGO_AVAILABLE=1 || true
else
(sudo apt-get update -qq && DEBIAN_FRONTEND=noninteractive sudo apt-get install -y -qq build-essential && CGO_AVAILABLE=1) || \
(apt-get update -qq && DEBIAN_FRONTEND=noninteractive apt-get install -y -qq build-essential && CGO_AVAILABLE=1) || true
fi
elif command -v apk &> /dev/null; then
echo "Using apk (Alpine)..."
apk add --no-cache gcc musl-dev && CGO_AVAILABLE=1 || true
elif command -v yum &> /dev/null; then
echo "Using yum (RHEL/CentOS)..."
yum install -y gcc && CGO_AVAILABLE=1 || true
elif command -v dnf &> /dev/null; then
echo "Using dnf (Fedora)..."
dnf install -y gcc && CGO_AVAILABLE=1 || true
else
echo "⚠ No supported package manager found (apt-get, apk, yum, dnf)"
echo "⚠ gcc installation skipped - race detector will be disabled"
fi
# Verify installation
if command -v gcc &> /dev/null || [ -f /usr/bin/gcc ]; then
echo "✓ gcc successfully installed"
gcc --version || /usr/bin/gcc --version
CGO_AVAILABLE=1
else
echo "⚠ gcc installation failed - race detector will be disabled"
fi
fi
echo "cgo_available=$CGO_AVAILABLE" >> $GITHUB_OUTPUT
continue-on-error: true
- name: Install dependencies
working-directory: bugulma/backend
run: go mod download
env:
GO111MODULE: on
CGO_ENABLED: 1
GOPROXY: https://proxy.golang.org,direct
GOSUMDB: sum.golang.org
- name: Tidy and verify modules
working-directory: bugulma/backend
run: |
go mod tidy
go mod verify
env:
GO111MODULE: on
CGO_ENABLED: 0
GOPROXY: https://proxy.golang.org,direct
GOSUMDB: sum.golang.org
- name: Verify module setup
working-directory: bugulma/backend
run: |
pwd
ls -la go.mod
go list -m
# Verify all packages can be listed
go list ./...
env:
GO111MODULE: on
CGO_ENABLED: 0
GOPROXY: https://proxy.golang.org,direct
GOSUMDB: sum.golang.org
- name: Build module to populate cache
working-directory: bugulma/backend
run: go build ./...
env:
GO111MODULE: on
CGO_ENABLED: 0
GOPROXY: https://proxy.golang.org,direct
GOSUMDB: sum.golang.org
- name: Vet
working-directory: bugulma/backend
run: go vet ./...
env:
GO111MODULE: on
CGO_ENABLED: 0
GOPROXY: https://proxy.golang.org,direct
GOSUMDB: sum.golang.org
- name: Test
working-directory: bugulma/backend
run: |
# Check if Docker is available for testcontainers
# Allow forcing Docker testing with DOCKER_FORCE=true (useful for local development)
if [ "$DOCKER_FORCE" = "true" ] || (command -v docker &> /dev/null && docker info &> /dev/null 2>&1); then
echo "✅ Docker available - running all tests with testcontainers"
echo "🧪 Testcontainers will provide isolated PostgreSQL instances"
# Check if CGO is available for race detector
CGO_AVAILABLE="${{ steps.cgo-setup.outputs.cgo_available || '0' }}"
# Build test command
TEST_CMD="go test -v"
# Add race detector if CGO is available
if [ "$CGO_AVAILABLE" = "1" ] && command -v gcc &> /dev/null; then
echo "Running tests with race detector..."
TEST_CMD="$TEST_CMD -race"
export CGO_ENABLED=1
else
echo "Running tests without race detector (CGO not available)..."
export CGO_ENABLED=0
fi
# Add coverage
TEST_CMD="$TEST_CMD -coverprofile=coverage.out"
# Run all tests (testcontainers will handle database isolation)
echo "Running all tests with testcontainers..."
$TEST_CMD ./...
else
echo "⚠ Docker not available - falling back to unit tests only"
echo "⚠ Integration tests require Docker for testcontainers"
# Run only unit tests (integration tests are excluded by build tags)
go test -v -coverprofile=coverage.out ./...
echo "⚠ Integration tests were skipped due to Docker not being available"
echo "✅ Unit tests completed"
fi
env:
GO111MODULE: on
GOPROXY: https://proxy.golang.org,direct
GOSUMDB: sum.golang.org
- name: Coverage
working-directory: bugulma/backend
run: go tool cover -html=coverage.out -o coverage.html
backend-build:
runs-on: ubuntu-latest
needs: backend-lint
if: gitea.event_name == 'push' && gitea.ref == 'refs/heads/master'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver-opts: |
image=moby/buildkit:latest
- name: Login to Container Registry
uses: docker/login-action@v3
with:
registry: registry.bk.glpx.pro
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push backend
uses: docker/build-push-action@v5
with:
context: bugulma/backend
file: bugulma/backend/Dockerfile
push: true
tags: |
registry.bk.glpx.pro/turash/turash-backend:latest
registry.bk.glpx.pro/turash/turash-backend:${{ gitea.sha }}
cache-from: type=registry,ref=registry.bk.glpx.pro/turash/turash-backend:buildcache
cache-to: type=registry,ref=registry.bk.glpx.pro/turash/turash-backend:buildcache,mode=max
platforms: linux/amd64
build-args: |
BUILDKIT_INLINE_CACHE=1
e2e-test:
runs-on: ubuntu-latest
needs: [frontend-build, backend-build]
if: gitea.event_name == 'push' && gitea.ref == 'refs/heads/master'
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '24'
- name: Enable Corepack (for Yarn)
run: corepack enable
- name: Install dependencies
working-directory: bugulma/frontend
run: yarn install --immutable
- name: Run E2E tests
working-directory: bugulma/frontend
run: yarn test:e2e --headed=false