Skip to content

Merge pull request #713 from vormadal/claude/list-reorder-animation-k… #1042

Merge pull request #713 from vormadal/claude/list-reorder-animation-k…

Merge pull request #713 from vormadal/claude/list-reorder-animation-k… #1042

Workflow file for this run

name: Frontend CI
on:
push:
branches: [ main, develop ]
paths:
- 'anything-frontend/**'
- '.github/workflows/frontend-ci.yml'
pull_request:
branches: [ main, develop ]
paths:
- 'anything-frontend/**'
- '.github/workflows/frontend-ci.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: true
jobs:
lint-and-build:
name: Lint and Build (Next.js)
runs-on: ubuntu-latest
timeout-minutes: 15
defaults:
run:
working-directory: ./anything-frontend
steps:
- name: Checkout code
uses: actions/checkout@v7
with:
fetch-depth: 0 # Shallow clones should be disabled for better SonarCloud analysis
- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: anything-frontend/package-lock.json
- name: Install dependencies
run: npm ci --ignore-scripts
- name: Run ESLint
run: npm run lint
- name: Type-check
run: npm run typecheck
- name: Build Next.js application
run: npm run build
env:
NEXT_PUBLIC_API_URL: http://localhost:5238
- name: Upload build artifacts
uses: actions/upload-artifact@v7
with:
name: nextjs-build
path: anything-frontend/.next
test:
name: Run Tests
runs-on: ubuntu-latest
timeout-minutes: 15
defaults:
run:
working-directory: ./anything-frontend
steps:
- name: Checkout code
uses: actions/checkout@v7
with:
fetch-depth: 0 # Shallow clones should be disabled for better SonarCloud analysis
- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: anything-frontend/package-lock.json
- name: Install dependencies
run: npm ci --ignore-scripts
- name: Run tests with coverage
run: npm run test:coverage
- name: Upload coverage artifacts
uses: actions/upload-artifact@v7
with:
name: coverage
path: anything-frontend/coverage
visual-tests:
name: Visual Snapshot Tests
runs-on: ubuntu-latest
timeout-minutes: 20
permissions:
contents: read
defaults:
run:
working-directory: ./anything-frontend
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: anything-frontend/package-lock.json
- name: Install dependencies
run: npm ci --ignore-scripts
- name: Build Next.js application
run: npm run build
env:
NEXT_PUBLIC_API_URL: http://localhost:5238
- name: Install Playwright browsers
run: npx playwright install --with-deps chromium
- name: Run visual snapshot tests
run: npm run test:e2e:visual
- name: Upload Playwright report
if: always()
uses: actions/upload-artifact@v7
with:
name: visual-playwright-report
path: anything-frontend/playwright-report/
e2e-tests:
name: E2E Tests
runs-on: ubuntu-latest
needs: [lint-and-build]
timeout-minutes: 30
permissions:
contents: read
services:
postgres:
image: postgres:16
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: anything
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
defaults:
run:
working-directory: ./anything-frontend
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Setup .NET
uses: actions/setup-dotnet@v6
with:
dotnet-version: '10.0.x'
- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: anything-frontend/package-lock.json
- name: Cache .NET packages
uses: actions/cache@v6
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj', '**/Directory.Build.props') }}
restore-keys: |
${{ runner.os }}-nuget-
- name: Restore .NET dependencies
run: dotnet restore Anything.slnx
working-directory: ${{ github.workspace }}
- name: Build .NET solution
run: dotnet build Anything.slnx --no-restore --configuration Release
working-directory: ${{ github.workspace }}
- name: Install frontend dependencies
run: npm ci --ignore-scripts
- name: Build Next.js application
run: npm run build
env:
NEXT_PUBLIC_API_URL: http://localhost:5238
- name: Install Playwright browsers
run: npx playwright install --with-deps chromium
- name: Start Minio
run: |
docker run -d \
--name minio \
-p 9000:9000 \
-e MINIO_ROOT_USER=minioadmin \
-e MINIO_ROOT_PASSWORD=minioadmin \
minio/minio:latest server /data
working-directory: ${{ github.workspace }}
- name: Wait for Minio to be ready
run: timeout 60 bash -c 'until curl -sf http://localhost:9000/minio/health/live; do sleep 2; done'
working-directory: ${{ github.workspace }}
- name: Create Minio bucket
run: |
AWS_ACCESS_KEY_ID=minioadmin \
AWS_SECRET_ACCESS_KEY=minioadmin \
AWS_DEFAULT_REGION=us-east-1 \
aws s3 mb s3://recipe-images --endpoint-url http://localhost:9000
working-directory: ${{ github.workspace }}
- name: Start .NET API
run: dotnet run --project src/Anything.API/Anything.API.csproj --no-build --configuration Release --no-launch-profile &
working-directory: ${{ github.workspace }}
env:
ASPNETCORE_ENVIRONMENT: CI
ASPNETCORE_URLS: http://localhost:5238
ConnectionStrings__anything: Host=localhost;Port=5432;Database=anything;Username=postgres;Password=postgres
ASPIRE_ALLOW_UNSECURED_TRANSPORT: "true"
ASPIRE__DISABLE_DASHBOARD: "true"
Admin__Email: ${{ secrets.E2E_ADMIN_EMAIL || 'admin@anything.local' }}
Admin__Password: ${{ secrets.E2E_ADMIN_PASSWORD || 'Admin123!' }}
- name: Start Next.js application
run: |
cp -r .next/static .next/standalone/.next/static
cp -r public .next/standalone/public 2>/dev/null || true
PORT=3001 node .next/standalone/server.js &
- name: Wait for API to be ready
run: timeout 60 bash -c 'until curl -sf http://localhost:5238/health; do sleep 2; done'
working-directory: ${{ github.workspace }}
- name: Wait for Next.js to be ready
run: timeout 60 bash -c 'until curl -sf http://localhost:3001; do sleep 2; done'
- name: Run E2E tests
run: npm run test:e2e
env:
E2E_BASE_URL: http://localhost:3001
E2E_ADMIN_EMAIL: ${{ secrets.E2E_ADMIN_EMAIL || 'admin@anything.local' }}
E2E_ADMIN_PASSWORD: ${{ secrets.E2E_ADMIN_PASSWORD || 'Admin123!' }}
- name: Stop background services
if: always()
run: |
pkill -f "Anything.API" || true
pkill -f "standalone/server.js" || true
docker stop minio || echo 'Minio container was not running'
docker rm minio || echo 'Minio container could not be removed'
- name: Upload Playwright report
if: always()
uses: actions/upload-artifact@v7
with:
name: e2e-playwright-report
path: anything-frontend/playwright-report/
sonarcloud:
name: SonarCloud Analysis
runs-on: ubuntu-latest
needs: [lint-and-build, test]
timeout-minutes: 10
if: (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) && github.actor != 'dependabot[bot]'
defaults:
run:
working-directory: ./anything-frontend
steps:
- name: Checkout code
uses: actions/checkout@v7
with:
fetch-depth: 0 # Shallow clones should be disabled for SonarCloud analysis
- name: Download coverage artifacts
uses: actions/download-artifact@v8
with:
name: coverage
path: anything-frontend/coverage
- name: SonarCloud Scan
uses: SonarSource/sonarqube-scan-action@v8
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: https://sonarcloud.io
with:
projectBaseDir: anything-frontend
args: >
-Dsonar.projectKey=vormadal_Anything-frontend
-Dsonar.organization=vormadal
-Dsonar.sources=src
-Dsonar.exclusions=**/*.test.ts,**/*.test.tsx,**/node_modules/**,**/.next/**,**/public/**,**/lib/api-client/**
-Dsonar.test.inclusions=**/*.test.ts,**/*.test.tsx
-Dsonar.coverage.exclusions=**/app/layout.tsx,**/middleware.ts,**/context/QueryProvider.tsx,**/components/ui/sonner.tsx,**/lib/api-client/**
-Dsonar.javascript.lcov.reportPaths=coverage/lcov.info