Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41cd1b3778 | ||
|
|
02e38e435b | ||
|
|
7fc8140dfb | ||
|
|
a9a876086d | ||
|
|
c445761f97 | ||
|
|
22d26b2ea0 | ||
|
|
4f1b736552 | ||
|
|
5429e09e01 | ||
|
|
744f736e9a | ||
|
|
13c1b3b773 | ||
|
|
2bbeeb682c | ||
|
|
d59af8fcc6 | ||
|
|
5224048ad8 | ||
|
|
ba5074718c |
@@ -0,0 +1,88 @@
|
||||
name: Deploy to Staging
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ dev ]
|
||||
|
||||
concurrency:
|
||||
group: staging-${{ github.repository }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
build-and-deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
driver-opts: network=host
|
||||
|
||||
- name: Generate Version
|
||||
id: version
|
||||
run: echo "VERSION=1.0.0-dev.${{ github.run_number }}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Build Docker Image
|
||||
env:
|
||||
IMAGE_NAME: ${{ vars.SERVICE_NAME || github.event.repository.name }}
|
||||
VERSION: ${{ steps.version.outputs.VERSION }}
|
||||
run: |
|
||||
docker build \
|
||||
--tag ${{ secrets.NEXUS_REGISTRY }}/$IMAGE_NAME:$VERSION \
|
||||
--tag ${{ secrets.NEXUS_REGISTRY }}/$IMAGE_NAME:1.0.0-latest \
|
||||
--build-arg NEXUS_REGISTRY=${{ secrets.NEXUS_REGISTRY }} \
|
||||
.
|
||||
|
||||
- name: Login to Nexus
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ secrets.NEXUS_REGISTRY }}
|
||||
username: ${{ secrets.NEXUS_USER }}
|
||||
password: ${{ secrets.NEXUS_PASS }}
|
||||
|
||||
- name: Push to Nexus
|
||||
env:
|
||||
IMAGE_NAME: ${{ vars.SERVICE_NAME || github.event.repository.name }}
|
||||
VERSION: ${{ steps.version.outputs.VERSION }}
|
||||
run: |
|
||||
docker push ${{ secrets.NEXUS_REGISTRY }}/$IMAGE_NAME:$VERSION
|
||||
docker push ${{ secrets.NEXUS_REGISTRY }}/$IMAGE_NAME:1.0.0-latest
|
||||
|
||||
- name: Deploy to Staging
|
||||
env:
|
||||
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||
STAGING_HOST: ${{ secrets.STAGING_HOST }}
|
||||
STAGING_USER: ${{ secrets.STAGING_USER }}
|
||||
IMAGE_NAME: ${{ vars.SERVICE_NAME || github.event.repository.name }}
|
||||
VERSION: ${{ steps.version.outputs.VERSION }}
|
||||
run: |
|
||||
mkdir -p ~/.ssh
|
||||
echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
|
||||
chmod 600 ~/.ssh/id_rsa
|
||||
ssh-keyscan -H $STAGING_HOST >> ~/.ssh/known_hosts
|
||||
|
||||
ssh $STAGING_USER@$STAGING_HOST "
|
||||
cd /srv/staging/narng-platform/compose
|
||||
docker compose pull $IMAGE_NAME
|
||||
export ${IMAGE_NAME}_TAG=$VERSION
|
||||
docker compose up -d $IMAGE_NAME
|
||||
"
|
||||
|
||||
- name: Wait for Health Check
|
||||
env:
|
||||
IMAGE_NAME: ${{ vars.SERVICE_NAME || github.event.repository.name }}
|
||||
run: sleep 15
|
||||
|
||||
- name: Run Smoke Test
|
||||
env:
|
||||
STAGING_HOST: ${{ secrets.STAGING_HOST }}
|
||||
run: |
|
||||
STATUS=$(curl -sk -o /dev/null -w "%{http_code}" https://api.$STAGING_HOST/api/categories || echo "000")
|
||||
if [ "$STATUS" != "200" ]; then
|
||||
echo "Smoke test failed with status $STATUS"
|
||||
exit 1
|
||||
fi
|
||||
echo "Smoke test passed!"
|
||||
|
||||
+70
-143
@@ -1,184 +1,111 @@
|
||||
name: Dev Deploy to Staging
|
||||
name: Central Deploy
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
workflow_dispatch:
|
||||
workflow_call:
|
||||
inputs:
|
||||
repo_name:
|
||||
description: 'Repository to build and deploy (e.g., narng-api)'
|
||||
required: true
|
||||
type: string
|
||||
branch:
|
||||
description: 'Branch to deploy'
|
||||
required: true
|
||||
default: 'dev'
|
||||
type: string
|
||||
|
||||
env:
|
||||
REGISTRY: 192.168.1.8:8084
|
||||
COMPOSE_PATH: /srv/staging/narng-platform/compose
|
||||
ORG: narng-platform
|
||||
|
||||
jobs:
|
||||
build-and-deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
- name: Checkout service code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ env.ORG }}/${{ inputs.repo_name }}
|
||||
ref: ${{ inputs.branch }}
|
||||
token: ${{ secrets.NARNG_GIT_TOKEN }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Determine service metadata
|
||||
- name: Detect service metadata
|
||||
id: meta
|
||||
run: |
|
||||
REPO_NAME=$(basename ${{ github.repository }})
|
||||
REPO_NAME="${{ inputs.repo_name }}"
|
||||
case "$REPO_NAME" in
|
||||
narng-api-laravel) SERVICE="laravel"; TAG_VAR="LARAVEL_TAG" ;;
|
||||
narng-api|narng-api-gateway) SERVICE="api"; TAG_VAR="API_TAG" ;;
|
||||
narng-web-app) SERVICE="web"; TAG_VAR="WEB_TAG" ;;
|
||||
*) SERVICE=$(echo "$REPO_NAME" | sed 's/^narng-//'); TAG_VAR=$(echo "$SERVICE" | tr '[:lower:]' '[:upper:]')_TAG ;;
|
||||
*)
|
||||
SERVICE=$(echo "$REPO_NAME" | sed 's/^narng-//')
|
||||
TAG_VAR=$(echo "$SERVICE" | tr '[:lower:]' '[:upper:]')_TAG
|
||||
;;
|
||||
esac
|
||||
echo "SERVICE=$SERVICE" >> $GITHUB_OUTPUT
|
||||
echo "TAG_VAR=$TAG_VAR" >> $GITHUB_OUTPUT
|
||||
echo "IMAGE=${{ env.REGISTRY }}/$REPO_NAME" >> $GITHUB_OUTPUT
|
||||
echo "service=$SERVICE" >> $GITHUB_OUTPUT
|
||||
echo "tag_var=$TAG_VAR" >> $GITHUB_OUTPUT
|
||||
echo "image=${{ env.REGISTRY }}/${{ env.ORG }}/$REPO_NAME" >> $GITHUB_OUTPUT
|
||||
echo "version=1.0.0-dev.${{ github.run_number }}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Generate version
|
||||
id: version
|
||||
run: echo "VERSION=1.0.0-dev.${{ github.run_number }}" >> $GITHUB_OUTPUT
|
||||
- name: Prepare SSH key
|
||||
env:
|
||||
STAGING_SSH_KEY: ${{ secrets.STAGING_SSH_KEY }}
|
||||
run: |
|
||||
echo "$STAGING_SSH_KEY" > /tmp/deploy_key_raw
|
||||
if head -1 /tmp/deploy_key_raw | grep -q "BEGIN OPENSSH PRIVATE KEY"; then
|
||||
cp /tmp/deploy_key_raw /tmp/deploy_key
|
||||
else
|
||||
base64 -d /tmp/deploy_key_raw > /tmp/deploy_key
|
||||
fi
|
||||
chmod 600 /tmp/deploy_key
|
||||
ssh-keygen -l -f /tmp/deploy_key || { echo "ERROR: Invalid SSH key"; exit 1; }
|
||||
|
||||
- name: Login to Nexus
|
||||
run: echo "${{ secrets.NEXUS_PASS }}" | docker login ${{ env.REGISTRY }} -u "${{ secrets.NEXUS_USER }}" --password-stdin
|
||||
|
||||
- name: Build Docker image
|
||||
env:
|
||||
DOCKER_BUILDKIT: 1
|
||||
run: |
|
||||
IMAGE=${{ steps.meta.outputs.IMAGE }}
|
||||
VERSION=${{ steps.version.outputs.VERSION }}
|
||||
docker buildx build --builder default --tag "$IMAGE:$VERSION" --tag "$IMAGE:1.0.0-latest" --load . 2>&1 | tail -20
|
||||
|
||||
- name: Login to Nexus
|
||||
env:
|
||||
NEXUS_USER: ${{ secrets.NEXUS_USER }}
|
||||
NEXUS_PASS: ${{ secrets.NEXUS_PASS }}
|
||||
run: echo "$NEXUS_PASS" | docker login ${{ env.REGISTRY }} -u "$NEXUS_USER" --password-stdin
|
||||
IMAGE=${{ steps.meta.outputs.image }}
|
||||
VERSION=${{ steps.meta.outputs.version }}
|
||||
docker buildx build \
|
||||
--builder default \
|
||||
--no-cache \
|
||||
--tag "$IMAGE:$VERSION" \
|
||||
--tag "$IMAGE:1.0.0-latest" \
|
||||
--load . 2>&1 | tail -30
|
||||
|
||||
- name: Push to Nexus
|
||||
run: |
|
||||
IMAGE=${{ steps.meta.outputs.IMAGE }}
|
||||
VERSION=${{ steps.version.outputs.VERSION }}
|
||||
IMAGE=${{ steps.meta.outputs.image }}
|
||||
VERSION=${{ steps.meta.outputs.version }}
|
||||
docker push "$IMAGE:$VERSION"
|
||||
docker push "$IMAGE:1.0.0-latest"
|
||||
|
||||
- name: Deploy to staging via SSH
|
||||
uses: appleboy/ssh-action@v1.0.3
|
||||
env:
|
||||
NEXUS_USER: ${{ secrets.NEXUS_USER }}
|
||||
NEXUS_PASS: ${{ secrets.NEXUS_PASS }}
|
||||
SERVICE: ${{ steps.meta.outputs.service }}
|
||||
VERSION: ${{ steps.meta.outputs.version }}
|
||||
TAG_VAR: ${{ steps.meta.outputs.tag_var }}
|
||||
REGISTRY: ${{ env.REGISTRY }}
|
||||
COMPOSE_PATH: ${{ env.COMPOSE_PATH }}
|
||||
with:
|
||||
host: ${{ secrets.STAGING_HOST }}
|
||||
username: ${{ secrets.STAGING_USER }}
|
||||
key: ${{ secrets.STAGING_SSH_KEY }}
|
||||
key_path: /tmp/deploy_key
|
||||
port: 2222
|
||||
envs: NEXUS_USER,NEXUS_PASS,SERVICE,VERSION,TAG_VAR,REGISTRY,COMPOSE_PATH
|
||||
script: |
|
||||
SERVICE=${{ steps.meta.outputs.SERVICE }}
|
||||
VERSION=${{ steps.version.outputs.VERSION }}
|
||||
TAG_VAR=${{ steps.meta.outputs.TAG_VAR }}
|
||||
set -ex
|
||||
echo "Deploying $SERVICE:$VERSION"
|
||||
|
||||
sed -i "s|^${TAG_VAR}=.*|${TAG_VAR}=${VERSION}|" /srv/staging/narng-platform/compose/.env
|
||||
|
||||
cd /srv/staging/narng-platform/compose
|
||||
docker compose pull $SERVICE
|
||||
docker compose up -d --force-recreate --no-deps $SERVICE
|
||||
echo "$NEXUS_PASS" | docker login "$REGISTRY" -u "$NEXUS_USER" --password-stdin
|
||||
sed -i "s|^${TAG_VAR}=.*|${TAG_VAR}=${VERSION}|" "$COMPOSE_PATH/.env"
|
||||
cd "$COMPOSE_PATH"
|
||||
docker compose pull "$SERVICE"
|
||||
docker compose up -d --force-recreate --no-deps "$SERVICE"
|
||||
docker image prune -f
|
||||
|
||||
# name: Dev Deploy to Staging
|
||||
# on:
|
||||
# push:
|
||||
# branches:
|
||||
# - dev
|
||||
# workflow_dispatch:
|
||||
# workflow_call: # برای استفاده در ریپوهای دیگر
|
||||
|
||||
# env:
|
||||
# REGISTRY: 192.168.1.8:8084
|
||||
|
||||
# jobs:
|
||||
# build-and-deploy:
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
# - name: Checkout code
|
||||
# uses: actions/checkout@v4
|
||||
# with:
|
||||
# fetch-depth: 0
|
||||
|
||||
# - name: Determine service metadata
|
||||
# id: meta
|
||||
# run: |
|
||||
# REPO_NAME=$(basename ${{ github.repository }})
|
||||
# case "$REPO_NAME" in
|
||||
# narng-api-laravel)
|
||||
# SERVICE="laravel"
|
||||
# TAG_VAR="LARAVEL_TAG"
|
||||
# ;;
|
||||
# narng-api | narng-api-gateway)
|
||||
# SERVICE="api"
|
||||
# TAG_VAR="API_TAG"
|
||||
# ;;
|
||||
# narng-web-app)
|
||||
# SERVICE="web"
|
||||
# TAG_VAR="WEB_TAG"
|
||||
# ;;
|
||||
# *)
|
||||
# SERVICE=$(echo "$REPO_NAME" | sed 's/^narng-//')
|
||||
# TAG_VAR=$(echo "$SERVICE" | tr '[:lower:]' '[:upper:]')_TAG
|
||||
# ;;
|
||||
# esac
|
||||
# echo "SERVICE=$SERVICE" >> $GITHUB_OUTPUT
|
||||
# echo "TAG_VAR=$TAG_VAR" >> $GITHUB_OUTPUT
|
||||
# echo "REPO_NAME=$REPO_NAME" >> $GITHUB_OUTPUT
|
||||
# echo "IMAGE=${{ env.REGISTRY }}/$REPO_NAME" >> $GITHUB_OUTPUT
|
||||
|
||||
# - name: Generate version
|
||||
# id: version
|
||||
# run: |
|
||||
# VERSION="1.0.0-dev.${{ github.run_number }}"
|
||||
# echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
|
||||
|
||||
# - name: Build Docker image
|
||||
# env:
|
||||
# DOCKER_BUILDKIT: 1
|
||||
# run: |
|
||||
# IMAGE=${{ steps.meta.outputs.IMAGE }}
|
||||
# VERSION=${{ steps.version.outputs.VERSION }}
|
||||
# export DOCKER_BUILDKIT=1
|
||||
# docker buildx build \
|
||||
# --builder default \
|
||||
# --tag "$IMAGE:$VERSION" \
|
||||
# --tag "$IMAGE:1.0.0-latest" \
|
||||
# --load \
|
||||
# . 2>&1 | tail -20
|
||||
|
||||
# - name: Login to Nexus
|
||||
# env:
|
||||
# NEXUS_USER: ${{ secrets.NEXUS_USER }}
|
||||
# NEXUS_PASS: ${{ secrets.NEXUS_PASS }}
|
||||
# run: |
|
||||
# echo "$NEXUS_PASS" | docker login ${{ env.REGISTRY }} -u "$NEXUS_USER" --password-stdin
|
||||
|
||||
# - name: Push to Nexus
|
||||
# run: |
|
||||
# IMAGE=${{ steps.meta.outputs.IMAGE }}
|
||||
# VERSION=${{ steps.version.outputs.VERSION }}
|
||||
# docker push "$IMAGE:$VERSION"
|
||||
# docker push "$IMAGE:1.0.0-latest"
|
||||
|
||||
# - name: Deploy to staging (Host-level)
|
||||
# run: |
|
||||
# SERVICE=${{ steps.meta.outputs.SERVICE }}
|
||||
# VERSION=${{ steps.version.outputs.VERSION }}
|
||||
# TAG_VAR=${{ steps.meta.outputs.TAG_VAR }}
|
||||
# echo "Deploying $SERVICE:$VERSION"
|
||||
|
||||
# # آپدیت فایل .env در مسیر صحیح سرور
|
||||
# docker run --rm -v /srv/staging/narng-platform:/srv/staging/narng-platform alpine sh -c "sed -i 's|^${TAG_VAR}=.*|${TAG_VAR}=${VERSION}|' /srv/staging/narng-platform/compose/.env"
|
||||
|
||||
# # ریاستارت کانتینر با استفاده از فایل .env صحیح
|
||||
# docker run --rm \
|
||||
# -v /var/run/docker.sock:/var/run/docker.sock \
|
||||
# -v /srv/staging/narng-platform:/srv/staging/narng-platform:ro \
|
||||
# -w /srv/staging/narng-platform/compose \
|
||||
# docker:24-cli \
|
||||
# sh -c "docker compose --env-file .env up -d --no-deps $SERVICE"
|
||||
|
||||
# - name: Verify
|
||||
# run: |
|
||||
# SERVICE=${{ steps.meta.outputs.SERVICE }}
|
||||
# CONTAINER="staging-narng-${SERVICE}"
|
||||
# sleep 10
|
||||
# STATUS=$(docker inspect --format='{{.State.Status}}' "$CONTAINER" 2>/dev/null || echo "not found")
|
||||
# echo "Container: $CONTAINER - Status: $STATUS"
|
||||
echo "✅ $SERVICE:$VERSION deployed"
|
||||
@@ -0,0 +1,25 @@
|
||||
name: Test SSH Connection
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Test SSH
|
||||
env:
|
||||
STAGING_SSH_KEY: ${{ secrets.STAGING_SSH_KEY }}
|
||||
STAGING_HOST: ${{ secrets.STAGING_HOST }}
|
||||
STAGING_USER: ${{ secrets.STAGING_USER }}
|
||||
run: |
|
||||
echo "$STAGING_SSH_KEY" > /tmp/key_raw
|
||||
if head -1 /tmp/key_raw | grep -q "BEGIN OPENSSH"; then
|
||||
cp /tmp/key_raw /tmp/key
|
||||
else
|
||||
base64 -d /tmp/key_raw > /tmp/key
|
||||
fi
|
||||
chmod 600 /tmp/key
|
||||
echo "=== Key fingerprint ==="
|
||||
ssh-keygen -l -f /tmp/key
|
||||
echo "=== SSH Test ==="
|
||||
ssh -i /tmp/key -p 2222 -o StrictHostKeyChecking=no $STAGING_USER@$STAGING_HOST "echo SSH_OK && docker ps --format '{{.Names}}' | head -3"
|
||||
@@ -0,0 +1,5 @@
|
||||
node_modules/
|
||||
test-results/
|
||||
playwright-report/
|
||||
.env
|
||||
*.log
|
||||
@@ -0,0 +1,18 @@
|
||||
Narng CI/CD
|
||||
این ریپو حاوی کانفیگها و اسکریپتهای مرکزی CI/CD برای پروژه Narng است.
|
||||
|
||||
ساختار
|
||||
.gitea/workflows/deploy-staging.yml: Pipeline اصلی برای Deploy به Staging (شاخه dev).
|
||||
scripts/: اسکریپتهای کمکی برای Deploy.
|
||||
نحوه استفاده
|
||||
برای فعالسازی این Pipeline در یک سرویس (مثلاً narng-auth):
|
||||
|
||||
فایل .gitea/workflows/deploy-staging.yml را در ریپو سرویس ایجاد کنید.
|
||||
در صورت نیاز، متغیر SERVICE_NAME را در تنظیمات ریپو سرویس تنظیم کنید.
|
||||
در صورت نیاز، Secrets زیر را در ریپو سرویس تنظیم کنید:
|
||||
NEXUS_REGISTRY: آدرس Registry (مثلاً 192.168.1.8:8084)
|
||||
NEXUS_USER: کاربری Nexus
|
||||
NEXUS_PASS: پسورد Nexus
|
||||
SSH_PRIVATE_KEY: کلید خصوصی SSH برای دسترسی به سرور
|
||||
STAGING_HOST: آدرس سرور Staging
|
||||
STAGING_USER: کاربری سرور (مثلاً root)
|
||||
Reference in New Issue
Block a user