feat: update deployment scripts and configuration; enhance CI/CD process with new scripts for staging and production

This commit is contained in:
2026-02-26 12:36:53 +00:00
parent 965a505e15
commit 5707eb30dd
9 changed files with 364 additions and 220 deletions

62
scripts/ci-deploy.sh Executable file
View File

@@ -0,0 +1,62 @@
#!/usr/bin/env bash
set -euo pipefail
# CI step: deploy to production via rsync
# Called from .gitea/workflows/deploy.yml
# Required env: RSYNC_USER, RSYNC_PASS, BRANCH
# Read .env
set -o allexport
. ./.env
. ./api/config.yml.env
set +o allexport
# Validate required env vars
for var in RSYNC_USER RSYNC_PASS RSYNC_HOST RSYNC_PORT; do
if [ -z "${!var:-}" ]; then
echo "${var} missing, exiting"
exit 1
fi
done
echo "Deploying ${BRANCH} to ${RSYNC_HOST} on port ${RSYNC_PORT} as ${RSYNC_USER}"
# Exclude source and sourcemaps on master deploy
excludes=""
if [ "${BRANCH}" = "master" ]; then
excludes='--exclude=src --exclude=*.map'
echo "master deploy, excluding ${excludes}"
fi
SSH_CMD="sshpass -p ${RSYNC_PASS} ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -p ${RSYNC_PORT} -l ${RSYNC_USER}"
# Sync frontend
rsync -rlcgD --perms -i -u -v --stats --progress \
--delete \
-e "${SSH_CMD}" \
${excludes} \
frontend/ \
"${RSYNC_HOST}":./frontend/
# Sync API config and hooks
rsync -rlcgD --perms -i -u -v --stats --progress \
--delete \
-e "${SSH_CMD}" \
api/ \
"${RSYNC_HOST}":./api/
# Ensure media directory exists on remote
mkdir -p media
chmod 770 media
rsync -rlcgD --perms -i -u -v --stats --progress \
-e "${SSH_CMD}" \
media \
"${RSYNC_HOST}":./
# Reload tibi-server config
reloadUrl="${LIVE_URL}/api/_/admin/reload"
curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer ${ADMIN_TOKEN}" -d '{}' "${reloadUrl}"
# Clear SSR cache
ssrUrl="${LIVE_URL}/api/ssr"
curl -X POST -H "Content-Type: application/json" -d '{}' "${ssrUrl}?clear=1"

45
scripts/ci-modify-config.sh Executable file
View File

@@ -0,0 +1,45 @@
#!/usr/bin/env bash
set -euo pipefail
# CI step: modify config for deployment
# Called from .gitea/workflows/deploy.yml
# Enable sentry
sed -i 's#\(sentryEnvironment.*\)".*"#\1"'"${GITHUB_REF_NAME}"'"#g' frontend/src/config.ts
sed -i 's#//\( sentry\\.init.*\)#\1#g' frontend/src/config.ts
sed -i 's#metrictCall = false#metrictCall = true#g' frontend/src/config.ts
# Build release string from git info
set -o allexport
. ./.env
echo "PROJECT_RELEASE=${SENTRY_PROJECT}.r$(git rev-list HEAD --count)-$(git describe --all --long | sed 's+/+-+')" >> .env
. ./.env
set +o allexport
echo "______ .env ______"
cat .env
echo
# Inject release and origin URL into hooks
sed -i 's#\(const release = \).*#\1"'"${PROJECT_RELEASE}"'"#g' api/hooks/config-client.js
sed -i 's#\(const originURL = \).*#\1"'"${LIVE_URL}"'"#g' api/hooks/config-client.js
# Inject cache-busting timestamp
stamp=$(date +%s)
sed -i "s/__TIMESTAMP__/${stamp}/g" frontend/spa.html
# Copy spa.html to api/templates (remove symlink or file first)
if [ -d api/templates ]; then
[ -L api/templates/spa.html ] && rm api/templates/spa.html
[ -f api/templates/spa.html ] && rm api/templates/spa.html
cp frontend/spa.html api/templates/spa.html
fi
echo "______ frontend/spa.html ______"
cat frontend/spa.html
# Set preview URL
sed -i 's#\(PREVIEW_URL=\).*#\1'"${LIVE_URL}"'/preview#g' api/config.yml.env
echo "______ api/config.yml.env ______"
cat api/config.yml.env

37
scripts/ci-staging.sh Executable file
View File

@@ -0,0 +1,37 @@
#!/usr/bin/env bash
set -euo pipefail
# CI step: deploy to staging environment
# Called from .gitea/workflows/deploy.yml
# Required env: API_BASEDIR, COMPOSE_PROJECT_NAME
# Read .env
set -o allexport
. ./.env
. ./api/config.yml.env
set +o allexport
# Sanitize compose project name (replace / with -)
COMPOSE_PROJECT_NAME=$(echo "${COMPOSE_PROJECT_NAME}" | sed 's+/+-+g')
export COMPOSE_PROJECT_NAME
# Sync files to staging directory
mkdir -p "${API_BASEDIR}/frontend"
rsync -av api "${API_BASEDIR}/"
rsync -av frontend/dist "${API_BASEDIR}/frontend/"
rsync -av frontend/assets "${API_BASEDIR}/frontend/"
sed -i 's#\(PREVIEW_URL=\).*#\1'"${STAGING_URL}"'/preview#g' "${API_BASEDIR}/api/config.yml.env"
# Start staging stack
docker compose -f docker-compose-staging.yml -p "${COMPOSE_PROJECT_NAME}" up -d --build --remove-orphans
# Wait for API to be ready
sleep 5
# Reload tibi-server config
reloadUrl="${STAGING_URL}/api/_/admin/reload"
curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer ${ADMIN_TOKEN}" -d '{}' "${reloadUrl}"
# Clear SSR cache
ssrUrl="${STAGING_URL}/api/ssr"
curl -X POST -H "Content-Type: application/json" -d '{}' "${ssrUrl}?clear=1"

32
scripts/ci-upload-sourcemaps.sh Executable file
View File

@@ -0,0 +1,32 @@
#!/usr/bin/env bash
set -euo pipefail
# CI step: upload sourcemaps to Sentry
# Called from .gitea/workflows/deploy.yml
# Required env: SENTRY_AUTH_TOKEN (passed from workflow secrets)
# Read .env
set -o allexport
. ./.env
set +o allexport
# Skip gracefully if no token is configured
if [ -z "${SENTRY_AUTH_TOKEN:-}" ]; then
echo "SENTRY_AUTH_TOKEN not set, skipping sourcemap upload"
exit 0
fi
echo "SENTRY_URL=${SENTRY_URL:-}"
echo "SENTRY_ORG=${SENTRY_ORG:-}"
echo "SENTRY_PROJECT=${SENTRY_PROJECT:-}"
echo "PROJECT_RELEASE=${PROJECT_RELEASE:-}"
echo "Injecting debug IDs..."
npx sentry-cli sourcemaps --log-level info inject frontend/dist
echo "Creating release and uploading sourcemaps..."
npx sentry-cli sourcemaps --log-level info upload \
--release="${PROJECT_RELEASE:-${SENTRY_PROJECT}.dirty}" \
--url-prefix='~/dist' \
--ext js --ext mjs --ext map \
frontend/dist