Template
feat(ci): own MokoGitea deploy workflows (dev/rc/prod) as canonical synced source #5
@@ -0,0 +1,145 @@
|
||||
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
#
|
||||
# FILE INFORMATION
|
||||
# DEFGROUP: MokoGitea.Workflow
|
||||
# INGROUP: MokoStandards.Deploy
|
||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Go
|
||||
# PATH: /.mokogitea/workflows/deploy-dev.yml
|
||||
# VERSION: 01.00.00
|
||||
# BRIEF: Build and deploy to the dev environment on push to the dev branch.
|
||||
# Portable across Go server repos: ALL deployment config comes from repo
|
||||
# Actions variables (vars.*) and secrets (secrets.*), nothing hardcoded.
|
||||
# Canonical source — syncs to root .mokogitea/workflows/ of Go server
|
||||
# repos (Template-Go#3).
|
||||
#
|
||||
# Required repo VARIABLES (all tier-scoped so each environment is independent —
|
||||
# a repo may host its rc/dev/prod tiers on different machines):
|
||||
# DEV_SSH_HOST, DEV_SSH_PORT, DEV_SSH_USERNAME - SSH deploy target for the dev tier
|
||||
# DEV_REGISTRY, DEV_REGISTRY_USER, DEV_IMAGE - container registry + login user + image
|
||||
# DEV_CONTAINER - compose service/container to recreate
|
||||
# DEV_COMPOSE_PROJECT - docker compose -p project name
|
||||
# DEV_COMPOSE_DIR - dir containing docker-compose.yml on host
|
||||
# DEV_SOURCE_DIR - build source checkout on host
|
||||
# DEV_TAG_ENV - compose env-var name that pins the image tag
|
||||
# DEV_HEALTH_URL - external URL to verify after deploy
|
||||
# Required SECRETS (already configured org-wide; reused, not re-set):
|
||||
# DEPLOY_SSH_KEY - deploy private key (repo/org secret)
|
||||
# MOKOGITEA_TOKEN - registry/API token (org secret)
|
||||
|
||||
name: Deploy (Dev)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
# Manual trigger for isolated end-to-end tests without a full dev push.
|
||||
# Runs on the ref it is dispatched from; that ref must carry current source
|
||||
# (>= the dev database migration version) or the rebuilt image will refuse the
|
||||
# newer DB. Dispatch from `dev` once `dev` is current.
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: deploy-dev
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
||||
|
||||
jobs:
|
||||
deploy-dev:
|
||||
name: "Build & Deploy to Dev"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout source
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Determine version
|
||||
id: config
|
||||
run: |
|
||||
VERSION=$(git describe --tags --always 2>/dev/null || echo "dev-$(git rev-parse --short HEAD)")
|
||||
echo "tag=${VERSION}-dev" >> $GITHUB_OUTPUT
|
||||
echo "Version: ${VERSION}-dev"
|
||||
|
||||
- name: Write deploy key
|
||||
env:
|
||||
DEPLOY_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
|
||||
run: |
|
||||
mkdir -p ~/.ssh
|
||||
echo "$DEPLOY_KEY" > ~/.ssh/deploy_key
|
||||
chmod 600 ~/.ssh/deploy_key
|
||||
|
||||
- name: Build and deploy to dev via SSH
|
||||
env:
|
||||
REGISTRY_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
|
||||
TAG: ${{ steps.config.outputs.tag }}
|
||||
run: |
|
||||
# Runner-side values (TAG, REGISTRY_TOKEN) are injected into the remote shell
|
||||
# via an env prefix; a *quoted* heredoc keeps every $var expanding once, on the
|
||||
# remote. Repo variables (vars.*) are substituted inline by Actions before ssh.
|
||||
ssh -i ~/.ssh/deploy_key -p ${{ vars.DEV_SSH_PORT }} \
|
||||
-o ConnectTimeout=30 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
|
||||
-o ServerAliveInterval=30 -o ServerAliveCountMax=10 \
|
||||
${{ vars.DEV_SSH_USERNAME }}@${{ vars.DEV_SSH_HOST }} \
|
||||
"TAG='$TAG' REGISTRY_TOKEN='$REGISTRY_TOKEN' bash -s" <<'DEPLOY_EOF'
|
||||
set -e
|
||||
echo 'SSH connected to dev environment'
|
||||
|
||||
if [ -z "$TAG" ]; then
|
||||
echo 'ERROR: TAG is empty; refusing to build an untagged image' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
HEALTH_FMT='{{.State.Health.Status}}'
|
||||
|
||||
echo 'Cleaning Docker build cache...'
|
||||
docker builder prune -af 2>/dev/null || true
|
||||
docker image prune -af 2>/dev/null || true
|
||||
|
||||
echo 'Pulling source...'
|
||||
SOURCE_DIR='${{ vars.DEV_SOURCE_DIR }}'
|
||||
if [ ! -d "$SOURCE_DIR/.git" ]; then
|
||||
git clone -b dev ${{ github.server_url }}/${{ github.repository }}.git "$SOURCE_DIR"
|
||||
fi
|
||||
cd "$SOURCE_DIR"
|
||||
git remote set-url origin ${{ github.server_url }}/${{ github.repository }}.git 2>/dev/null || true
|
||||
git fetch origin dev
|
||||
git reset --hard origin/dev
|
||||
|
||||
echo "Building image: ${{ vars.DEV_REGISTRY }}/${{ vars.DEV_IMAGE }}:$TAG"
|
||||
docker build --no-cache --build-arg GOFLAGS='-p 1' \
|
||||
--tag "${{ vars.DEV_REGISTRY }}/${{ vars.DEV_IMAGE }}:$TAG" \
|
||||
-f Dockerfile .
|
||||
|
||||
echo 'Pushing to registry...'
|
||||
echo "$REGISTRY_TOKEN" | docker login ${{ vars.DEV_REGISTRY }} -u ${{ vars.DEV_REGISTRY_USER }} --password-stdin
|
||||
docker push "${{ vars.DEV_REGISTRY }}/${{ vars.DEV_IMAGE }}:$TAG"
|
||||
|
||||
echo 'Restarting dev container...'
|
||||
cd '${{ vars.DEV_COMPOSE_DIR }}'
|
||||
# Drive the dev service image tag via its compose env-var (no sed on the shared
|
||||
# file); remove any lingering fixed-name container first, then force-recreate.
|
||||
docker rm -f '${{ vars.DEV_CONTAINER }}' 2>/dev/null || true
|
||||
${{ vars.DEV_TAG_ENV }}="$TAG" docker compose -p '${{ vars.DEV_COMPOSE_PROJECT }}' up -d --force-recreate '${{ vars.DEV_CONTAINER }}'
|
||||
|
||||
echo 'Health check...'
|
||||
for i in 1 2 3 4 5 6 7 8; do
|
||||
sleep 15
|
||||
if docker inspect --format="$HEALTH_FMT" '${{ vars.DEV_CONTAINER }}' 2>/dev/null | grep -q healthy; then
|
||||
echo 'Dev container healthy!'
|
||||
exit 0
|
||||
fi
|
||||
echo "Waiting... (attempt $i/8)"
|
||||
done
|
||||
echo 'Health check failed'
|
||||
docker logs '${{ vars.DEV_CONTAINER }}' --tail 20
|
||||
exit 1
|
||||
DEPLOY_EOF
|
||||
|
||||
- name: Verify dev instance
|
||||
run: |
|
||||
sleep 5
|
||||
curl -sf "${{ vars.DEV_HEALTH_URL }}" && echo " Dev API healthy"
|
||||
@@ -0,0 +1,153 @@
|
||||
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
#
|
||||
# FILE INFORMATION
|
||||
# DEFGROUP: MokoGitea.Workflow
|
||||
# INGROUP: MokoStandards.Deploy
|
||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Go
|
||||
# PATH: /.mokogitea/workflows/deploy-prod.yml
|
||||
# VERSION: 01.00.00
|
||||
# BRIEF: Build and deploy to the production environment on push to the main branch.
|
||||
# Portable across Go server repos: ALL deployment config comes from repo
|
||||
# Actions variables (vars.*) and secrets (secrets.*), nothing hardcoded.
|
||||
# Also publishes the :latest tag (prod-only) alongside the versioned tag.
|
||||
# Canonical source — syncs to root .mokogitea/workflows/ of Go server
|
||||
# repos (Template-Go#3).
|
||||
#
|
||||
# Required repo VARIABLES (all tier-scoped so each environment is independent —
|
||||
# a repo may host its rc/dev/prod tiers on different machines):
|
||||
# PROD_SSH_HOST, PROD_SSH_PORT, PROD_SSH_USERNAME - SSH deploy target for the prod tier
|
||||
# PROD_REGISTRY, PROD_REGISTRY_USER, PROD_IMAGE - container registry + login user + image
|
||||
# PROD_CONTAINER - compose service/container to recreate
|
||||
# PROD_COMPOSE_PROJECT - docker compose -p project name
|
||||
# PROD_COMPOSE_DIR - dir containing docker-compose.yml on host
|
||||
# PROD_SOURCE_DIR - build source checkout on host
|
||||
# PROD_TAG_ENV - compose env-var name that pins the image tag
|
||||
# PROD_HEALTH_URL - external URL to verify after deploy
|
||||
# Required SECRETS (already configured org-wide; reused, not re-set):
|
||||
# DEPLOY_SSH_KEY - deploy private key (repo/org secret)
|
||||
# MOKOGITEA_TOKEN - registry/API token (org secret)
|
||||
|
||||
name: Deploy (Prod)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
# Manual trigger for isolated redeploys of the current main HEAD.
|
||||
# Runs on the ref it is dispatched from; that ref must carry current source
|
||||
# (>= the prod database migration version) or the rebuilt image will refuse the
|
||||
# newer DB. Dispatch from `main` once `main` is current.
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: deploy-prod
|
||||
cancel-in-progress: false
|
||||
|
||||
env:
|
||||
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
||||
|
||||
jobs:
|
||||
deploy-prod:
|
||||
name: "Build & Deploy to Prod"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout source
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Determine version
|
||||
id: config
|
||||
run: |
|
||||
VERSION=$(git describe --tags --always 2>/dev/null || echo "prod-$(git rev-parse --short HEAD)")
|
||||
echo "tag=${VERSION}" >> $GITHUB_OUTPUT
|
||||
echo "Version: ${VERSION}"
|
||||
|
||||
- name: Write deploy key
|
||||
env:
|
||||
DEPLOY_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
|
||||
run: |
|
||||
mkdir -p ~/.ssh
|
||||
echo "$DEPLOY_KEY" > ~/.ssh/deploy_key
|
||||
chmod 600 ~/.ssh/deploy_key
|
||||
|
||||
- name: Build and deploy to prod via SSH
|
||||
env:
|
||||
REGISTRY_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
|
||||
TAG: ${{ steps.config.outputs.tag }}
|
||||
run: |
|
||||
# Runner-side values (TAG, REGISTRY_TOKEN) are injected into the remote shell
|
||||
# via an env prefix; a *quoted* heredoc keeps every $var expanding once, on the
|
||||
# remote. Repo variables (vars.*) are substituted inline by Actions before ssh.
|
||||
ssh -i ~/.ssh/deploy_key -p ${{ vars.PROD_SSH_PORT }} \
|
||||
-o ConnectTimeout=30 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
|
||||
-o ServerAliveInterval=30 -o ServerAliveCountMax=10 \
|
||||
${{ vars.PROD_SSH_USERNAME }}@${{ vars.PROD_SSH_HOST }} \
|
||||
"TAG='$TAG' REGISTRY_TOKEN='$REGISTRY_TOKEN' bash -s" <<'DEPLOY_EOF'
|
||||
set -e
|
||||
echo 'SSH connected to prod environment'
|
||||
|
||||
if [ -z "$TAG" ]; then
|
||||
echo 'ERROR: TAG is empty; refusing to build an untagged image' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
HEALTH_FMT='{{.State.Health.Status}}'
|
||||
|
||||
echo 'Cleaning Docker build cache...'
|
||||
docker builder prune -af 2>/dev/null || true
|
||||
docker image prune -af 2>/dev/null || true
|
||||
|
||||
echo 'Pulling source...'
|
||||
SOURCE_DIR='${{ vars.PROD_SOURCE_DIR }}'
|
||||
if [ ! -d "$SOURCE_DIR/.git" ]; then
|
||||
git clone -b main ${{ github.server_url }}/${{ github.repository }}.git "$SOURCE_DIR"
|
||||
fi
|
||||
cd "$SOURCE_DIR"
|
||||
git remote set-url origin ${{ github.server_url }}/${{ github.repository }}.git 2>/dev/null || true
|
||||
git fetch origin main
|
||||
git reset --hard origin/main
|
||||
|
||||
echo "Building image: ${{ vars.PROD_REGISTRY }}/${{ vars.PROD_IMAGE }}:$TAG (+ :latest)"
|
||||
# Prod publishes both the versioned tag and a moving :latest tag.
|
||||
docker build --no-cache --build-arg GOFLAGS='-p 1' \
|
||||
--tag "${{ vars.PROD_REGISTRY }}/${{ vars.PROD_IMAGE }}:$TAG" \
|
||||
--tag "${{ vars.PROD_REGISTRY }}/${{ vars.PROD_IMAGE }}:latest" \
|
||||
-f Dockerfile .
|
||||
|
||||
echo 'Pushing to registry...'
|
||||
echo "$REGISTRY_TOKEN" | docker login ${{ vars.PROD_REGISTRY }} -u ${{ vars.PROD_REGISTRY_USER }} --password-stdin
|
||||
docker push "${{ vars.PROD_REGISTRY }}/${{ vars.PROD_IMAGE }}:$TAG"
|
||||
docker push "${{ vars.PROD_REGISTRY }}/${{ vars.PROD_IMAGE }}:latest"
|
||||
|
||||
echo 'Restarting prod container...'
|
||||
cd '${{ vars.PROD_COMPOSE_DIR }}'
|
||||
# Drive the prod service image tag via its compose env-var (no sed on the shared
|
||||
# file); remove any lingering fixed-name container first, then force-recreate.
|
||||
docker rm -f '${{ vars.PROD_CONTAINER }}' 2>/dev/null || true
|
||||
${{ vars.PROD_TAG_ENV }}="$TAG" docker compose -p '${{ vars.PROD_COMPOSE_PROJECT }}' up -d --force-recreate '${{ vars.PROD_CONTAINER }}'
|
||||
|
||||
echo 'Health check...'
|
||||
for i in 1 2 3 4 5 6 7 8; do
|
||||
sleep 15
|
||||
if docker inspect --format="$HEALTH_FMT" '${{ vars.PROD_CONTAINER }}' 2>/dev/null | grep -q healthy; then
|
||||
echo 'Prod container healthy!'
|
||||
exit 0
|
||||
fi
|
||||
echo "Waiting... (attempt $i/8)"
|
||||
done
|
||||
echo 'Health check failed'
|
||||
docker logs '${{ vars.PROD_CONTAINER }}' --tail 20
|
||||
exit 1
|
||||
DEPLOY_EOF
|
||||
|
||||
- name: Verify prod instance
|
||||
run: |
|
||||
sleep 5
|
||||
curl -sf "${{ vars.PROD_HEALTH_URL }}" && echo " Prod API healthy"
|
||||
|
||||
- name: Notify on failure
|
||||
if: failure()
|
||||
run: echo "::error::Prod deploy failed for ${{ steps.config.outputs.tag }}"
|
||||
@@ -0,0 +1,146 @@
|
||||
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
#
|
||||
# FILE INFORMATION
|
||||
# DEFGROUP: MokoGitea.Workflow
|
||||
# INGROUP: MokoStandards.Deploy
|
||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Go
|
||||
# PATH: /.mokogitea/workflows/deploy-rc.yml
|
||||
# VERSION: 01.00.00
|
||||
# BRIEF: Build and deploy to the RC environment on push to the rc branch.
|
||||
# Portable across Go server repos: ALL deployment config comes from repo
|
||||
# Actions variables (vars.*) and secrets (secrets.*), nothing hardcoded.
|
||||
# The rc branch is created by promote-rc when a PR to main opens.
|
||||
# Canonical source — syncs to root .mokogitea/workflows/ of Go server
|
||||
# repos (Template-Go#3).
|
||||
#
|
||||
# Required repo VARIABLES (all tier-scoped so each environment is independent —
|
||||
# a repo may host its rc/dev/prod tiers on different machines):
|
||||
# RC_SSH_HOST, RC_SSH_PORT, RC_SSH_USERNAME - SSH deploy target for the rc tier
|
||||
# RC_REGISTRY, RC_REGISTRY_USER, RC_IMAGE - container registry + login user + image
|
||||
# RC_CONTAINER - compose service/container to recreate
|
||||
# RC_COMPOSE_PROJECT - docker compose -p project name
|
||||
# RC_COMPOSE_DIR - dir containing docker-compose.yml on host
|
||||
# RC_SOURCE_DIR - build source checkout on host
|
||||
# RC_TAG_ENV - compose env-var name that pins the image tag
|
||||
# RC_HEALTH_URL - external URL to verify after deploy
|
||||
# Required SECRETS (already configured org-wide; reused, not re-set):
|
||||
# DEPLOY_SSH_KEY - deploy private key (repo/org secret)
|
||||
# MOKOGITEA_TOKEN - registry/API token (org secret)
|
||||
|
||||
name: Deploy (RC)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- rc
|
||||
# Manual trigger for isolated end-to-end tests without a full RC promotion.
|
||||
# Runs on the ref it is dispatched from; that ref must carry current source
|
||||
# (>= the RC database migration version) or the rebuilt image will refuse the
|
||||
# newer DB. Dispatch from `rc` once `rc` is current.
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: deploy-rc
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
||||
|
||||
jobs:
|
||||
deploy-rc:
|
||||
name: "Build & Deploy to RC"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout source
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Determine version
|
||||
id: config
|
||||
run: |
|
||||
VERSION=$(git describe --tags --always 2>/dev/null || echo "rc-$(git rev-parse --short HEAD)")
|
||||
echo "tag=${VERSION}-rc" >> $GITHUB_OUTPUT
|
||||
echo "Version: ${VERSION}-rc"
|
||||
|
||||
- name: Write deploy key
|
||||
env:
|
||||
DEPLOY_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
|
||||
run: |
|
||||
mkdir -p ~/.ssh
|
||||
echo "$DEPLOY_KEY" > ~/.ssh/deploy_key
|
||||
chmod 600 ~/.ssh/deploy_key
|
||||
|
||||
- name: Build and deploy to RC via SSH
|
||||
env:
|
||||
REGISTRY_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
|
||||
TAG: ${{ steps.config.outputs.tag }}
|
||||
run: |
|
||||
# Runner-side values (TAG, REGISTRY_TOKEN) are injected into the remote shell
|
||||
# via an env prefix; a *quoted* heredoc keeps every $var expanding once, on the
|
||||
# remote. Repo variables (vars.*) are substituted inline by Actions before ssh.
|
||||
ssh -i ~/.ssh/deploy_key -p ${{ vars.RC_SSH_PORT }} \
|
||||
-o ConnectTimeout=30 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
|
||||
-o ServerAliveInterval=30 -o ServerAliveCountMax=10 \
|
||||
${{ vars.RC_SSH_USERNAME }}@${{ vars.RC_SSH_HOST }} \
|
||||
"TAG='$TAG' REGISTRY_TOKEN='$REGISTRY_TOKEN' bash -s" <<'DEPLOY_EOF'
|
||||
set -e
|
||||
echo 'SSH connected to RC environment'
|
||||
|
||||
if [ -z "$TAG" ]; then
|
||||
echo 'ERROR: TAG is empty; refusing to build an untagged image' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
HEALTH_FMT='{{.State.Health.Status}}'
|
||||
|
||||
echo 'Cleaning Docker build cache...'
|
||||
docker builder prune -af 2>/dev/null || true
|
||||
docker image prune -af 2>/dev/null || true
|
||||
|
||||
echo 'Pulling source...'
|
||||
SOURCE_DIR='${{ vars.RC_SOURCE_DIR }}'
|
||||
if [ ! -d "$SOURCE_DIR/.git" ]; then
|
||||
git clone -b rc ${{ github.server_url }}/${{ github.repository }}.git "$SOURCE_DIR"
|
||||
fi
|
||||
cd "$SOURCE_DIR"
|
||||
git remote set-url origin ${{ github.server_url }}/${{ github.repository }}.git 2>/dev/null || true
|
||||
git fetch origin rc
|
||||
git reset --hard origin/rc
|
||||
|
||||
echo "Building image: ${{ vars.RC_REGISTRY }}/${{ vars.RC_IMAGE }}:$TAG"
|
||||
docker build --no-cache --build-arg GOFLAGS='-p 1' \
|
||||
--tag "${{ vars.RC_REGISTRY }}/${{ vars.RC_IMAGE }}:$TAG" \
|
||||
-f Dockerfile .
|
||||
|
||||
echo 'Pushing to registry...'
|
||||
echo "$REGISTRY_TOKEN" | docker login ${{ vars.RC_REGISTRY }} -u ${{ vars.RC_REGISTRY_USER }} --password-stdin
|
||||
docker push "${{ vars.RC_REGISTRY }}/${{ vars.RC_IMAGE }}:$TAG"
|
||||
|
||||
echo 'Restarting RC container...'
|
||||
cd '${{ vars.RC_COMPOSE_DIR }}'
|
||||
# Drive the rc service image tag via its compose env-var (no sed on the shared
|
||||
# file); remove any lingering fixed-name container first, then force-recreate.
|
||||
docker rm -f '${{ vars.RC_CONTAINER }}' 2>/dev/null || true
|
||||
${{ vars.RC_TAG_ENV }}="$TAG" docker compose -p '${{ vars.RC_COMPOSE_PROJECT }}' up -d --force-recreate '${{ vars.RC_CONTAINER }}'
|
||||
|
||||
echo 'Health check...'
|
||||
for i in 1 2 3 4 5 6 7 8; do
|
||||
sleep 15
|
||||
if docker inspect --format="$HEALTH_FMT" '${{ vars.RC_CONTAINER }}' 2>/dev/null | grep -q healthy; then
|
||||
echo 'RC container healthy!'
|
||||
exit 0
|
||||
fi
|
||||
echo "Waiting... (attempt $i/8)"
|
||||
done
|
||||
echo 'Health check failed'
|
||||
docker logs '${{ vars.RC_CONTAINER }}' --tail 20
|
||||
exit 1
|
||||
DEPLOY_EOF
|
||||
|
||||
- name: Verify RC instance
|
||||
run: |
|
||||
sleep 5
|
||||
curl -sf "${{ vars.RC_HEALTH_URL }}" && echo " RC API healthy"
|
||||
Reference in New Issue
Block a user