#!/usr/bin/env bash set -euo pipefail # End-to-end deploy for lecoffre-front (branch ext) # - Push code (lecoffre-front), trigger CI implicitly via commit message prefix # - docker compose pull (lecoffre_node), load env from .env.master, restart front # - Validate envs, check main URLs (front + externes), and IdNot state ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" FRONT_DIR="$ROOT_DIR/lecoffre-front" NODE_DIR="$ROOT_DIR/lecoffre_node" require() { command -v "$1" >/dev/null 2>&1 || { echo "[ERROR] Missing dependency: $1" >&2; exit 1; }; } require git require curl if [[ ! -d "$FRONT_DIR/.git" ]]; then echo "[ERROR] lecoffre-front is not a git repo (submodule?)" >&2 exit 1 fi if [[ ! -f "$NODE_DIR/.env.master" ]]; then echo "[ERROR] Missing $NODE_DIR/.env.master" >&2 exit 1 fi echo "[STEP] Push lecoffre-front on branch ext and tag ext (no interactive)" ( cd "$FRONT_DIR" \ && git fetch -p \ && (git show-ref --verify --quiet refs/heads/ext || git checkout -b ext) \ && git checkout ext \ && git add -A \ && { git diff --cached --quiet || git commit -m "ci: docker_tag=ext chore(front): deploy ext"; } \ && git push -u origin HEAD:refs/heads/ext \ && { git tag -l ext >/dev/null 2>&1 && git tag -f ext || git tag ext; } \ && { git ls-remote --tags origin refs/tags/ext >/dev/null 2>&1 \ && git push -f origin refs/tags/ext \ || git push origin refs/tags/ext; } ) echo "[STEP] Pull new image and restart front via docker compose" ( cd "$NODE_DIR" && docker compose pull lecoffre-front && docker compose up -d --no-deps lecoffre-front ) echo "[STEP] Wait for local front (http://localhost:3004/)" ATTEMPTS=60 until curl -fsS http://localhost:3004/ >/dev/null 2>&1; do ((ATTEMPTS--)) || true if [[ $ATTEMPTS -le 0 ]]; then echo "[ERROR] Front not responding" >&2; exit 1; fi sleep 2 done echo "[OK] Front responding" echo "[STEP] Validate NEXT_PUBLIC_* vs .env.master (from container env)" mapfile -t FILE_KVS < <(grep -E '^[[:space:]]*NEXT_PUBLIC_[A-Za-z0-9_]+' "$NODE_DIR/.env.master" | sed 's/^[[:space:]]*//' | sort) MISMATCH=0 for kv in "${FILE_KVS[@]}"; do key="${kv%%=*}"; expect="${kv#*=}"; expect="$(printf '%s' "$expect" | tr -d '\r' | sed 's/^\"//; s/\"$//')" actual="$(cd "$NODE_DIR" && docker compose exec -T lecoffre-front /bin/sh -lc "env | grep -E '^${key}=' | head -n1 | sed 's/^${key}=//'" || true)" if [[ "$actual" != "$expect" ]]; then echo "[MISMATCH] $key: running='$actual' vs .env.master='$expect'"; MISMATCH=1; fi done [[ $MISMATCH -eq 0 ]] && echo "[OK] Env match" || { echo "[FAIL] Env mismatch" >&2; exit 1; } echo "[STEP] Curl checks - public front" curl -siS 'https://dev4.4nkweb.com/lecoffre?nocache='$(date +%s) | sed -n '1,20p' curl -siS 'https://dev4.4nkweb.com/lecoffre/?nocache='$(date +%s) | sed -n '1,20p' echo "[STEP] Curl checks - core app endpoints" curl -sS --connect-timeout 3 --max-time 8 'https://dev4.4nkweb.com/lecoffre/_next/static/chunks/webpack.js' | head -c 120 | sed 's/.*/[webpack-chunk] .../' || true curl -sS --connect-timeout 3 --max-time 8 'https://dev4.4nkweb.com/lecoffre/' | head -c 120 | sed 's/.*/[home] .../' || true echo "[STEP] Curl checks - external flows (proxied)" curl -siS -X OPTIONS 'https://dev3.4nkweb.com/api/v1/idnot/state' \ -H 'Origin: https://dev4.4nkweb.com' \ -H 'Access-Control-Request-Method: POST' \ -H 'Access-Control-Request-Headers: content-type' | sed -n '1,20p' STATE_RESP="$(curl -siS -X POST 'https://dev3.4nkweb.com/api/v1/idnot/state' \ -H 'Origin: https://dev4.4nkweb.com' \ -H 'Content-Type: application/json' \ --data '{"next_url":"https://dev4.4nkweb.com/lecoffre/authorized-client"}')" echo "$STATE_RESP" | sed -n '1,30p' STATE_JSON="$(echo "$STATE_RESP" | awk 'BEGIN{p=0} /^\r?$/{p=1;next} p{print}')" STATE_VAL="$(echo "$STATE_JSON" | sed -n 's/.*"state"[[:space:]]*:[[:space:]]*"\([^"]\+\)".*/\1/p' | head -n1)" if [[ -z "$STATE_VAL" ]]; then echo "[WARN] No state in response"; fi echo "[DONE] Deploy + validations completed"