Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d76d8fb330 | ||
|
|
ab8e50823b | ||
|
|
7570a1998f | ||
|
|
7a3684a1b3 | ||
|
|
8523cb61f7 |
@@ -0,0 +1,66 @@
|
|||||||
|
name: DH V2 CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: dhv2-ci-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
api:
|
||||||
|
name: API · typecheck, tests, build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: api-v3
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '24'
|
||||||
|
cache: npm
|
||||||
|
cache-dependency-path: api-v3/package-lock.json
|
||||||
|
- run: npm ci
|
||||||
|
- run: npm run typecheck
|
||||||
|
- run: npm test
|
||||||
|
- run: npm run build
|
||||||
|
|
||||||
|
web:
|
||||||
|
name: WEB · typecheck, build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: web-v2
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '24'
|
||||||
|
cache: npm
|
||||||
|
cache-dependency-path: web-v2/package-lock.json
|
||||||
|
- run: npm ci
|
||||||
|
- run: npm run typecheck
|
||||||
|
- run: npm run build
|
||||||
|
|
||||||
|
contract:
|
||||||
|
name: Docker / scripts contract
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [api, web]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Validate shell scripts
|
||||||
|
run: |
|
||||||
|
while IFS= read -r -d '' script; do
|
||||||
|
bash -n "$script"
|
||||||
|
done < <(find scripts -type f -name '*.sh' -print0)
|
||||||
|
- name: Validate Compose
|
||||||
|
run: docker compose --env-file .env.example config >/dev/null
|
||||||
|
- name: Build production images
|
||||||
|
run: docker compose --env-file .env.example build api migrate web
|
||||||
@@ -0,0 +1,288 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -Eeuo pipefail
|
||||||
|
|
||||||
|
APP="/var/www/dhv2.korexlabs.com"
|
||||||
|
KEY="/root/.ssh/dhv2_github"
|
||||||
|
BACKUP_ROOT="/root/DH_V2_BACKUPS"
|
||||||
|
DEPLOY_REF="${DHV2_DEPLOY_REF:-deploy}"
|
||||||
|
STAMP="$(date +%Y%m%d_%H%M%S)"
|
||||||
|
BACKUP="$BACKUP_ROOT/GITHUB_DEPLOY_${STAMP}"
|
||||||
|
STAGE="/root/dhv2-github-stage-${STAMP}"
|
||||||
|
LOG="/tmp/dhv2-github-deploy-${STAMP}.log"
|
||||||
|
API_TEST_IMAGE="dhv2-api:github-${STAMP}"
|
||||||
|
WEB_TEST_IMAGE="dhv2-web:github-${STAMP}"
|
||||||
|
PHASE="bootstrap"
|
||||||
|
PREV_SHA=""
|
||||||
|
TARGET_SHA=""
|
||||||
|
EXPECTED_API_VERSION=""
|
||||||
|
EXPECTED_WEB_VERSION=""
|
||||||
|
|
||||||
|
cd "$APP"
|
||||||
|
export GIT_SSH_COMMAND="ssh -i $KEY -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new"
|
||||||
|
exec > >(tee -a "$LOG") 2>&1
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
set +e
|
||||||
|
git worktree remove --force "$STAGE" >/dev/null 2>&1 || true
|
||||||
|
rm -rf "$STAGE"
|
||||||
|
docker image rm "$API_TEST_IMAGE" "$WEB_TEST_IMAGE" >/dev/null 2>&1 || true
|
||||||
|
}
|
||||||
|
|
||||||
|
publish_status() {
|
||||||
|
local rc="${1:-1}"
|
||||||
|
set +e
|
||||||
|
|
||||||
|
local outcome="failure"
|
||||||
|
[ "$rc" -eq 0 ] && outcome="success"
|
||||||
|
local current="unknown"
|
||||||
|
current="$(git rev-parse HEAD 2>/dev/null || echo unknown)"
|
||||||
|
local status_file log_file status_blob log_blob tree commit
|
||||||
|
|
||||||
|
status_file="$(mktemp /tmp/dhv2-status.XXXXXX)"
|
||||||
|
log_file="$(mktemp /tmp/dhv2-log.XXXXXX)"
|
||||||
|
|
||||||
|
{
|
||||||
|
echo "status=$outcome"
|
||||||
|
echo "exit_code=$rc"
|
||||||
|
echo "phase=$PHASE"
|
||||||
|
echo "timestamp=$(date --iso-8601=seconds)"
|
||||||
|
echo "deploy_ref=$DEPLOY_REF"
|
||||||
|
echo "previous_sha=${PREV_SHA:-unknown}"
|
||||||
|
echo "target_sha=${TARGET_SHA:-unknown}"
|
||||||
|
echo "current_sha=$current"
|
||||||
|
echo "api_version=${EXPECTED_API_VERSION:-unknown}"
|
||||||
|
echo "web_version=${EXPECTED_WEB_VERSION:-unknown}"
|
||||||
|
echo "backup=${BACKUP:-unknown}"
|
||||||
|
} > "$status_file"
|
||||||
|
|
||||||
|
tail -n 500 "$LOG" > "$log_file" 2>/dev/null || true
|
||||||
|
status_blob="$(git hash-object -w "$status_file" 2>/dev/null || true)"
|
||||||
|
log_blob="$(git hash-object -w "$log_file" 2>/dev/null || true)"
|
||||||
|
|
||||||
|
if [ -n "$status_blob" ] && [ -n "$log_blob" ]; then
|
||||||
|
tree="$(printf '100644 blob %s\tdeploy.log\n100644 blob %s\tstatus.txt\n' "$log_blob" "$status_blob" | git mktree 2>/dev/null || true)"
|
||||||
|
if [ -n "$tree" ]; then
|
||||||
|
commit="$(printf 'deploy-status: %s · phase %s\n' "$outcome" "$PHASE" | git -c user.name='DH V2 Deploy Bot' -c user.email='deploy@dhv2.local' commit-tree "$tree" 2>/dev/null || true)"
|
||||||
|
[ -z "$commit" ] || git push --force origin "$commit:refs/heads/deploy-status" >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -f "$status_file" "$log_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
on_exit() {
|
||||||
|
local rc=$?
|
||||||
|
trap - EXIT ERR
|
||||||
|
cleanup
|
||||||
|
publish_status "$rc"
|
||||||
|
exit "$rc"
|
||||||
|
}
|
||||||
|
trap on_exit EXIT
|
||||||
|
|
||||||
|
rollback() {
|
||||||
|
local rc=$?
|
||||||
|
trap - ERR
|
||||||
|
PHASE="rollback"
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "============================================================"
|
||||||
|
echo " DH V2 · DEPLOY FALLÓ · ROLLBACK"
|
||||||
|
echo "============================================================"
|
||||||
|
|
||||||
|
cd "$APP"
|
||||||
|
if [ -n "${PREV_SHA:-}" ]; then
|
||||||
|
git reset --hard "$PREV_SHA" || true
|
||||||
|
docker compose build api web </dev/null || true
|
||||||
|
docker compose up -d --no-deps --force-recreate api web </dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Estado tras rollback:"
|
||||||
|
docker compose ps -a </dev/null || true
|
||||||
|
echo
|
||||||
|
echo "Últimos logs:"
|
||||||
|
docker compose logs --tail=160 api web </dev/null || true
|
||||||
|
echo
|
||||||
|
echo "Backup PRE disponible en: $BACKUP"
|
||||||
|
echo "Las migraciones son forward-only; database-before.dump queda disponible para restauración manual si hiciera falta."
|
||||||
|
exit "$rc"
|
||||||
|
}
|
||||||
|
trap rollback ERR
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "============================================================"
|
||||||
|
echo " DH V2 · DEPLOY DESDE GITHUB · $DEPLOY_REF"
|
||||||
|
echo "============================================================"
|
||||||
|
|
||||||
|
for cmd in git docker curl tar node; do
|
||||||
|
command -v "$cmd" >/dev/null || { echo "ERROR: falta $cmd"; false; }
|
||||||
|
done
|
||||||
|
[ -f "$KEY" ] || { echo "ERROR: falta deploy key $KEY"; false; }
|
||||||
|
[ -d .git ] || { echo "ERROR: $APP no es repositorio Git"; false; }
|
||||||
|
|
||||||
|
git config --global --add safe.directory "$APP" >/dev/null 2>&1 || true
|
||||||
|
|
||||||
|
if [ -n "$(git status --porcelain --untracked-files=no)" ]; then
|
||||||
|
echo "ERROR: hay cambios locales versionados en producción."
|
||||||
|
git status --short
|
||||||
|
false
|
||||||
|
fi
|
||||||
|
|
||||||
|
PREV_SHA="$(git rev-parse HEAD)"
|
||||||
|
PHASE="fetch"
|
||||||
|
git fetch origin "$DEPLOY_REF"
|
||||||
|
TARGET_SHA="$(git rev-parse "origin/$DEPLOY_REF")"
|
||||||
|
|
||||||
|
echo "Actual: $PREV_SHA"
|
||||||
|
echo "Objetivo: $TARGET_SHA"
|
||||||
|
|
||||||
|
if [ "$TARGET_SHA" = "$PREV_SHA" ]; then
|
||||||
|
echo "Producción ya está en el commit autorizado."
|
||||||
|
PHASE="complete"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! git merge-base --is-ancestor "$PREV_SHA" "$TARGET_SHA"; then
|
||||||
|
echo "ERROR: origin/$DEPLOY_REF no es fast-forward desde producción."
|
||||||
|
false
|
||||||
|
fi
|
||||||
|
|
||||||
|
PHASE="candidate-preflight"
|
||||||
|
mkdir -p "$STAGE"
|
||||||
|
git worktree add --detach "$STAGE" "$TARGET_SHA" >/dev/null
|
||||||
|
|
||||||
|
EXPECTED_API_VERSION="$(node -p "require('$STAGE/api-v3/package.json').version")"
|
||||||
|
EXPECTED_WEB_VERSION="$(node -p "require('$STAGE/web-v2/package.json').version")"
|
||||||
|
|
||||||
|
echo "API candidata: $EXPECTED_API_VERSION"
|
||||||
|
echo "WEB candidata: $EXPECTED_WEB_VERSION"
|
||||||
|
|
||||||
|
docker compose --env-file "$APP/.env" -f "$STAGE/docker-compose.yml" config >/dev/null
|
||||||
|
|
||||||
|
while IFS= read -r -d '' script; do
|
||||||
|
bash -n "$script"
|
||||||
|
done < <(find "$STAGE/scripts" -type f -name '*.sh' -print0)
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "========== TEST API CANDIDATA =========="
|
||||||
|
docker build --target builder -t "$API_TEST_IMAGE" "$STAGE/api-v3" </dev/null
|
||||||
|
docker run --rm \
|
||||||
|
-v "$STAGE/api-v3/test:/app/test:ro" \
|
||||||
|
-v "$STAGE/api-v3/tsconfig.test.json:/app/tsconfig.test.json:ro" \
|
||||||
|
"$API_TEST_IMAGE" npm test </dev/null
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "========== BUILD WEB CANDIDATA =========="
|
||||||
|
docker build -t "$WEB_TEST_IMAGE" "$STAGE/web-v2" </dev/null
|
||||||
|
|
||||||
|
PHASE="backup"
|
||||||
|
echo
|
||||||
|
echo "========== BACKUP PRE =========="
|
||||||
|
install -d -m 700 "$BACKUP"
|
||||||
|
docker compose exec -T db sh -lc 'pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" -Fc' </dev/null > "$BACKUP/database-before.dump"
|
||||||
|
tar \
|
||||||
|
--exclude='./.git' \
|
||||||
|
--exclude='./.env' \
|
||||||
|
--exclude='*/node_modules' \
|
||||||
|
--exclude='*/dist' \
|
||||||
|
--exclude='*.zip' \
|
||||||
|
--exclude='*.tar.gz' \
|
||||||
|
--exclude='*.tgz' \
|
||||||
|
-czf "$BACKUP/source-before.tar.gz" .
|
||||||
|
install -m 600 .env "$BACKUP/.env"
|
||||||
|
git rev-parse HEAD > "$BACKUP/previous.sha"
|
||||||
|
printf '%s\n' "$TARGET_SHA" > "$BACKUP/target.sha"
|
||||||
|
docker compose ps -a > "$BACKUP/docker-before.txt"
|
||||||
|
(
|
||||||
|
cd "$BACKUP"
|
||||||
|
sha256sum database-before.dump source-before.tar.gz .env previous.sha target.sha docker-before.txt > SHA256SUMS.txt
|
||||||
|
sha256sum -c SHA256SUMS.txt
|
||||||
|
)
|
||||||
|
chmod 600 "$BACKUP"/* "$BACKUP/.env" 2>/dev/null || true
|
||||||
|
|
||||||
|
PHASE="fast-forward"
|
||||||
|
echo
|
||||||
|
echo "========== FAST-FORWARD =========="
|
||||||
|
git log --oneline --no-decorate "$PREV_SHA..$TARGET_SHA"
|
||||||
|
git merge --ff-only "origin/$DEPLOY_REF"
|
||||||
|
|
||||||
|
PHASE="build"
|
||||||
|
echo
|
||||||
|
echo "========== BUILD PRODUCCIÓN =========="
|
||||||
|
docker compose build api migrate web </dev/null
|
||||||
|
|
||||||
|
PHASE="migrations"
|
||||||
|
echo
|
||||||
|
echo "========== MIGRACIONES =========="
|
||||||
|
docker compose --profile tools run --rm migrate </dev/null
|
||||||
|
docker compose --profile tools run --rm migrate npm run migration:show </dev/null | tee "$BACKUP/migrations.txt"
|
||||||
|
grep -Fq 'Pending migrations: no' "$BACKUP/migrations.txt"
|
||||||
|
|
||||||
|
PHASE="recreate"
|
||||||
|
echo
|
||||||
|
echo "========== RECREATE API + WEB =========="
|
||||||
|
docker compose up -d --no-deps --force-recreate api web </dev/null
|
||||||
|
|
||||||
|
PHASE="health"
|
||||||
|
echo
|
||||||
|
echo "========== HEALTH =========="
|
||||||
|
HEALTH_OK=0
|
||||||
|
for _ in $(seq 1 60); do
|
||||||
|
if curl -fsS --max-time 5 http://127.0.0.1:3101/api/v3/health > "$BACKUP/health.json" 2>/dev/null; then
|
||||||
|
if grep -F '"status":"ok"' "$BACKUP/health.json" >/dev/null; then
|
||||||
|
HEALTH_OK=1
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$HEALTH_OK" -ne 1 ]; then
|
||||||
|
echo "ERROR: API no pasó healthcheck."
|
||||||
|
docker compose logs --tail=180 api
|
||||||
|
false
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat "$BACKUP/health.json"
|
||||||
|
echo
|
||||||
|
|
||||||
|
grep -Fq "\"version\":\"$EXPECTED_API_VERSION\"" "$BACKUP/health.json"
|
||||||
|
grep -Fq '"database":"ok"' "$BACKUP/health.json"
|
||||||
|
|
||||||
|
WEB_CODE="$(curl -sS -o /dev/null -w '%{http_code}' --max-time 10 http://127.0.0.1:8182/)"
|
||||||
|
[ "$WEB_CODE" = "200" ] || { echo "ERROR: WEB HTTP $WEB_CODE"; false; }
|
||||||
|
|
||||||
|
PHASE="verify"
|
||||||
|
echo
|
||||||
|
echo "========== VERIFICACIÓN FINAL =========="
|
||||||
|
docker compose ps -a | tee "$BACKUP/docker-after.txt"
|
||||||
|
if docker compose ps --status running --services | grep -Fxq api && docker compose ps --status running --services | grep -Fxq web && docker compose ps --status running --services | grep -Fxq db; then
|
||||||
|
echo "Servicios críticos: OK"
|
||||||
|
else
|
||||||
|
echo "ERROR: falta un servicio crítico en ejecución."
|
||||||
|
false
|
||||||
|
fi
|
||||||
|
|
||||||
|
PHASE="post-backup"
|
||||||
|
docker compose exec -T db sh -lc 'pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" -Fc' </dev/null > "$BACKUP/database-after.dump"
|
||||||
|
git rev-parse HEAD > "$BACKUP/deployed.sha"
|
||||||
|
printf 'API=%s\nWEB=%s\n' "$EXPECTED_API_VERSION" "$EXPECTED_WEB_VERSION" > "$BACKUP/deployed-versions.txt"
|
||||||
|
(
|
||||||
|
cd "$BACKUP"
|
||||||
|
sha256sum database-after.dump deployed.sha deployed-versions.txt health.json migrations.txt docker-after.txt >> SHA256SUMS.txt
|
||||||
|
sha256sum -c SHA256SUMS.txt
|
||||||
|
)
|
||||||
|
chmod 600 "$BACKUP"/* "$BACKUP/.env" 2>/dev/null || true
|
||||||
|
|
||||||
|
PHASE="complete"
|
||||||
|
trap - ERR
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "============================================================"
|
||||||
|
echo " DH V2 · DEPLOY OK"
|
||||||
|
echo "============================================================"
|
||||||
|
echo "Commit: $TARGET_SHA"
|
||||||
|
echo "API: $EXPECTED_API_VERSION"
|
||||||
|
echo "WEB: $EXPECTED_WEB_VERSION"
|
||||||
|
echo "Backup: $BACKUP"
|
||||||
|
echo "============================================================"
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -Eeuo pipefail
|
||||||
|
|
||||||
|
APP="/var/www/dhv2.korexlabs.com"
|
||||||
|
KEY="/root/.ssh/dhv2_github"
|
||||||
|
WATCHER="/usr/local/sbin/dhv2-auto-deploy"
|
||||||
|
SERVICE="/etc/systemd/system/dhv2-auto-deploy.service"
|
||||||
|
TIMER="/etc/systemd/system/dhv2-auto-deploy.timer"
|
||||||
|
|
||||||
|
if [ "$(id -u)" -ne 0 ]; then
|
||||||
|
echo "ERROR: ejecutar como root."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "$APP"
|
||||||
|
[ -d .git ] || { echo "ERROR: $APP no es repositorio Git."; exit 1; }
|
||||||
|
[ -f "$KEY" ] || { echo "ERROR: falta $KEY"; exit 1; }
|
||||||
|
|
||||||
|
git config --global --add safe.directory "$APP" >/dev/null 2>&1 || true
|
||||||
|
git config core.sshCommand "ssh -i $KEY -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new"
|
||||||
|
|
||||||
|
cat > "$WATCHER" <<'WATCH'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -Eeuo pipefail
|
||||||
|
|
||||||
|
APP="/var/www/dhv2.korexlabs.com"
|
||||||
|
KEY="/root/.ssh/dhv2_github"
|
||||||
|
LOCK="/var/lock/dhv2-auto-deploy.lock"
|
||||||
|
|
||||||
|
exec 9>"$LOCK"
|
||||||
|
flock -n 9 || exit 0
|
||||||
|
|
||||||
|
cd "$APP"
|
||||||
|
export GIT_SSH_COMMAND="ssh -i $KEY -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new"
|
||||||
|
git config --global --add safe.directory "$APP" >/dev/null 2>&1 || true
|
||||||
|
|
||||||
|
if ! git fetch --quiet origin deploy; then
|
||||||
|
echo "No se pudo consultar origin/deploy; producción no se modifica."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
TARGET="$(git rev-parse origin/deploy)"
|
||||||
|
CURRENT="$(git rev-parse HEAD)"
|
||||||
|
|
||||||
|
[ "$TARGET" != "$CURRENT" ] || exit 0
|
||||||
|
|
||||||
|
if ! git merge-base --is-ancestor "$CURRENT" "$TARGET"; then
|
||||||
|
echo "ERROR: origin/deploy no es fast-forward desde $CURRENT. Deploy rechazado."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
TMP="$(mktemp /root/dhv2-deploy.XXXXXX.sh)"
|
||||||
|
trap 'rm -f "$TMP"' EXIT
|
||||||
|
|
||||||
|
git show "$TARGET:scripts/deploy-github.sh" > "$TMP"
|
||||||
|
chmod 700 "$TMP"
|
||||||
|
DHV2_DEPLOY_REF=deploy bash "$TMP"
|
||||||
|
WATCH
|
||||||
|
chmod 700 "$WATCHER"
|
||||||
|
|
||||||
|
cat > "$SERVICE" <<'UNIT'
|
||||||
|
[Unit]
|
||||||
|
Description=DH V2 autonomous GitHub deploy check
|
||||||
|
After=network-online.target docker.service
|
||||||
|
Wants=network-online.target
|
||||||
|
Requires=docker.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
User=root
|
||||||
|
WorkingDirectory=/var/www/dhv2.korexlabs.com
|
||||||
|
ExecStart=/usr/local/sbin/dhv2-auto-deploy
|
||||||
|
Nice=10
|
||||||
|
IOSchedulingClass=best-effort
|
||||||
|
IOSchedulingPriority=6
|
||||||
|
UNIT
|
||||||
|
|
||||||
|
cat > "$TIMER" <<'UNIT'
|
||||||
|
[Unit]
|
||||||
|
Description=Check DH V2 deploy branch every minute
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnBootSec=45s
|
||||||
|
OnUnitInactiveSec=60s
|
||||||
|
AccuracySec=10s
|
||||||
|
Persistent=true
|
||||||
|
Unit=dhv2-auto-deploy.service
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
|
UNIT
|
||||||
|
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable --now dhv2-auto-deploy.timer
|
||||||
|
|
||||||
|
if ! systemctl start dhv2-auto-deploy.service; then
|
||||||
|
echo
|
||||||
|
echo "ERROR: la comprobación inicial de deploy falló."
|
||||||
|
journalctl -u dhv2-auto-deploy.service -n 140 --no-pager || true
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "============================================================"
|
||||||
|
echo " DH V2 AUTO-DEPLOY INSTALADO Y VALIDADO"
|
||||||
|
echo "============================================================"
|
||||||
|
echo "Watcher: $WATCHER"
|
||||||
|
echo "Timer: dhv2-auto-deploy.timer"
|
||||||
|
echo "Logs: journalctl -u dhv2-auto-deploy.service"
|
||||||
|
echo "============================================================"
|
||||||
|
systemctl --no-pager --full status dhv2-auto-deploy.timer | sed -n '1,16p' || true
|
||||||
Reference in New Issue
Block a user