加固既有生产部署流程(07-27-yang-jun-reimbursement-readiness)
这个提交包含在:
@@ -7,7 +7,7 @@ operations require explicit approval and evidence.
|
||||
|
||||
## Rules
|
||||
|
||||
- Use `SYNC_ENV=0 POSTGRES_DATA_DIR=<absolute> STORAGE_HOST_DIR=<absolute> DEPLOY_DATA_MODE=<existing|initialize> bash deploy/trialrun/deploy.sh` only when deployment is approved; do not overwrite remote `.env`.
|
||||
- Existing installations use `DEPLOY_SERVER=<ssh-target> bash deploy/trialrun/deploy-existing.sh` only when deployment is approved; the wrapper reads the frozen allowlisted contract and keeps `SYNC_ENV=0`. First initialization or controlled recovery without that unit uses `deploy.sh` with explicit absolute data paths and `DEPLOY_DATA_MODE`; neither path overwrites remote `.env` by default.
|
||||
- When `server/src/config.js` reads a new environment key, add the same key to
|
||||
`deploy/trialrun/.env.example` before deployment; `deploy/trialrun/deploy.sh`
|
||||
runs `node deploy/trialrun/validate-env-contract.js` at step 0 and must fail
|
||||
@@ -1282,3 +1282,63 @@ bash scripts/qa/run-automatic-backup-contract.sh
|
||||
<explicit-controlled-paths> \
|
||||
bash deploy/trialrun/install-offhost-app-health-monitor.sh install
|
||||
```
|
||||
|
||||
## Scenario: Existing Deployment Preflight And Cache Stability
|
||||
|
||||
### 1. Scope / Trigger
|
||||
|
||||
- Trigger: deploying a new published commit onto an existing single-host trialrun installation.
|
||||
- Purpose: prevent a wrong repository-root interpretation from reaching `rsync --delete`, and prevent per-commit build identity from invalidating stable dependency layers.
|
||||
|
||||
### 2. Signatures
|
||||
|
||||
- Existing deployment entry: `DEPLOY_SERVER=<ssh-target> bash deploy/trialrun/deploy-existing.sh`.
|
||||
- Remote preflight: `deploy/trialrun/preflight-remote.sh` executed over SSH before rsync.
|
||||
- Canonical parameter source: allowlisted `Environment=` values from `hyb-oa-automatic-backup-daily.service`.
|
||||
- Stable image stages: `base`, `client_deps`, `client_build`, `server_deps`, `server_build`.
|
||||
|
||||
### 3. Contracts
|
||||
|
||||
- Never derive `REMOTE_DIR` from Compose `com.docker.compose.project.working_dir`; it may name the Compose-file directory rather than the repository root.
|
||||
- The existing-deployment wrapper reads only `REMOTE_DIR`, `REMOTE_ENV_FILE`, `COMPOSE_FILE`, `COMPOSE_PROJECT_NAME`, `POSTGRES_DATA_DIR` and `STORAGE_HOST_DIR`; it does not echo their values.
|
||||
- Before `mkdir` or rsync, existing mode requires repository markers, `PG_VERSION`, storage directory and a regular non-symlink env file when `SYNC_ENV=0`.
|
||||
- `apk add` and both lockfile `npm ci` steps precede `BUILD_SHA` / `VITE_BUILD_SHA`. Build identity may invalidate application output, never stable dependency installation.
|
||||
- Seed and smoke output reports readiness, counts and booleans; it does not print full login identifiers, contact values, WeCom identifiers, redirect URI or generated credentials.
|
||||
|
||||
### 4. Validation & Error Matrix
|
||||
|
||||
- Config directory passed as `REMOTE_DIR` -> preflight fails before rsync.
|
||||
- Remote env missing or symlinked with `SYNC_ENV=0` -> preflight fails before rsync.
|
||||
- Existing PGDATA missing `PG_VERSION` or storage missing -> preflight fails before rsync.
|
||||
- Canonical systemd unit missing an allowlisted value -> wrapper fails without calling `deploy.sh`.
|
||||
- Lockfile unchanged but a new SHA reruns dependency installation -> Dockerfile contract test fails.
|
||||
|
||||
### 5. Good/Base/Bad Cases
|
||||
|
||||
- Good: wrapper reads the frozen unit contract, preflight passes, Git archive syncs and unchanged dependency layers are cached.
|
||||
- Base: first initialization uses reviewed explicit parameters and `DEPLOY_DATA_MODE=initialize`; it does not pretend an existing unit is available.
|
||||
- Bad: inspect a running container's `working_dir`, append another `deploy/trialrun`, then discover the mistake only after rsync.
|
||||
|
||||
### 6. Tests Required
|
||||
|
||||
- `bash -n deploy/trialrun/deploy.sh deploy/trialrun/deploy-existing.sh deploy/trialrun/preflight-remote.sh`.
|
||||
- `node deploy/trialrun/validate-env-contract.js`.
|
||||
- `cd server && npm test -- tests/unit/scripts/deployment-safety-contract.test.js`.
|
||||
- Synthetic fixtures must prove wrong root, missing/symlink env and invalid data fail; static ordering must prove preflight precedes rsync and dependency stages precede build args.
|
||||
|
||||
### 7. Wrong vs Correct
|
||||
|
||||
#### Wrong
|
||||
|
||||
```bash
|
||||
# working_dir may be the Compose config directory, not the repository root.
|
||||
REMOTE_DIR="$(docker inspect <server> --format '<working_dir-label>')" \
|
||||
bash deploy/trialrun/deploy.sh
|
||||
```
|
||||
|
||||
#### Correct
|
||||
|
||||
```bash
|
||||
DEPLOY_SERVER=<approved-ssh-target> \
|
||||
bash deploy/trialrun/deploy-existing.sh
|
||||
```
|
||||
|
||||
在新工单中引用
屏蔽一个用户