feat: add live deploy target with multi-instance support to deploy-module.yml
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: Cascade Main → Dev / Cascade main → branches (push) Successful in 3s
Platform: moko-platform CI / Gate 1: Code Quality (push) Failing after 44s
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Has been cancelled
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Has been cancelled
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Has been cancelled
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Has been cancelled
Platform: moko-platform CI / Gate 4: Governance (push) Has been cancelled
Platform: moko-platform CI / Gate 5: Template Integrity (push) Has been cancelled
Platform: moko-platform CI / CI Summary (push) Has been cancelled
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: Cascade Main → Dev / Cascade main → branches (push) Successful in 3s
Platform: moko-platform CI / Gate 1: Code Quality (push) Failing after 44s
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Has been cancelled
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Has been cancelled
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Has been cancelled
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Has been cancelled
Platform: moko-platform CI / Gate 4: Governance (push) Has been cancelled
Platform: moko-platform CI / Gate 5: Template Integrity (push) Has been cancelled
Platform: moko-platform CI / CI Summary (push) Has been cancelled
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
- Add 'live' and 'all' options to server selector - Live deploy reads LIVE_TARGETS JSON secret for multiple production instances - Move dev/demo host config from hardcoded env to vars.* - Add summary step for deploy reporting Authored-by: Moko Consulting Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,28 @@
|
||||
name: Deploy Dolibarr Module
|
||||
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
#
|
||||
# FILE INFORMATION
|
||||
# DEFGROUP: Gitea.Workflow
|
||||
# INGROUP: moko-platform.Deploy
|
||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
|
||||
# PATH: /templates/workflows/deploy-module.yml
|
||||
# VERSION: 02.00.00
|
||||
# BRIEF: Deploy Dolibarr module to dev, demo, or live environments
|
||||
#
|
||||
# Secrets required:
|
||||
# GA_TOKEN - Gitea API token for repo access
|
||||
# DEPLOY_SSH_KEY - SSH private key for server access
|
||||
# LIVE_TARGETS - JSON array of live instances (optional), e.g.:
|
||||
# [{"host":"client1.example.com","user":"deploy",
|
||||
# "mods_dir":"/path/MokoDoliMods",
|
||||
# "custom_dir":"/path/htdocs/custom"}]
|
||||
#
|
||||
# Variables required:
|
||||
# DEV_HOST, DEV_USER, DEV_MODS_DIR, DEV_CUSTOM_DIR
|
||||
# DEMO_HOST, DEMO_USER, DEMO_MODS_DIR, DEMO_CUSTOM_DIR
|
||||
|
||||
name: "Dolibarr: Deploy Module"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
@@ -7,30 +31,26 @@ on:
|
||||
description: 'Module repo name (e.g. MokoCRM, MokoDoliSign)'
|
||||
required: true
|
||||
server:
|
||||
description: 'Target server'
|
||||
description: 'Target environment'
|
||||
required: true
|
||||
default: 'dev'
|
||||
type: choice
|
||||
options:
|
||||
- dev
|
||||
- demo
|
||||
- both
|
||||
- live
|
||||
- dev+demo
|
||||
- all
|
||||
|
||||
env:
|
||||
GITEA_URL: https://git.mokoconsulting.tech
|
||||
ORG: MokoConsulting
|
||||
DEV_HOST: waas.dev.mokoconsulting.tech
|
||||
DEV_USER: mokoconsulting_dev
|
||||
DEV_MODS_DIR: /home/mokoconsulting_dev/MokoDoliMods
|
||||
DEV_CUSTOM_DIR: /home/mokoconsulting_dev/crm.dev.mokoconsulting.tech/htdocs/custom
|
||||
DEMO_HOST: waas.demo.mokoconsulting.tech
|
||||
DEMO_USER: mokoconsulting_demo
|
||||
DEMO_MODS_DIR: /home/mokoconsulting_demo/MokoDoliMods
|
||||
DEMO_CUSTOM_DIR: /home/mokoconsulting_demo/crm.demo.mokoconsulting.tech/htdocs/custom
|
||||
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
|
||||
ORG: ${{ vars.GITEA_ORG || 'MokoConsulting' }}
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
name: Deploy ${{ inputs.module_repo }} to ${{ inputs.server }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Validate module repo
|
||||
run: |
|
||||
@@ -39,11 +59,11 @@ jobs:
|
||||
-H "Authorization: token ${{ secrets.GA_TOKEN }}" \
|
||||
"${GITEA_URL}/api/v1/repos/${ORG}/${REPO}")
|
||||
if [ "$STATUS" != "200" ]; then
|
||||
echo "ERROR: ${ORG}/${REPO} not found"; exit 1
|
||||
echo "::error::${ORG}/${REPO} not found (HTTP ${STATUS})"
|
||||
exit 1
|
||||
fi
|
||||
echo "REPO=${REPO}" >> $GITHUB_ENV
|
||||
|
||||
# Derive symlink name
|
||||
LINK_NAME=$(echo "$REPO" | sed 's/MokoDoli//;s/Moko//' | tr '[:upper:]' '[:lower:]')
|
||||
[ "$REPO" = "MokoCRM" ] && LINK_NAME="mokocrm"
|
||||
[ "$REPO" = "MokoDoliProjTemplate" ] && LINK_NAME="mokoprojtemplate"
|
||||
@@ -56,27 +76,27 @@ jobs:
|
||||
"${GITEA_URL}/api/v1/repos/${ORG}/${{ env.REPO }}/tags?limit=1")
|
||||
TAG=$(echo "$TAGS" | jq -r '.[0].name // empty')
|
||||
echo "TAG=${TAG}" >> $GITHUB_ENV
|
||||
[ -n "$TAG" ] && echo "Deploying: $TAG" || echo "No tags — deploying main"
|
||||
[ -n "$TAG" ] && echo "Deploying: $TAG" || echo "No tags - deploying main"
|
||||
|
||||
- name: Deploy to dev
|
||||
if: inputs.server == 'dev' || inputs.server == 'both'
|
||||
if: inputs.server == 'dev' || inputs.server == 'dev+demo' || inputs.server == 'all'
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ env.DEV_HOST }}
|
||||
username: ${{ env.DEV_USER }}
|
||||
host: ${{ vars.DEV_HOST }}
|
||||
username: ${{ vars.DEV_USER }}
|
||||
key: ${{ secrets.DEPLOY_SSH_KEY }}
|
||||
script: |
|
||||
REPO="${{ env.REPO }}"
|
||||
LINK="${{ env.LINK_NAME }}"
|
||||
TAG="${{ env.TAG }}"
|
||||
MODS="${{ env.DEV_MODS_DIR }}"
|
||||
CUSTOM="${{ env.DEV_CUSTOM_DIR }}"
|
||||
MODS="${{ vars.DEV_MODS_DIR }}"
|
||||
CUSTOM="${{ vars.DEV_CUSTOM_DIR }}"
|
||||
|
||||
mkdir -p "$MODS" && cd "$MODS"
|
||||
if [ -d "$REPO" ]; then
|
||||
cd "$REPO" && git fetch --tags origin
|
||||
else
|
||||
git clone "https://git.mokoconsulting.tech/${{ env.ORG }}/${REPO}.git"
|
||||
git clone "${{ env.GITEA_URL }}/${{ env.ORG }}/${REPO}.git"
|
||||
cd "$REPO"
|
||||
fi
|
||||
|
||||
@@ -90,27 +110,27 @@ jobs:
|
||||
cd "$CUSTOM"
|
||||
[ -L "$LINK" ] || [ -d "$LINK" ] && rm -rf "$LINK"
|
||||
ln -sf "$MODS/$REPO/src" "$LINK"
|
||||
echo "OK: $LINK → $MODS/$REPO/src (${TAG:-main})"
|
||||
echo "OK: $LINK -> $MODS/$REPO/src (${TAG:-main})"
|
||||
|
||||
- name: Deploy to demo
|
||||
if: inputs.server == 'demo' || inputs.server == 'both'
|
||||
if: inputs.server == 'demo' || inputs.server == 'dev+demo' || inputs.server == 'all'
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ env.DEMO_HOST }}
|
||||
username: ${{ env.DEMO_USER }}
|
||||
host: ${{ vars.DEMO_HOST }}
|
||||
username: ${{ vars.DEMO_USER }}
|
||||
key: ${{ secrets.DEPLOY_SSH_KEY }}
|
||||
script: |
|
||||
REPO="${{ env.REPO }}"
|
||||
LINK="${{ env.LINK_NAME }}"
|
||||
TAG="${{ env.TAG }}"
|
||||
MODS="${{ env.DEMO_MODS_DIR }}"
|
||||
CUSTOM="${{ env.DEMO_CUSTOM_DIR }}"
|
||||
MODS="${{ vars.DEMO_MODS_DIR }}"
|
||||
CUSTOM="${{ vars.DEMO_CUSTOM_DIR }}"
|
||||
|
||||
mkdir -p "$MODS" && cd "$MODS"
|
||||
if [ -d "$REPO" ]; then
|
||||
cd "$REPO" && git fetch --tags origin
|
||||
else
|
||||
git clone "https://git.mokoconsulting.tech/${{ env.ORG }}/${REPO}.git"
|
||||
git clone "${{ env.GITEA_URL }}/${{ env.ORG }}/${REPO}.git"
|
||||
cd "$REPO"
|
||||
fi
|
||||
|
||||
@@ -124,4 +144,80 @@ jobs:
|
||||
cd "$CUSTOM"
|
||||
[ -L "$LINK" ] || [ -d "$LINK" ] && rm -rf "$LINK"
|
||||
ln -sf "$MODS/$REPO/src" "$LINK"
|
||||
echo "OK: $LINK → $MODS/$REPO/src (${TAG:-main})"
|
||||
echo "OK: $LINK -> $MODS/$REPO/src (${TAG:-main})"
|
||||
|
||||
- name: Deploy to live
|
||||
if: inputs.server == 'live' || inputs.server == 'all'
|
||||
env:
|
||||
LIVE_TARGETS: ${{ secrets.LIVE_TARGETS }}
|
||||
DEPLOY_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
|
||||
run: |
|
||||
if [ -z "$LIVE_TARGETS" ] || [ "$LIVE_TARGETS" = "null" ]; then
|
||||
echo "::error::LIVE_TARGETS secret is not configured."
|
||||
echo "Set it to a JSON array of target objects."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
COUNT=$(echo "$LIVE_TARGETS" | jq 'length')
|
||||
echo "Deploying to ${COUNT} live instance(s)..."
|
||||
|
||||
echo "$DEPLOY_KEY" > /tmp/deploy_key
|
||||
chmod 600 /tmp/deploy_key
|
||||
|
||||
FAILED=0
|
||||
for i in $(seq 0 $((COUNT - 1))); do
|
||||
HOST=$(echo "$LIVE_TARGETS" | jq -r ".[$i].host")
|
||||
USER=$(echo "$LIVE_TARGETS" | jq -r ".[$i].user")
|
||||
MODS=$(echo "$LIVE_TARGETS" | jq -r ".[$i].mods_dir")
|
||||
CUSTOM=$(echo "$LIVE_TARGETS" | jq -r ".[$i].custom_dir")
|
||||
PORT=$(echo "$LIVE_TARGETS" | jq -r ".[$i].port // 22")
|
||||
LABEL=$(echo "$LIVE_TARGETS" | jq -r ".[$i].label // empty")
|
||||
[ -z "$LABEL" ] && LABEL="$HOST"
|
||||
|
||||
echo ""
|
||||
echo "=== Instance $((i+1))/${COUNT}: ${LABEL} (${USER}@${HOST}:${PORT}) ==="
|
||||
|
||||
ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=15 \
|
||||
-i /tmp/deploy_key -p "$PORT" "${USER}@${HOST}" \
|
||||
"REPO='${{ env.REPO }}' LINK='${{ env.LINK_NAME }}' TAG='${{ env.TAG }}' MODS='${MODS}' CUSTOM='${CUSTOM}' GITEA_URL='${{ env.GITEA_URL }}' ORG='${{ env.ORG }}' bash" <<'REMOTE_SCRIPT' || { echo "::warning::Failed: ${LABEL}"; FAILED=$((FAILED+1)); continue; }
|
||||
mkdir -p "$MODS" && cd "$MODS"
|
||||
if [ -d "$REPO" ]; then
|
||||
cd "$REPO" && git fetch --tags origin
|
||||
else
|
||||
git clone "${GITEA_URL}/${ORG}/${REPO}.git"
|
||||
cd "$REPO"
|
||||
fi
|
||||
|
||||
if [ -n "$TAG" ]; then
|
||||
git checkout "$TAG" --quiet
|
||||
else
|
||||
git checkout main --quiet
|
||||
git pull --ff-only origin main --quiet
|
||||
fi
|
||||
|
||||
cd "$CUSTOM"
|
||||
[ -L "$LINK" ] || [ -d "$LINK" ] && rm -rf "$LINK"
|
||||
ln -sf "$MODS/$REPO/src" "$LINK"
|
||||
echo "OK: $LINK -> $MODS/$REPO/src (${TAG:-main})"
|
||||
REMOTE_SCRIPT
|
||||
done
|
||||
|
||||
rm -f /tmp/deploy_key
|
||||
|
||||
if [ "$FAILED" -gt 0 ]; then
|
||||
echo "::error::${FAILED} of ${COUNT} live deployment(s) failed"
|
||||
exit 1
|
||||
fi
|
||||
echo "All ${COUNT} live instance(s) deployed successfully."
|
||||
|
||||
- name: Summary
|
||||
if: always()
|
||||
run: |
|
||||
echo "## Deploy: ${{ env.REPO }} -> ${{ inputs.server }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "|-------|-------|" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Module | \`${{ env.REPO }}\` |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Symlink | \`${{ env.LINK_NAME }}\` |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Version | \`${{ env.TAG || 'main' }}\` |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Target | \`${{ inputs.server }}\` |" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
Reference in New Issue
Block a user