Skip to main content

CI/CD

In this project, CI/CD (Continuous Integration / Continuous Deployment) processes are managed via GitHub Actions. When developers push their code to certain branches, workflows are automatically triggered to update, test, and deploy the application.

Environments

Currently, we have two main environments:

  • dev
  • prod

In the near future, a preprod environment is planned to be added for releases.

The file structure is as follows:

.github
└── workflows
├── dev-deployment.yml
├── main-deployment.yml
└── preprod-deployment.yml

Example Workflow: Dev Environment

Below is an example GitHub Actions workflow used for the backend. This structure is automatically triggered when code is pushed to the dev branch and allows code to be deployed from the bastion host to the application server (App VM).

name: "DEV Deployment Flow"

on:
push:
branches: [dev]

jobs:
build:
name: "Bastion to App Deployment"
runs-on: ubuntu-latest

steps:
- name: "📍 Checkout DEV Branch"
uses: actions/checkout@v4
with:
ref: dev
fetch-depth: 0

- name: "🚀 Connect to Bastion & Deploy to App VM"
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.BASTION_HOST }}
username: ${{ secrets.BASTION_USER }}
key: ${{ secrets.BASTION_KEY }}
port: ${{ secrets.BASTION_PORT }}
script: |
echo "🔌 Connected to Bastion. Jumping to App VM via 'dev_app'..."

ssh -T dev_app << 'ENDSSH'
set -e

echo "📂 Navigating to /var/www/backend..."
cd /var/www/backend

echo "⬇️ Pulling latest code..."
git pull origin dev

echo "🟢 Loading NVM and Node 24..."
[ -s "$HOME/.nvm/nvm.sh" ] && \. "$HOME/.nvm/nvm.sh"
nvm use 24

echo "📦 Installing dependencies..."
npm ci --legacy-peer-deps

echo "🔨 Building Application..."
npm run build

echo "🔄 Restarting re_api..."
pm2 restart re_api

echo "✅ Deployment Scripts Finished Successfully."
ENDSSH

- name: "✈️ Telegram Notification"
if: success()
run: |
COMMIT_MSG=$(git log -1 --pretty=format:'%s')
SAFE_COMMIT_MSG=$(echo "$COMMIT_MSG" | sed 's/"/\\"/g')

MESSAGE="🔥 *[NEW API]* DEV Deployment Successful%0A%0A📝 *Commit:* \`$SAFE_COMMIT_MSG\`"

curl -s -X POST "https://api.telegram.org/bot${{ secrets.TELEGRAM_BOT_TOKEN }}/sendMessage" \
-d chat_id="${{ secrets.TELEGRAM_CHAT_ID }}" \
-d text="$MESSAGE" \
-d parse_mode="Markdown"

Step-by-Step Deployment Process

The main steps that occur in this workflow are as follows:

  1. Checkout: The dev branch containing the latest changes is checked out.
  2. Connecting via Bastion: Access to the bastion server is established via SSH, followed by access to the application server.
  3. Change to Directory: Navigate to the /var/www/backend directory containing the backend code.
  4. Update the Code: Pull the latest changes using Git (git pull origin dev).
  5. Environment Setup: Load and activate the required Node.js version (24) via NVM.
  6. Install Dependencies: Clean installation of all frontend/backend dependencies (npm ci --legacy-peer-deps).
  7. Build: Build the application (npm run build).
  8. Restart Service: Restart the application service with PM2 (pm2 restart re_api).
  9. Telegram Notification: Once deployment is successful, send an automatic notification (including the latest commit message) to the relevant Telegram channel.

Secrets

For secure workflow execution, the following environment secrets must be defined in the GitHub organization:

  • BASTION_HOST
  • BASTION_USER
  • BASTION_KEY
  • BASTION_PORT
  • TELEGRAM_BOT_TOKEN
  • TELEGRAM_CHAT_ID

You can create different workflow files for each environment (e.g., prod, dev, preprod), and tailor them as needed (branch name, environment variables, etc.).