CI/CD Pipeline & GitHub Actions

Overview

The Docker build and deployment process is fully automated using GitHub Actions. The pipeline runs tests, builds the application, creates a Docker image, and deploys to production automatically on every push to the master/main branch.


GitHub Actions Workflow Improvements

Enhanced Documentation

The deploy-frontend.yml workflow includes:

  • Clear purpose statements for each stage
  • When each stage runs (push vs PR, master/main only)
  • What causes pipeline failure
  • Required secrets and environment variables
  • Error messages with troubleshooting tips

Better Naming

  • Changed "Use Node.js 20" to "Setup Node.js 20"
  • Changed "Check test results" to "Verify test results"
  • More descriptive deploy step comments

Improved Error Handling

  • Better error messages explaining what went wrong
  • Troubleshooting tips in failure messages
  • Clear indication of required secrets

Workflow Structure

Two-Stage Pipeline

The deployment pipeline has two distinct stages with different triggers and purposes:

graph TD Push["Push to master/main"] subgraph stage1["Stage 1: Test & Verify"] direction TB Checkout1["Checkout code"] Setup1["Setup Node.js 20"] Cache1["Use npm cache"] Install["npm ci"] Lint["npm run lint"] Test["npm run test"] Coverage["Generate coverage"] Verify["Verify results"] end subgraph stage2["Stage 2: Build & Deploy"] direction TB Checkout2["Checkout code"] Setup2["Setup Node.js 20"] Cache2["Use npm cache"] Install2["npm ci"] Build["npm run build"] Docker["docker build"] Deploy["Deploy to Vercel"] Summary["Deployment summary"] end subgraph triggers["Triggers"] direction TB AllCommits["Runs on:
- Push to any branch
- Pull requests"] MainOnly["Runs on:
- Push to master/main only"] end Push --> stage1 stage1 -->|Success| stage2 stage1 -->|Failure| Blocked["❌ Deployment blocked"] stage1 --> AllCommits stage2 --> MainOnly stage2 --> Success["βœ… Deployed"] stage2 -->|Failure| Failure["❌ Deployment failed"] style stage1 fill:#e3f2fd style stage2 fill:#c8e6c9 style Success fill:#fff9c4 style Blocked fill:#ffccbc style Failure fill:#ffccbc

Stage 1: Test & Verify (Always Runs)

Trigger: Every commit and pull request to any branch

Purpose: Ensure code quality and prevent broken code from being deployed

Steps

1. Checkout code
   └─ Gets the latest code from repository

2. Setup Node.js 20
   └─ Installs Node.js runtime environment

3. Use npm cache
   └─ Speeds up dependency installation

4. Install dependencies
   └─ npm ci (clean install for reproducibility)
   └─ Installs all project dependencies

5. Run linter
   └─ npm run lint (ESLint)
   └─ Checks code style and quality

6. Run tests
   └─ npm run test (Vitest)
   └─ Runs 478+ unit and integration tests

7. Generate coverage report
   └─ Vitest coverage analysis
   └─ Ensures adequate test coverage

8. Verify test results
   └─ Fails if tests fail
   └─ Fails if linting issues found

Key Features

βœ… Runs on all commits - Including pull requests
βœ… Fast feedback - Developers see failures immediately
βœ… Prevents bad code - Broken code can't reach production
βœ… npm caching - Speeds up repeated runs
βœ… Coverage tracking - Maintains test quality

Example Output

βœ“ Checkout code
βœ“ Setup Node.js 20
βœ“ Use npm cache
βœ“ Install dependencies (15 seconds)
βœ“ Run linter (8 seconds)
  β”œβ”€ No ESLint errors found
βœ“ Run tests (45 seconds)
  β”œβ”€ Passed: 478 tests
  β”œβ”€ Failed: 0 tests
βœ“ Generate coverage report
  β”œβ”€ Coverage: 87%
βœ“ Verify test results
  └─ All tests passed!

Stage 2: Build & Deploy (Protected)

Trigger: Only on push to master or main branch

Runs After: Stage 1 succeeds

Purpose: Build production bundle and deploy to Vercel

Steps

1. Checkout code
   └─ Gets the latest code

2. Setup Node.js 20
   └─ Installs Node.js runtime

3. Use npm cache
   └─ Speeds up builds

4. Install dependencies
   └─ npm ci (same as Stage 1)

5. Build production bundle
   └─ npm run build (Vite)
   └─ Creates optimized dist/ directory
   └─ Minifies and bundles code
   └─ Optimizes assets

6. Verify build output
   └─ Checks dist/ directory exists
   └─ Verifies build artifacts
   └─ Fails if build errors

7. Build Docker image
   └─ docker build (optional - for testing)
   └─ Creates container image
   └─ Tests multi-stage build

8. Deploy to Vercel
   └─ Pushes production build
   └─ Triggers Vercel deployment
   └─ Makes app live

9. Deployment summary
   └─ Shows deployment URL
   └─ Logs build time
   └─ Provides rollback info

Key Features

βœ… Master/main only - Production only from main branch
βœ… Depends on Stage 1 - Can't deploy if tests fail
βœ… Docker verification - Tests build before deployment
βœ… Automated deployment - No manual steps needed
βœ… Clear summary - Shows deployment status

Example Output

βœ“ Checkout code
βœ“ Setup Node.js 20
βœ“ Use npm cache
βœ“ Install dependencies (15 seconds)
βœ“ Build production bundle (35 seconds)
  β”œβ”€ dist/index.html: 2.5KB
  β”œβ”€ dist/assets/index.js: 485KB
  β”œβ”€ dist/assets/vendor.js: 250KB
  └─ dist/assets/index.css: 45KB
βœ“ Verify build output
  β”œβ”€ dist/ directory found
  β”œβ”€ All expected files present
βœ“ Build Docker image (30 seconds)
  β”œβ”€ Image size: 45MB
  β”œβ”€ Layers: 5
βœ“ Deploy to Vercel (20 seconds)
  β”œβ”€ Build ID: abc123def456
  β”œβ”€ URL: https://stockease-...vercel.app
βœ“ Deployment summary
  └─ βœ… Deployed to production

Conditional Execution Logic

When Tests Run

on:
  push:
    branches: [ master, main ]
  pull_request:
    branches: [ master, main ]
Event Test Stage Deploy Stage
Push to master/main βœ… Runs βœ… Runs (if tests pass)
Push to feature branch βœ… Runs ❌ Skipped
Pull request βœ… Runs ❌ Skipped
Direct commit to master βœ… Runs βœ… Runs (if tests pass)
Draft PR βœ… Runs ❌ Skipped

Deployment Protection

if: success() && github.ref == 'refs/heads/master'

Deployment only happens when:

  1. All tests pass
  2. Push is to master/main branch
  3. No failures in previous stages
  4. Commit is on main branch (not PR)

Required Configuration

Secrets

Two secrets must be configured in GitHub repository settings:

Secret Purpose Where to Get
VERCEL_TOKEN Authentication for Vercel deployment Vercel Settings
FRONTEND_API_BASE_URL Production API endpoint Your backend API URL

Environment Variables

VITE_API_BASE_URL: ${{ secrets.FRONTEND_API_BASE_URL }}
NODE_ENV: production

GitHub Actions Permissions

The workflow needs:

  • Read access to repository code
  • Write access to deployment status
  • Secrets access (automatic)

Error Handling

Test Failures

If tests fail, the pipeline stops before deployment:

❌ npm run test FAILED
  └─ Error: 2 tests failed
     β”œβ”€ LoginPage should render login form
     └─ Dashboard should handle API errors
  
  Action: Fix the failing tests before pushing again

Build Failures

If the build fails, deployment is blocked:

❌ npm run build FAILED
  └─ Error: TypeScript compilation error
     └─ src/components/Button.tsx:15: Type 'string' is not assignable to type 'number'
  
  Action: Fix the TypeScript error

Deployment Failures

If Vercel deployment fails, you're notified:

❌ Deploy to Vercel FAILED
  └─ Error: Deployment quota exceeded
  
  Action: Check Vercel dashboard or contact support

Monitoring & Debugging

View Workflow Status

  1. Go to GitHub repository
  2. Click "Actions" tab
  3. Click workflow run to see details
  4. Click job to see step-by-step output

Common Issues & Solutions

Tests Failing

# Run tests locally first
npm run test

# Check linting
npm run lint

# Then push
git push origin feature-branch

Build Failing

# Build locally to verify
npm run build

# Check for build errors
npm run build -- --show-error

# Then push
git push

Deployment Not Triggering

# Ensure you're pushing to master/main
git push origin master

# Not to a feature branch
# (deployment won't trigger on feature branches)

Performance Metrics

Typical Pipeline Times

Stage Time Notes
Test Stage 60-90 seconds Includes npm install, lint, tests
Build Stage 50-70 seconds Includes npm install, build, Docker build
Deploy Stage 20-40 seconds Vercel deployment
Total 2-3 minutes From push to live

Optimization

  • npm cache: Reduces install time from 30s β†’ 10s
  • Layer caching: Docker reuses dependencies layer
  • Parallel execution: Tests run in parallel (if configured)

Best Practices

1. Commit Frequently

Push changes regularly to get fast feedback:

git commit -m "feat: add user profile page"
git push origin feature-branch

2. Keep Tests Passing

Don't push code with failing tests:

# Always run locally first
npm run test
npm run lint

# Then push
git push

3. Use Meaningful Commit Messages

# Good
git commit -m "fix: handle API timeout in product list"

# Bad
git commit -m "fix stuff"

4. Create Pull Requests

Don't push directly to master:

# Create feature branch
git checkout -b feature/add-search

# Work and push
git push origin feature/add-search

# Create PR on GitHub
# Let tests run on PR
# Get review
# Merge to master

5. Monitor Deployments

Check GitHub Actions and Vercel dashboards after merging:

# Check Actions
open https://github.com/Keglev/stockease-frontend/actions

# Check Vercel
open https://vercel.com/keglev/stockease-frontend

Deployment Workflow

Complete Development Cycle

1. Create feature branch
   git checkout -b feature/new-feature

2. Make changes
   Edit files, commit regularly

3. Run tests locally
   npm run test
   npm run lint

4. Push to GitHub
   git push origin feature/new-feature

5. Create Pull Request
   - Tests run on PR
   - Get code review
   - Fix any issues

6. Merge to master
   - Tests run again
   - If all pass, deploy starts

7. Vercel deployment
   - Build happens
   - Tests in production
   - App goes live

8. Monitor
   - Check Vercel dashboard
   - Monitor error tracking
   - Watch logs

Troubleshooting

Pipeline Not Running

Check:

  1. Branch is master/main
  2. Pushed to GitHub (not just committed locally)
  3. .github/workflows/deploy-frontend.yml exists
  4. Repository settings allow Actions

Fix:

# Verify remote is GitHub
git remote -v

# Push again
git push origin master

Deployment Stuck

Check:

  1. GitHub Actions status
  2. Vercel deployment status
  3. Check for hanging processes

Fix:

# Cancel workflow on GitHub (Actions tab)
# Then push again
git push origin master

API Errors After Deployment

Check:

  1. VITE_API_BASE_URL is correct
  2. API server is running
  3. CORS is configured correctly

Fix:

# Check what URL is in the build
docker run your-image:latest cat /usr/share/nginx/html/assets/*.js | grep api

# Rebuild with correct URL
docker build --build-arg VITE_API_BASE_URL=https://api.correct.com .


Last Updated: November 12, 2025
Status: βœ… Production Ready
Maintenance: Automated via GitHub Actions