198 lines
8.2 KiB
YAML
198 lines
8.2 KiB
YAML
name: Deploy feedback demo
|
|
|
|
run-name: Deploy feedback demo from main
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- main
|
|
workflow_dispatch:
|
|
|
|
jobs:
|
|
deploy:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 30
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Validate deployment settings
|
|
env:
|
|
STAGING_HOST: ${{ vars.STAGING_HOST }}
|
|
STAGING_PORT: ${{ vars.STAGING_PORT }}
|
|
STAGING_APP_DIR: ${{ vars.STAGING_APP_DIR }}
|
|
WEB_PORT: ${{ vars.WEB_PORT }}
|
|
SSO_CLIENT_ID_VAR: ${{ vars.SSO_CLIENT_ID }}
|
|
SSO_CLIENT_ID_SECRET: ${{ secrets.SSO_CLIENT_ID }}
|
|
STAGING_USER: ${{ secrets.STAGING_USER }}
|
|
STAGING_SSH_PRIVATE_KEY: ${{ secrets.STAGING_SSH_PRIVATE_KEY }}
|
|
STAGING_SSH_KNOWN_HOSTS: ${{ secrets.STAGING_SSH_KNOWN_HOSTS }}
|
|
SSO_CLIENT_SECRET: ${{ secrets.SSO_CLIENT_SECRET }}
|
|
JWT_SECRET: ${{ secrets.JWT_SECRET }}
|
|
run: |
|
|
set -eu
|
|
|
|
test "${STAGING_HOST:-10.13.10.4}" = "10.13.10.4" || {
|
|
echo "STAGING_HOST must be 10.13.10.4" >&2
|
|
exit 1
|
|
}
|
|
test "${WEB_PORT:-8864}" = "8864" || {
|
|
echo "WEB_PORT must be 8864" >&2
|
|
exit 1
|
|
}
|
|
|
|
SSO_CLIENT_ID="${SSO_CLIENT_ID_SECRET:-${SSO_CLIENT_ID_VAR:-}}"
|
|
export SSO_CLIENT_ID
|
|
for name in STAGING_USER STAGING_SSH_PRIVATE_KEY STAGING_SSH_KNOWN_HOSTS SSO_CLIENT_ID SSO_CLIENT_SECRET JWT_SECRET; do
|
|
if [ -z "${!name:-}" ]; then
|
|
echo "Missing Gitea secret: $name" >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
echo "Feedback demo deployment settings are present."
|
|
|
|
- name: Deploy to 10.13.10.4:8864 over SSH
|
|
env:
|
|
STAGING_HOST: ${{ vars.STAGING_HOST }}
|
|
STAGING_PORT: ${{ vars.STAGING_PORT }}
|
|
STAGING_APP_DIR: ${{ vars.STAGING_APP_DIR }}
|
|
WEB_PORT: ${{ vars.WEB_PORT }}
|
|
SUPPORT_CONSOLE_API_BASE_URL: ${{ vars.SUPPORT_CONSOLE_API_BASE_URL }}
|
|
SSO_ISSUER: ${{ vars.SSO_ISSUER }}
|
|
SSO_AUTHORIZATION_ENDPOINT: ${{ vars.SSO_AUTHORIZATION_ENDPOINT }}
|
|
SSO_TOKEN_ENDPOINT: ${{ vars.SSO_TOKEN_ENDPOINT }}
|
|
SSO_USERINFO_ENDPOINT: ${{ vars.SSO_USERINFO_ENDPOINT }}
|
|
SSO_SCOPE: ${{ vars.SSO_SCOPE }}
|
|
SSO_CLIENT_ID_VAR: ${{ vars.SSO_CLIENT_ID }}
|
|
SSO_CLIENT_ID_SECRET: ${{ secrets.SSO_CLIENT_ID }}
|
|
SUPPORT_TENANT_ID: ${{ vars.SUPPORT_TENANT_ID }}
|
|
STAGING_USER: ${{ secrets.STAGING_USER }}
|
|
STAGING_SSH_PRIVATE_KEY: ${{ secrets.STAGING_SSH_PRIVATE_KEY }}
|
|
STAGING_SSH_KNOWN_HOSTS: ${{ secrets.STAGING_SSH_KNOWN_HOSTS }}
|
|
SSO_CLIENT_SECRET: ${{ secrets.SSO_CLIENT_SECRET }}
|
|
JWT_SECRET: ${{ secrets.JWT_SECRET }}
|
|
run: |
|
|
set -eu
|
|
set -o pipefail
|
|
umask 077
|
|
|
|
staging_host="${STAGING_HOST:-10.13.10.4}"
|
|
staging_port="${STAGING_PORT:-22}"
|
|
staging_app_dir="${STAGING_APP_DIR:-/home/user/egbim_qa_platform}"
|
|
web_port="${WEB_PORT:-8864}"
|
|
support_console_api_base_url="${SUPPORT_CONSOLE_API_BASE_URL:-https://feedback.hmac.kr/api/support}"
|
|
sso_issuer="${SSO_ISSUER:-https://sso.hmac.kr/oidc}"
|
|
sso_authorization_endpoint="${SSO_AUTHORIZATION_ENDPOINT:-https://sso.hmac.kr/oidc/oauth2/auth}"
|
|
sso_token_endpoint="${SSO_TOKEN_ENDPOINT:-https://sso.hmac.kr/oidc/oauth2/token}"
|
|
sso_userinfo_endpoint="${SSO_USERINFO_ENDPOINT:-https://sso.hmac.kr/oidc/userinfo}"
|
|
sso_scope="${SSO_SCOPE:-openid profile email tenants}"
|
|
sso_client_id="${SSO_CLIENT_ID_SECRET:-${SSO_CLIENT_ID_VAR:-}}"
|
|
sso_client_secret="$SSO_CLIENT_SECRET"
|
|
jwt_secret="$JWT_SECRET"
|
|
support_tenant_id="${SUPPORT_TENANT_ID:-}"
|
|
|
|
test "$staging_host" = "10.13.10.4"
|
|
test "$web_port" = "8864"
|
|
|
|
ssh_dir="$RUNNER_TEMP/staging-ssh"
|
|
mkdir -p "$ssh_dir"
|
|
chmod 700 "$ssh_dir"
|
|
key_file="$ssh_dir/id_ed25519"
|
|
known_hosts_file="$ssh_dir/known_hosts"
|
|
printf '%s\n' "$STAGING_SSH_PRIVATE_KEY" > "$key_file"
|
|
printf '%s\n' "$STAGING_SSH_KNOWN_HOSTS" > "$known_hosts_file"
|
|
chmod 600 "$key_file" "$known_hosts_file"
|
|
trap 'rm -rf "$ssh_dir"' EXIT
|
|
|
|
ssh-keygen -y -f "$key_file" > "$ssh_dir/id_ed25519.pub"
|
|
ssh_args=(
|
|
-i "$key_file"
|
|
-p "$staging_port"
|
|
-o BatchMode=yes
|
|
-o IdentitiesOnly=yes
|
|
-o StrictHostKeyChecking=yes
|
|
-o UserKnownHostsFile="$known_hosts_file"
|
|
)
|
|
remote="$STAGING_USER@$staging_host"
|
|
|
|
shell_quote() {
|
|
printf "'%s'" "$(printf '%s' "$1" | sed "s/'/'\\\\''/g")"
|
|
}
|
|
|
|
remote_app_dir="$(shell_quote "$staging_app_dir")"
|
|
ssh "${ssh_args[@]}" "$remote" "mkdir -p $remote_app_dir"
|
|
tar \
|
|
--exclude='.git' \
|
|
--exclude='node_modules' \
|
|
--exclude='.next' \
|
|
--exclude='dist' \
|
|
--exclude='uploads' \
|
|
--exclude='.venv' \
|
|
--exclude='.venv-*' \
|
|
--exclude='.cache' \
|
|
--exclude='.turbo' \
|
|
--exclude='apps/docs/static' \
|
|
-czf - . | ssh "${ssh_args[@]}" "$remote" "tar -xzf - -C $remote_app_dir"
|
|
|
|
base64_value() {
|
|
printf '%s' "$1" | base64 -w 0
|
|
}
|
|
|
|
app_dir_b64="$(base64_value "$staging_app_dir")"
|
|
web_port_b64="$(base64_value "$web_port")"
|
|
console_url_b64="$(base64_value "$support_console_api_base_url")"
|
|
sso_issuer_b64="$(base64_value "$sso_issuer")"
|
|
sso_authorization_endpoint_b64="$(base64_value "$sso_authorization_endpoint")"
|
|
sso_token_endpoint_b64="$(base64_value "$sso_token_endpoint")"
|
|
sso_userinfo_endpoint_b64="$(base64_value "$sso_userinfo_endpoint")"
|
|
sso_scope_b64="$(base64_value "$sso_scope")"
|
|
sso_client_id_b64="$(base64_value "$sso_client_id")"
|
|
sso_client_secret_b64="$(base64_value "$sso_client_secret")"
|
|
jwt_secret_b64="$(base64_value "$jwt_secret")"
|
|
support_tenant_id_b64="$(base64_value "$support_tenant_id")"
|
|
|
|
# Run an explicit Bash script on the server. The server user's login
|
|
# shell may be zsh; sending one large command string through it makes
|
|
# nested quotes and loop syntax unreliable.
|
|
ssh "${ssh_args[@]}" "$remote" bash -s <<REMOTE_SCRIPT
|
|
set -eu
|
|
|
|
decode_value() {
|
|
printf '%s' "\$1" | base64 -d
|
|
}
|
|
|
|
staging_app_dir="\$(printf '%s' '$app_dir_b64' | base64 -d)"
|
|
web_port="\$(printf '%s' '$web_port_b64' | base64 -d)"
|
|
export WEB_PORT="\$web_port"
|
|
export SUPPORT_CONSOLE_API_BASE_URL="\$(printf '%s' '$console_url_b64' | base64 -d)"
|
|
export SSO_ISSUER="\$(printf '%s' '$sso_issuer_b64' | base64 -d)"
|
|
export SSO_AUTHORIZATION_ENDPOINT="\$(printf '%s' '$sso_authorization_endpoint_b64' | base64 -d)"
|
|
export SSO_TOKEN_ENDPOINT="\$(printf '%s' '$sso_token_endpoint_b64' | base64 -d)"
|
|
export SSO_USERINFO_ENDPOINT="\$(printf '%s' '$sso_userinfo_endpoint_b64' | base64 -d)"
|
|
export SSO_SCOPE="\$(printf '%s' '$sso_scope_b64' | base64 -d)"
|
|
export SSO_CLIENT_ID="\$(printf '%s' '$sso_client_id_b64' | base64 -d)"
|
|
export SSO_CLIENT_SECRET="\$(printf '%s' '$sso_client_secret_b64' | base64 -d)"
|
|
export JWT_SECRET="\$(printf '%s' '$jwt_secret_b64' | base64 -d)"
|
|
export SUPPORT_TENANT_ID="\$(printf '%s' '$support_tenant_id_b64' | base64 -d)"
|
|
|
|
cd "\$staging_app_dir"
|
|
compose_file='docker/docker-compose.prod.yml'
|
|
docker compose -f "\$compose_file" config --quiet
|
|
docker compose -f "\$compose_file" up -d --build
|
|
|
|
for attempt in \$(seq 1 60); do
|
|
if curl -fsS "http://127.0.0.1:\$web_port/api/health" >/dev/null; then
|
|
docker compose -f "\$compose_file" ps
|
|
echo 'Feedback demo deployment and health check passed.'
|
|
exit 0
|
|
fi
|
|
sleep 2
|
|
done
|
|
|
|
docker compose -f "\$compose_file" ps
|
|
docker compose -f "\$compose_file" logs --tail=100 web
|
|
exit 1
|
|
REMOTE_SCRIPT
|