various fixes

This commit is contained in:
Kevin
2026-03-23 13:21:07 +08:00
parent 9c2e0329ca
commit b9ecfd02a4
18 changed files with 393 additions and 277 deletions

View File

@@ -7,11 +7,11 @@
# - 若需兼容旧 32 位 ARM 设备,可将该属性改为 armeabi-v7a,arm64-v8a体积会增大
# - 若需用 x86 模拟器验证此 APK需改回含 x86 的 ABI 或另建 job。
#
# 环境映射(按触发源自动推断
# main → dev (开发 + 内部测试)
# v*.*.* → prod (正式发布 + GitHub Release 附带 APK)
# 环境映射(与后端 api 一致main → 预发 stagingtag → 生产 production
# push main → stage → node scripts/use-env.js staging → .env.staging
# push v*.*.* → prod → node scripts/use-env.js production → .env.production
#
# 手动触发workflow_dispatch 可选 dev / stage / prod
# 手动触发 workflow_dispatch可选 dev / stage / proddev 用 .env.development便于打内部测试包
#
# Repository secrets与 android-release.yml 共用同一套即可):
# ANDROID_KEYSTORE_BASE64 / ANDROID_STORE_PASSWORD / ANDROID_KEY_ALIAS / ANDROID_KEY_PASSWORD
@@ -72,7 +72,8 @@ jobs:
elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
echo "env=${{ github.event.inputs.environment }}"
else
echo "env=dev"
# push 到 main本 workflow 仅监听 main 与 tag
echo "env=stage"
fi >> $GITHUB_OUTPUT
- name: Set up Node.js
@@ -86,8 +87,8 @@ jobs:
working-directory: app-expo
run: npm ci
- name: Quality checks (dev only)
if: steps.env.outputs.env == 'dev'
- name: Quality checks (non-prod)
if: steps.env.outputs.env != 'prod'
working-directory: app-expo
run: |
npm run format:check

View File

@@ -1,15 +1,15 @@
# API Dockermain → DevRepository secrets: DEV_*Tag v*.*.* → Prod 机PROD_*
# API Dockermain → StagingRepository secrets: STAGING_*Tag v*.*.* → Prod 机PROD_*
# 在 Repo → Settings → Secrets and variables → Actions 中配置,无需 GitHub Environments。
# 命名:DEV_SSH_HOST / DEV_SSH_USER / DEV_SSH_PRIVATE_KEY / DEV_SSH_PORT / DEV_DEPLOY_PATH
# 命名:STAGING_SSH_HOST / STAGING_SSH_USER / STAGING_SSH_PRIVATE_KEY / STAGING_SSH_PORT / STAGING_DEPLOY_PATH
# PROD_SSH_HOST / PROD_SSH_USER / PROD_SSH_PRIVATE_KEY / PROD_SSH_PORT / PROD_DEPLOY_PATH
# 阿里云镜像仍为仓库级ALIYUN_CR_USERNAME / ALIYUN_CR_PASSWORD
#
# 从旧版迁移:若仓库里仍是 SSH_HOST、SSH_PRIVATE_KEY、DEPLOY_PATH 等无前缀名称,
# 请把「原机 / 内部测试」对应值复制为 DEV_*,「新生产机」填 PROD_*,并删除旧的无前缀 Secret。
# 请把「预发机」对应值迁移为 STAGING_*,「新生产机」填 PROD_*,并删除旧的无前缀 Secret。
#
# 发布策略:
# - merge / push 到 main构建并部署到 Dev / 内部测试
# - 手动创建并推送 tag vMAJOR.MINOR.PATCH构建并部署到 Production
# - merge / push 到 main构建并部署到 Staging 机;使用仓库中的 api/.env.staging上传后切换为运行时 .env
# - 手动创建并推送 tag vMAJOR.MINOR.PATCH构建并部署到 Production;使用仓库中的 api/.env.production上传后切换为运行时 .env
#
# 注意paths 过滤在 tag push 时按「被指向的 commit」判断若该 commit 未改 api/ 与本 workflow不会触发。
# 此时可用 workflow_dispatch 选择对应 tag/ref 手动部署。
@@ -122,7 +122,7 @@ jobs:
if [[ "$REF_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "target=prod" >> "$GITHUB_OUTPUT"
else
echo "target=dev" >> "$GITHUB_OUTPUT"
echo "target=staging" >> "$GITHUB_OUTPUT"
fi
- name: Ensure production SSH secret is set
@@ -135,28 +135,28 @@ jobs:
exit 1
fi
- name: Ensure development SSH secret is set
- name: Ensure staging SSH secret is set
if: steps.deploy_target.outputs.target != 'prod'
env:
DEV_SSH_PRIVATE_KEY: ${{ secrets.DEV_SSH_PRIVATE_KEY }}
STAGING_SSH_PRIVATE_KEY: ${{ secrets.STAGING_SSH_PRIVATE_KEY }}
run: |
if [ -z "$DEV_SSH_PRIVATE_KEY" ]; then
echo "::error::DEV_SSH_PRIVATE_KEY 未配置或为空,无法部署开发机。请在 Repository secrets 中设置 DEV_SSH_*。"
if [ -z "$STAGING_SSH_PRIVATE_KEY" ]; then
echo "::error::STAGING_SSH_PRIVATE_KEY 未配置或为空,无法部署 staging。请在 Repository secrets 中设置 STAGING_SSH_*。"
exit 1
fi
# 勿用 `prod && PROD_KEY || DEV_KEY`PROD 为空时会错误回退到 DEV 密钥,导致连生产机报 Permission denied。
# 勿用 `prod && PROD_KEY || STAGING_KEY`PROD 为空时会错误回退到 staging 密钥,导致连生产机报 Permission denied。
- name: Set up SSH (production)
if: steps.deploy_target.outputs.target == 'prod'
uses: webfactory/ssh-agent@v0.9.1
with:
ssh-private-key: ${{ secrets.PROD_SSH_PRIVATE_KEY }}
- name: Set up SSH (development)
- name: Set up SSH (staging)
if: steps.deploy_target.outputs.target != 'prod'
uses: webfactory/ssh-agent@v0.9.1
with:
ssh-private-key: ${{ secrets.DEV_SSH_PRIVATE_KEY }}
ssh-private-key: ${{ secrets.STAGING_SSH_PRIVATE_KEY }}
- name: Export deploy connection env
run: |
@@ -169,10 +169,10 @@ jobs:
} >> "$GITHUB_ENV"
else
{
echo "SSH_HOST=${{ secrets.DEV_SSH_HOST }}"
echo "SSH_USER=${{ secrets.DEV_SSH_USER }}"
echo "SSH_PORT=${{ secrets.DEV_SSH_PORT || '22' }}"
echo "COMPOSE_DIR=${{ secrets.DEV_DEPLOY_PATH || '/opt/life-echo' }}"
echo "SSH_HOST=${{ secrets.STAGING_SSH_HOST }}"
echo "SSH_USER=${{ secrets.STAGING_SSH_USER }}"
echo "SSH_PORT=${{ secrets.STAGING_SSH_PORT || '22' }}"
echo "COMPOSE_DIR=${{ secrets.STAGING_DEPLOY_PATH || '/opt/life-echo' }}"
} >> "$GITHUB_ENV"
fi
@@ -222,10 +222,32 @@ jobs:
docker network inspect api_life-echo-network >/dev/null 2>&1 || docker network create api_life-echo-network
"
echo "上传候选 compose、Caddyfile 与环境变量..."
if [ "${{ steps.deploy_target.outputs.target }}" = "prod" ]; then
ENV_SRC="api/.env.production"
else
ENV_SRC="api/.env.staging"
fi
if [ ! -f "$ENV_SRC" ]; then
echo "::error::缺少 $ENV_SRC无法部署。"
exit 1
fi
if grep -Eq '=(your_|replace_with_|\\.{3}$)' "$ENV_SRC"; then
echo "::error::$ENV_SRC 仍包含占位符值,请先完善环境文件。"
exit 1
fi
if grep -Eq '^DATABASE_URL=.*@localhost:' "$ENV_SRC" || grep -Eq '^REDIS_URL=redis://localhost' "$ENV_SRC"; then
echo "::error::$ENV_SRC 包含 localhost 数据库或 Redis 地址,容器内将无法连接。"
exit 1
fi
if grep -Eq '^DATABASE_URL=.*@postgresql:' "$ENV_SRC"; then
echo "::error::$ENV_SRC 仍引用过期主机名 postgresql当前 compose 服务名应为 postgres。"
exit 1
fi
echo "上传候选 compose、Caddyfile 与环境文件..."
scp -P "$SSH_PORT" ./api/docker-compose.yml "$SSH_USER@$SSH_HOST:$COMPOSE_DIR/api/docker-compose.candidate.yml"
scp -P "$SSH_PORT" ./api/Caddyfile "$SSH_USER@$SSH_HOST:$COMPOSE_DIR/api/Caddyfile.candidate"
scp -P "$SSH_PORT" ./api/.env.production "$SSH_USER@$SSH_HOST:$COMPOSE_DIR/api/.env.production.candidate"
scp -P "$SSH_PORT" "$ENV_SRC" "$SSH_USER@$SSH_HOST:$COMPOSE_DIR/api/.env.candidate"
ssh -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" "
set -euo pipefail
@@ -255,9 +277,12 @@ jobs:
if [ -f '.env.production' ]; then
cp '.env.production' '.env.production.predeploy'
fi
if [ -f '.env' ]; then
cp '.env' '.env.predeploy'
fi
mv 'docker-compose.candidate.yml' '$COMPOSE_FILE'
mv 'Caddyfile.candidate' 'Caddyfile'
mv '.env.production.candidate' '.env.production'
mv '.env.candidate' '.env'
docker-compose -f '$COMPOSE_FILE' up -d --remove-orphans
echo '等待服务启动...'
sleep 20