sqlite-web 0.7.2
gitea.db
action_run_job
Create
Query
access
access_token
action
action_artifact
action_run
action_run_index
action_run_job
action_runner
action_runner_token
action_schedule
action_schedule_spec
action_task
action_task_output
action_task_step
action_tasks_version
action_variable
app_state
attachment
auth_token
badge
branch
collaboration
comment
commit_status
commit_status_index
commit_status_summary
commit_sync_log
commit_sync_status
dbfs_data
dbfs_meta
deploy_key
email_address
email_hash
external_login_user
follow
gpg_key
gpg_key_import
hook_task
issue
issue_assignees
issue_content_history
issue_dependency
issue_index
issue_label
issue_pin
issue_user
issue_watch
label
language_stat
lfs_lock
lfs_meta_object
login_source
milestone
mirror
notice
notification
oauth2_application
oauth2_authorization_code
oauth2_grant
org_user
package
package_blob
package_blob_upload
package_cleanup_rule
package_file
package_property
package_version
project
project_board
project_issue
protected_branch
protected_tag
public_key
pull_auto_merge
pull_request
push_mirror
reaction
release
renamed_branch
repo_archiver
repo_hidden_file
repo_indexer_status
repo_license
repo_redirect
repo_topic
repo_transfer
repo_unit
repository
review
review_state
secret
session
sqlite_sequence
star
stopwatch
system_setting
task
team
team_invite
team_repo
team_unit
team_user
topic
tracked_time
two_factor
upload
user
user_badge
user_blocking
user_open_id
user_redirect
user_setting
version
watch
webauthn_credential
webhook
Toggle helper tables
Structure
Content
Query
Insert
Drop
Import
Export
Delete row 9209 from action_run_job
id
9209
run_id
7416
repo_id
6
owner_id
5
commit_sha
67078f9a95f53530156ad27027eafe15a3126e89
is_fork_pull_request
0
name
部署到阿里云
attempt
0
workflow_payload
name: Deploy to Aliyun "on": push:
name: Deploy to Aliyun "on": push: branches: [main] tags: ['v*'] workflow_dispatch: inputs: environment: description: '部署环境' required: true default: 'production' type: choice options: - production skip_tests: description: '跳过测试(紧急修复)' required: false default: false type: boolean version: description: '部署版本号(手动输入)' required: false type: string env: IMAGE_PREFIX: ${{ github.repository_owner }}/juhi NODE_VERSION: "20" PNPM_VERSION: "8" REGISTRY: ghcr.io jobs: deploy-aliyun: name: 部署到阿里云 runs-on: ubuntu-latest steps: - name: 检出代码 uses: actions/checkout@v4 - name: 配置 SSH uses: webfactory/ssh-agent@v0.8.0 with: ssh-private-key: ${{ secrets.ALIYUN_SSH_PRIVATE_KEY }} - name: 配置 SSH Known Hosts run: | mkdir -p ~/.ssh echo "${{ secrets.ALIYUN_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts chmod 644 ~/.ssh/known_hosts - name: 同步部署文件到阿里云 run: | echo "==> 同步部署文件到阿里云..." rsync -avz --delete \ --exclude 'node_modules' \ --exclude '.git' \ --exclude 'backups' \ --exclude 'data' \ --exclude 'logs' \ docker-compose.prod.yml \ scripts/ \ deploy/ \ .env.production.example \ $USER@$HOST:$DEPLOY_PATH/ env: HOST: ${{ secrets.ALIYUN_HOST }} USER: ${{ secrets.ALIYUN_USER }} DEPLOY_PATH: /opt/juhi - name: 部署前检查 run: "ssh $USER@$HOST << 'EOF'\n cd /opt/juhi\n \n echo \"==> 执行部署前检查...\"\n \n # 检查 Docker\n if ! command -v docker &> /dev/null; then\n echo \"❌ Docker 未安装\"\n exit 1\n fi\n \n # 检查 Docker Compose\n if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then\n echo \"❌ Docker Compose 未安装\"\n exit 1\n fi\n \n # 检查磁盘空间\n DISK_USAGE=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')\n if [ \"$DISK_USAGE\" -gt 85 ]; then\n echo \"⚠️ 磁盘使用率过高:${DISK_USAGE}%\"\n fi\n \n echo \"✅ 部署前检查通过\"\nEOF\n" env: HOST: ${{ secrets.ALIYUN_HOST }} USER: ${{ secrets.ALIYUN_USER }} - name: 数据库备份 run: "ssh $USER@$HOST << 'EOF'\n cd /opt/juhi\n \n echo \"==> 执行数据库备份...\"\n BACKUP_DIR=\"/opt/juhi/backups\"\n mkdir -p \"$BACKUP_DIR\"\n TIMESTAMP=$(date +%Y%m%d_%H%M%S)\n BACKUP_FILE=\"$BACKUP_DIR/pre_deploy_${TIMESTAMP}.sql.gz\"\n \n # 使用 docker exec 执行备份\n docker exec juhi-postgres pg_dump -U \"${DB_USER:-juhi_user}\" -d \"${DB_NAME:-juhi_db}\" | gzip > \"$BACKUP_FILE\"\n \n if [ $? -eq 0 ]; then\n BACKUP_SIZE=$(du -h \"$BACKUP_FILE\" | cut -f1)\n echo \"✅ 备份完成:$BACKUP_FILE ($BACKUP_SIZE)\"\n else\n echo \"❌ 备份失败,终止部署\"\n exit 1\n fi\n \n # 清理 30 天前的旧备份\n find \"$BACKUP_DIR\" -name \"*.sql.gz\" -mtime +30 -delete 2>/dev/null || true\n echo \"✅ 清理旧备份完成\"\nEOF\n" env: HOST: ${{ secrets.ALIYUN_HOST }} USER: ${{ secrets.ALIYUN_USER }} - name: 拉取镜像并部署 run: "ssh $USER@$HOST << EOF\n cd $DEPLOY_PATH\n \n echo \"==========================================\"\n echo \"开始部署版本:${VERSION}\"\n echo \"==========================================\"\n \n # 拉取最新镜像\n echo \"==> 拉取 Docker 镜像...\"\n docker compose -f docker-compose.prod.yml pull api frontend\n \n # 记录当前运行版本\n CURRENT_VERSION=\\$(cat .deployed_version 2>/dev/null || echo \"unknown\")\n echo \"当前版本:\\$CURRENT_VERSION\"\n \n # 执行数据库迁移\n echo \"==> 执行数据库迁移...\"\n docker compose -f docker-compose.prod.yml --profile migrate run --rm migrate\n if [ \\$? -ne 0 ]; then\n echo \"❌ 数据库迁移失败\"\n exit 1\n fi\n echo \"✅ 数据库迁移完成\"\n \n # 滚动更新 API\n echo \"==> 更新 API 服务...\"\n docker compose -f docker-compose.prod.yml up -d --no-deps --remove-orphans api\n \n # 等待 API 就绪\n echo \"==> 等待 API 服务就绪...\"\n RETRY=0\n MAX_RETRY=15\n until curl -sf http://localhost:3000/health > /dev/null 2>&1; do\n RETRY=\\$((RETRY + 1))\n if [ \\$RETRY -ge \\$MAX_RETRY ]; then\n echo \"❌ API 健康检查超时\"\n docker compose -f docker-compose.prod.yml logs --tail=50 api\n exit 1\n fi\n echo \" 等待中... (\\${RETRY}/\\${MAX_RETRY})\"\n sleep 5\n done\n echo \"✅ API 健康检查通过\"\n \n # 更新前端\n echo \"==> 更新前端服务...\"\n docker compose -f docker-compose.prod.yml up -d --no-deps frontend\n \n # 重载 Nginx\n echo \"==> 重载 Nginx 配置...\"\n docker compose -f docker-compose.prod.yml exec -T nginx nginx -s reload 2>/dev/null || true\n \n # 清理旧镜像\n echo \"==> 清理旧镜像...\"\n docker image prune -f --filter \"until=24h\"\n \n # 记录部署版本\n echo \"${VERSION}\" > .deployed_version\n echo \"\\$(date -Iseconds)|${VERSION}|${CURRENT_VERSION}\" >> .deploy-history\n tail -20 .deploy-history > .deploy-history.tmp && mv .deploy-history.tmp .deploy-history\n \n echo \"==========================================\"\n echo \"✅ 部署完成:版本 ${VERSION}\"\n echo \"==========================================\"\nEOF\n" env: HOST: ${{ secrets.ALIYUN_HOST }} USER: ${{ secrets.ALIYUN_USER }} DEPLOY_PATH: /opt/juhi VERSION: ${{ needs.build.outputs.version }} - name: 部署后验证 run: "ssh $USER@$HOST << 'EOF'\n cd /opt/juhi\n \n echo \"==> 执行部署后验证...\"\n \n # 运行验证脚本\n if [ -f \"./scripts/post-deploy-verify.sh\" ]; then\n chmod +x ./scripts/post-deploy-verify.sh\n ./scripts/post-deploy-verify.sh --quick\n else\n # 基础验证\n echo \"1. 检查 API 健康...\"\n curl -sf http://localhost:3000/health || { echo \"❌ API 健康检查失败\"; exit 1; }\n echo \"✅ API 健康检查通过\"\n \n echo \"2. 检查前端...\"\n curl -sf http://localhost/ || { echo \"❌ 前端访问失败\"; exit 1; }\n echo \"✅ 前端访问正常\"\n \n echo \"3. 检查容器状态...\"\n UNHEALTHY=$(docker compose -f docker-compose.prod.yml ps --format json | grep -c '\"unhealthy\"' || true)\n if [ \"$UNHEALTHY\" -gt 0 ]; then\n echo \"❌ 发现不健康的容器\"\n docker compose -f docker-compose.prod.yml ps\n exit 1\n fi\n echo \"✅ 所有容器状态正常\"\n fi\n \n echo \"✅ 部署验证通过\"\nEOF\n" env: HOST: ${{ secrets.ALIYUN_HOST }} USER: ${{ secrets.ALIYUN_USER }} - if: startsWith(github.ref, 'refs/tags/v') name: 创建 GitHub Release(仅标签触发) uses: softprops/action-gh-release@v2 with: generate_release_notes: "true" make_latest: "true" - if: always() name: 发送部署通知 run: "echo \"## \U0001F680 部署完成\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\necho \"- 环境:阿里云生产环境\" >> $GITHUB_STEP_SUMMARY\necho \"- 版本:`${{ needs.build.outputs.version }}`\" >> $GITHUB_STEP_SUMMARY\necho \"- 状态:`${{ job.status }}`\" >> $GITHUB_STEP_SUMMARY\necho \"- 触发者:`${{ github.actor }}`\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\n\nif [ \"${{ job.status }}\" == \"success\" ]; then\n echo \"✅ 部署成功!\" >> $GITHUB_STEP_SUMMARY\nelse\n echo \"❌ 部署失败,请检查日志\" >> $GITHUB_STEP_SUMMARY\nfi\n" timeout-minutes: "20"
...
job_id
deploy-aliyun
needs
["build"]
runs_on
["ubuntu-latest"]
task_id
0
status
4
started
0
stopped
0
created
1774262376
updated
1774263612
raw_concurrency
is_concurrency_evaluated
1
concurrency_group
concurrency_cancel
0
Delete
Cancel