الملفات

163 أسطر
5.6 KiB
YAML

name: CI/CD - Build, Push, Deploy (Ghaymah)
# Runs automatically on pushes to the main branch, or manually for any branch/environment via workflow_dispatch
on:
push:
branches: ["main"]
workflow_dispatch:
inputs:
image_tag:
description: "Optional extra image tag (default: git SHA)"
required: false
default: ""
# Least privilege permissions
permissions:
contents: read
packages: write
env:
# Docker Hub registry address
DOCKER_HUB_REGISTRY: docker.io
GHAYMAH_NAMESPACE: my-team
IMAGE_NAME: sample-api
PROJECT_STAGING_NAME: sample-api-staging
PROJECT_PRODUCTION_NAME: sample-api-production
jobs:
# ---------------------------------------------------------------------
# 1) Build the image, test it, and push it to Docker Hub
# ---------------------------------------------------------------------
build-and-push:
name: Build & Push Image
runs-on: ubuntu-latest
outputs:
image_ref: ${{ steps.vars.outputs.image_ref }}
steps:
- name: Checkout code
uses: actions/checkout@v5.0.0
- name: Set image tag variables
id: vars
run: |
SHORT_SHA=$(echo "${GITHUB_SHA}" | cut -c1-7)
TAG="${{ github.event.inputs.image_tag }}"
if [ -z "$TAG" ]; then TAG="$SHORT_SHA"; fi
IMAGE_REF="${DOCKER_HUB_REGISTRY}/${GHAYMAH_NAMESPACE}/${IMAGE_NAME}:${TAG}"
echo "image_ref=${IMAGE_REF}" >> "$GITHUB_OUTPUT"
echo "Building: ${IMAGE_REF}"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# Log in to Docker Hub using credentials stored as GitHub Secrets
- name: Log in to Ghaymah Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.DOCKER_HUB_REGISTRY }}
username: ${{ secrets.GHAYMAH_REGISTRY_USER }}
password: ${{ secrets.GHAYMAH_REGISTRY_TOKEN }}
- name: Build image
uses: docker/build-push-action@v6
with:
context: .
push: false
load: true
tags: |
${{ steps.vars.outputs.image_ref }}
${{ env.DOCKER_HUB_REGISTRY }}/${{ env.GHAYMAH_NAMESPACE }}/${{ env.IMAGE_NAME }}:latest
cache-from: type=gha
cache-to: type=gha,mode=max
# Quick smoke test to confirm /health responds before pushing
- name: Smoke test the built image
run: |
docker run -d --name smoke -p 8080:8080 ${{ steps.vars.outputs.image_ref }}
for i in $(seq 1 10); do
if curl -sf http://localhost:8080/health; then echo "Health check passed"; break; fi
echo "Waiting for app to start... ($i/10)"; sleep 2
done
curl -sf http://localhost:8080/health || (docker logs smoke && exit 1)
docker stop smoke
- name: Push image to Ghaymah Registry
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: |
${{ steps.vars.outputs.image_ref }}
${{ env.DOCKER_HUB_REGISTRY }}/${{ env.GHAYMAH_NAMESPACE }}/${{ env.IMAGE_NAME }}:latest
# ---------------------------------------------------------------------
# 2) Automatic deployment to STAGING right after a successful build - no manual approval
# ---------------------------------------------------------------------
deploy-staging:
name: Deploy to Staging
needs: build-and-push
runs-on: ubuntu-latest
environment:
name: staging
steps:
- name: Install Ghaymah CLI
run: |
curl -fsSL https://cli.ghaymah.systems/install.sh | sh
gy version
- name: Authenticate Ghaymah CLI
run: gy auth login -e "${{ secrets.GHAYMAH_Email }}" -p "${{ secrets.GHAYMAH_PASSWORD }}"
- name: create project
run: gy resource project create -s .name=${{ env.PROJECT_STAGING_NAME }} || true
- name: get project id
id: get_project_id
run: |
echo "PROJECT_ID=$(gy resource project get | grep -oP '"id"\s*:\s*"\K[^"]+')" >> $GITHUB_ENV
- name: initialize application in Ghaymah
run: gy resource app init . -p ${{ env.PROJECT_ID }}
- name: Deploy Application to Staging
run: |
gy resource app launch
# ---------------------------------------------------------------------
# 3) Deploy to PRODUCTION - requires manual approval
# Approval is handled by the protected GitHub Environment "production"
# with Required Reviewers in repository settings, not by custom code.
# ---------------------------------------------------------------------
deploy-production:
name: Deploy to Production (Manual Approval Required)
needs: [build-and-push, deploy-staging]
runs-on: ubuntu-latest
environment:
name: production # This line enables the manual approval gate configured in repository settings
steps:
- name: Install Ghaymah CLI
run: |
curl -fsSL https://cli.ghaymah.systems/install.sh | sh
gy version
- name: Authenticate Ghaymah CLI
run: gy auth login -e "${{ secrets.GHAYMAH_Email }}" -p "${{ secrets.GHAYMAH_PASSWORD }}"
- name: create project
run: gy resource project create -s .name=${{ env.PROJECT_PRODUCTION_NAME }} || true
- name: get project id
id: get_project_id
run: |
echo "PROJECT_ID=$(gy resource project get | grep -oP '"id"\s*:\s*"\K[^"]+')" >> $GITHUB_ENV
- name: initialize application in Ghaymah
run: gy resource app init . -p ${{ env.PROJECT_ID }}
- name: Deploy Application to Production
run: |
gy resource app launch