Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 155 additions & 0 deletions .github/workflows/cicdpipeline.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
name: CI/CD Pipeline

# 1️⃣ Triggers: push to main, PRs, and manual deploy
on:
push:
branches:
- main
pull_request:
branches:
- main
workflow_dispatch:
inputs:
deploy:
description: 'Deploy to production now?'
required: false
default: 'no'

jobs:
# ──────────────
# Build + Test
# ──────────────
ci:
name: Build & Test
runs-on: ubuntu-latest
environment: testing

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Cache node_modules
uses: actions/cache@v3
with:
path: node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Lint
run: npm run lint

- name: Run tests
run: npm test -- --ci --reporter=jest-junit

- name: Upload test report
uses: actions/upload-artifact@v3
with:
name: test-results
path: junit.xml

- name: Build application
run: npm run build

# ──────────────
# Code Security & Quality
# ──────────────
code_scan:
name: Security & Code Quality
needs: ci
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: CodeQL Analysis
uses: github/codeql-action/init@v2
with:
languages: javascript
- name: Perform CodeQL scan
uses: github/codeql-action/analyze@v2

- name: SonarCloud Scan
uses: sonarsource/sonarcloud-github-action@master
with:
organization: your-org
projectKey: your-org_your-repo
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

# ──────────────
# Docker Build & Push
# ──────────────
docker:
name: Build & Push Docker Image
needs: [ci, code_scan]
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Log in to registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: |
ghcr.io/${{ github.repository_owner }}/your-app:latest
ghcr.io/${{ github.repository_owner }}/your-app:${{ github.sha }}

# ──────────────
# Deploy to Production
# ──────────────
deploy:
name: Deploy to Production
if: >
github.event_name == 'workflow_dispatch' &&
github.event.inputs.deploy == 'yes'
|| (github.event_name == 'push' && github.ref == 'refs/heads/main')
needs: docker
runs-on: ubuntu-latest
environment:
name: production
url: https://your-app.example.com
deployment_branch: main

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup SSH
uses: webfactory/ssh-agent@v0.9.1
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}

- name: Deploy via Ansible
run: |
ansible-playbook -i inventory/prod deploy.yml \
--extra-vars "image_tag=${{ github.sha }}"

- name: Notify Slack
if: success()
uses: 8398a7/action-slack@v3
with:
status: success
fields: repo,commit,author
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}