Skip to content

Introduce CI/CD workflow, frontend Dockerization, and Docker Compose #47

Introduce CI/CD workflow, frontend Dockerization, and Docker Compose

Introduce CI/CD workflow, frontend Dockerization, and Docker Compose #47

Workflow file for this run

name: CI / CD – TaskFlow
on:
push:
branches: [ main, develop ]
paths:
- 'Backend/**'
- 'Frontend/**'
- '.github/workflows/**'
pull_request:
branches: [ main, develop ]
paths:
- 'Backend/**'
- 'Frontend/**'
- '.github/workflows/**'
jobs:
changes:
runs-on: ubuntu-latest
outputs:
backend: ${{ steps.filter.outputs.backend }}
frontend: ${{ steps.filter.outputs.frontend }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
backend:
- 'Backend/**'
- 'Backend/Dockerfile'
frontend:
- 'Frontend/**'
- 'Frontend/Dockerfile'
# 1. Checkout + Setup .NET
setup-backend:
runs-on: ubuntu-latest
needs: changes
if: ${{ needs.changes.outputs.backend == 'true' }}
outputs:
cache-key: ${{ steps.cache.outputs.cache-key }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup .NET 8
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
- name: Cache dependencies
id: cache
uses: actions/cache@v4
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
restore-keys: ${{ runner.os }}-nuget-
# 2. Restore dependencies + Build
build-backend:
needs: setup-backend
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
- name: Restore dependencies
run: dotnet restore ./Backend/FlowTasks.sln
- name: Build
run: dotnet build ./Backend/FlowTasks.sln --configuration Release --no-restore
# 3. Unit Tests + Coverage
test-backend:
needs: build-backend
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: taskflow_test
ports: [5432:5432]
options: --health-cmd="pg_isready -U postgres" --health-interval=10s --health-timeout=5s --health-retries=5
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
- name: Restore dependencies
run: dotnet restore ./Backend/FlowTasks.sln
- name: Run Unit Tests + Coverage
env:
ConnectionStrings__DefaultConnection: Server=localhost;Port=5432;Database=taskflow_test;User Id=postgres;Password=postgres;
run: |
dotnet test ./Backend/FlowTasks.sln --configuration Release --collect:"XPlat Code Coverage" --results-directory:./coverage --logger "trx;LogFileName=test-results.trx"
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage/**/*.cobertura.xml
fail_ci_if_error: false
- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
with:
name: test-results
path: "**/TestResults/*.trx"
# 4. Code Quality
quality-backend:
needs: test-backend
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
with:
fetch-depth: 0
- name: SonarCloud Scan
uses: SonarSource/sonarqube-scan-action@a31c9398be7ace6bbfaf30c0bd5d415f843d45e9
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: https://sonarcloud.io
with:
args: >
-Dsonar.projectKey=TaskFlow
-Dsonar.organization=benamarfaiez
-Dsonar.sources=.
-Dsonar.tests=.
-Dsonar.exclusions=**/bin/**,**/obj/**,**/*.xml
-Dsonar.cs.opencover.reportsPaths=**/coverage/**/*.opencover.xml
-Dsonar.qualitygate.wait=true
# 5. Build & Push Docker Image
docker-backend:
needs: build-backend
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
file: ./Backend/Dockerfile
push: true
tags: |
ghcr.io/${{ github.repository_owner }}/taskflow:latest
ghcr.io/${{ github.repository_owner }}/taskflow:${{ github.sha }}
ghcr.io/${{ github.repository_owner }}/taskflow:${{ github.ref_name == 'main' && 'stable' || 'dev' }}
# ======================== FRONTEND JOBS ========================
setup-frontend:
needs: changes
if: ${{ needs.changes.outputs.frontend == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
cache-dependency-path: Frontend/package-lock.json
- name: Install dependencies
run: cd Frontend && npm ci --legacy-peer-deps
- name: Lint Frontend
run: cd Frontend && npm install && npx ng lint
# Décommente si tu ajoutes des tests Angular
# - name: Run tests
# run: cd Frontend && npm run test -- --watch=false --browsers=ChromeHeadless
build-frontend:
needs: setup-frontend
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
cache-dependency-path: Frontend/package-lock.json
- name: Install & Build
run: |
cd Frontend
npm ci --legacy-peer-deps
npm run build -- --configuration production
- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: frontend-dist
path: Frontend/dist/
docker-frontend:
needs: build-frontend
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push frontend image
uses: docker/build-push-action@v6
with:
context: ./Frontend
file: ./Frontend/Dockerfile
push: true
tags: |
ghcr.io/${{ github.repository_owner }}/taskflow-frontend:latest
ghcr.io/${{ github.repository_owner }}/taskflow-frontend:${{ github.sha }}
ghcr.io/${{ github.repository_owner }}/taskflow-frontend:${{ github.ref_name == 'main' && 'stable' || 'dev' }}