Skip to main content

Overview

SkillRise uses GitHub Actions for continuous integration and deployment. The pipeline consists of two workflows:

Build Workflow

Runs on pull requests to validate code quality

Deploy Workflow

Builds and pushes Docker images on main branch

Build Workflow

The build workflow runs on every pull request to ensure code quality before merging.

Configuration

.github/workflows/build.yml

Workflow Stages

1

Client Validation

The client job validates the React frontend:
Uses npm ci for clean, reproducible installs based on package-lock.json.
Checks for code quality issues, potential bugs, and style violations.Configuration: eslint.config.js
  • React hooks rules
  • React refresh plugin
  • Prettier integration
Verifies consistent code formatting without modifying files.Configuration: .prettierrc
  • 2-space indentation
  • Single quotes
  • Semicolons
  • Trailing commas
Compiles the React app with Vite to ensure no build errors.Build-time environment variables:
  • VITE_CLERK_PUBLISHABLE_KEY
  • VITE_STRIPE_PUBLISHABLE_KEY
  • VITE_BACKEND_URL
These are read from GitHub Secrets and embedded in the build.
2

Server Validation

The server job validates the Node.js backend:
Installs all dependencies including devDependencies for linting.
Checks Express server code for issues.Configuration: eslint.config.js
  • Node.js globals
  • ES2022 syntax
  • Prettier integration
Ensures consistent formatting across all server files.

Running Locally

You can run the same checks locally before pushing:
Use npm run lint:fix and npm run format to automatically fix issues.

Deploy Workflow

The deploy workflow automatically builds and pushes Docker images when code is merged to the main branch.

Configuration

.github/workflows/deploy.yml

Workflow Stages

1

Server Image Build

The build-and-push-server job creates the backend Docker image:
Clones the repository with full git history.
Authenticates with Docker Hub using repository secrets.
Process:
  1. Builds image from server/Dockerfile
  2. Tags as pushkarverma/skillrise-server:latest
  3. Pushes to Docker Hub
  4. Replaces previous latest tag
Image size: ~150MB
Build time: ~2-3 minutes
2

Client Image Build

The build-and-push-client job creates the frontend Docker image:
Same as server: checks out code and authenticates with Docker Hub.
Build arguments:
  • VITE_CLERK_PUBLISHABLE_KEY - Embedded in build for authentication
  • VITE_STRIPE_PUBLISHABLE_KEY - Embedded in build for payments
  • VITE_BACKEND_URL - API endpoint URL
Multi-stage build:
  1. Stage 1: Compiles React app with Vite
  2. Stage 2: Copies build to Nginx image
Image size: ~25MB
Build time: ~3-4 minutes

Job Execution

Both jobs run in parallel for faster deployment. They are independent and don’t wait for each other.

Required Secrets

Configure these secrets in your GitHub repository settings:
DOCKER_USERNAME
Your Docker Hub username
DOCKER_PASSWORD
Docker Hub access token (recommended) or password
Use an access token instead of your password for better security. Generate one at Docker Hub Security Settings.
VITE_CLERK_PUBLISHABLE_KEY
Clerk publishable key for authentication
Example: pk_test_... or pk_live_...
VITE_STRIPE_PUBLISHABLE_KEY
Stripe publishable key for payments
Example: pk_test_... or pk_live_...
VITE_BACKEND_URL
Backend API URL
Example: https://api.yourdomain.com or http://localhost:3000
These are public keys safe to embed in the client bundle. Never add secret keys here.

Adding Secrets

1

Navigate to Repository Settings

Go to your GitHub repository → SettingsSecrets and variablesActions
2

Add New Secret

Click New repository secret
3

Enter Secret Details

  • Name: Use exact names from the list above (case-sensitive)
  • Value: Paste the secret value
  • Click Add secret
4

Verify

Secrets should appear in the list but values remain hidden

Triggering Deployments

Automatic Deployment

Deployment triggers automatically when:
Or when you merge a pull request to main:

Manual Deployment

To trigger manually without code changes:
1

Go to Actions Tab

Navigate to Actions in your GitHub repository
2

Select Deploy Workflow

Click on Build and Deploy to Docker Hub
3

Run Workflow

Click Run workflow → Select main branch → Run workflow

Monitoring Workflow Runs

View Run Status

  1. Go to the Actions tab in your repository
  2. Click on a workflow run to see details
  3. Expand jobs to view step-by-step logs

Status Indicators

Success

All jobs completed successfully

In Progress

Workflow is currently running

Failed

One or more jobs failed

Common Failure Reasons

ESLint errors:
Fix: Run npm run lint:fix locally and commit fixesPrettier errors:
Fix: Run npm run format locally and commit changesBuild errors:
Fix: Run npm run build locally to identify the issue
Docker login failed:
Fix: Verify DOCKER_USERNAME and DOCKER_PASSWORD secretsBuild context error:
Fix: Ensure Dockerfile exists in the correct directoryPush failed:
Fix: Check Docker Hub repository permissions and credentialsBuild args missing:
Fix: Verify all client build secrets are configured

Workflow Optimization

Caching Dependencies

Add caching to speed up builds:

Docker Layer Caching

Enable BuildKit cache:

Matrix Builds

Test multiple Node versions:

Advanced Workflows

Environment-Specific Deployments

Deploy to staging and production:

Slack Notifications

Send deployment status to Slack:

Automated Rollbacks

Revert to previous image on failure:

Best Practices

Version Tagging

Use semantic versioning alongside latest:

Branch Protection

Require CI checks to pass before merging:
  • Go to SettingsBranches
  • Add rule for main
  • Enable “Require status checks”
  • Select CI jobs

Secrets Rotation

Regularly rotate credentials:
  • Docker Hub tokens every 90 days
  • API keys when team members leave
  • Use different keys for staging/production

Monitoring

Track deployment metrics:
  • Build duration trends
  • Image size changes
  • Deployment frequency
  • Failure rates

Next Steps

Docker Deployment

Deploy with Docker Compose

Environment Variables

Configure application settings