Merge branch 'main' into dev
This commit is contained in:
@@ -0,0 +1,83 @@
|
|||||||
|
name: Publish Images
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- dev
|
||||||
|
- release
|
||||||
|
- release/**
|
||||||
|
- main
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: publish-images-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
REMOTE_BASE_DIR: /opt/ctms-build
|
||||||
|
SSH_KEY_PATH: /tmp/tcloud_ci_key
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Prepare remote path metadata
|
||||||
|
id: meta
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo "repo_name=${GITHUB_REPOSITORY#*/}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "branch_name=${GITHUB_REF_NAME}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "short_sha=${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- name: Install SSH key
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
printf '%s\n' '${{ secrets.TCLOUD_SSH_KEY }}' > "${{ env.SSH_KEY_PATH }}"
|
||||||
|
chmod 600 "${{ env.SSH_KEY_PATH }}"
|
||||||
|
|
||||||
|
- name: Sync repository to Tencent Cloud host
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
TCLOUD_HOST: ${{ secrets.TCLOUD_HOST }}
|
||||||
|
TCLOUD_PORT: ${{ secrets.TCLOUD_PORT }}
|
||||||
|
TCLOUD_USER: ${{ secrets.TCLOUD_USER }}
|
||||||
|
REMOTE_REPO_DIR: ${{ env.REMOTE_BASE_DIR }}/${{ steps.meta.outputs.repo_name }}
|
||||||
|
run: |
|
||||||
|
ssh -i "${{ env.SSH_KEY_PATH }}" -p "${TCLOUD_PORT}" -o StrictHostKeyChecking=no "${TCLOUD_USER}@${TCLOUD_HOST}" \
|
||||||
|
"mkdir -p '${REMOTE_REPO_DIR}' && find '${REMOTE_REPO_DIR}' -mindepth 1 -maxdepth 1 -exec rm -rf {} +"
|
||||||
|
tar --exclude=.git -cf - . | \
|
||||||
|
ssh -i "${{ env.SSH_KEY_PATH }}" -p "${TCLOUD_PORT}" -o StrictHostKeyChecking=no "${TCLOUD_USER}@${TCLOUD_HOST}" \
|
||||||
|
"tar -xf - -C '${REMOTE_REPO_DIR}'"
|
||||||
|
|
||||||
|
- name: Build and push images on Tencent Cloud host
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
TCLOUD_HOST: ${{ secrets.TCLOUD_HOST }}
|
||||||
|
TCLOUD_PORT: ${{ secrets.TCLOUD_PORT }}
|
||||||
|
TCLOUD_USER: ${{ secrets.TCLOUD_USER }}
|
||||||
|
BRANCH_NAME: ${{ steps.meta.outputs.branch_name }}
|
||||||
|
COMMIT_SHA: ${{ github.sha }}
|
||||||
|
REGISTRY_HOST: ${{ secrets.REGISTRY_HOST }}
|
||||||
|
REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }}
|
||||||
|
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
|
||||||
|
REMOTE_REPO_DIR: ${{ env.REMOTE_BASE_DIR }}/${{ steps.meta.outputs.repo_name }}
|
||||||
|
run: |
|
||||||
|
BRANCH_NAME_B64="$(printf '%s' "${BRANCH_NAME}" | base64)"
|
||||||
|
COMMIT_SHA_B64="$(printf '%s' "${COMMIT_SHA}" | base64)"
|
||||||
|
REGISTRY_HOST_B64="$(printf '%s' "${REGISTRY_HOST}" | base64)"
|
||||||
|
REGISTRY_USERNAME_B64="$(printf '%s' "${REGISTRY_USERNAME}" | base64)"
|
||||||
|
REGISTRY_PASSWORD_B64="$(printf '%s' "${REGISTRY_PASSWORD}" | base64)"
|
||||||
|
ssh -i "${{ env.SSH_KEY_PATH }}" -p "${TCLOUD_PORT}" -o StrictHostKeyChecking=no "${TCLOUD_USER}@${TCLOUD_HOST}" "
|
||||||
|
cd '${REMOTE_REPO_DIR}'
|
||||||
|
chmod +x scripts/build-and-push-registry.sh
|
||||||
|
export BRANCH_NAME=\$(printf '%s' '${BRANCH_NAME_B64}' | base64 -d)
|
||||||
|
export COMMIT_SHA=\$(printf '%s' '${COMMIT_SHA_B64}' | base64 -d)
|
||||||
|
export REGISTRY_HOST=\$(printf '%s' '${REGISTRY_HOST_B64}' | base64 -d)
|
||||||
|
export REGISTRY_USERNAME=\$(printf '%s' '${REGISTRY_USERNAME_B64}' | base64 -d)
|
||||||
|
export REGISTRY_PASSWORD=\$(printf '%s' '${REGISTRY_PASSWORD_B64}' | base64 -d)
|
||||||
|
./scripts/build-and-push-registry.sh
|
||||||
|
"
|
||||||
@@ -12,6 +12,14 @@
|
|||||||
- `curl -i http://127.0.0.1/`
|
- `curl -i http://127.0.0.1/`
|
||||||
- `curl -i http://127.0.0.1/health`
|
- `curl -i http://127.0.0.1/health`
|
||||||
|
|
||||||
|
## 腾讯云私有镜像仓库
|
||||||
|
- GitHub Actions 会在推送到 `dev`、`release`、`release/*` 和 `main` 时,通过 SSH 连接腾讯云服务器,在服务器本机完成 `backend` 和 `nginx` 镜像的构建与推送。
|
||||||
|
- 私有仓库地址默认使用 `${REGISTRY_HOST}`,仓库命名为 `${REGISTRY_HOST}/ctms/ctms-backend` 和 `${REGISTRY_HOST}/ctms/ctms-nginx`。
|
||||||
|
- `dev` 分支发布 `dev-latest` 和 `dev-<short_sha>`,`release` 分支发布 `rc-release` 和 `rc-<short_sha>`,`release/*` 分支发布 `rc-<release-branch>` 和 `rc-<short_sha>`,`main` 分支发布 `latest` 和 `sha-<short_sha>`。
|
||||||
|
- 部署机需要先 `docker login <IP>:5000`,并使用私有仓库的 `htpasswd` 账号密码完成认证。
|
||||||
|
- `backend-init` 复用 `BACKEND_IMAGE`,所以生产机可在设置 `REGISTRY_HOST`,或直接指定 `BACKEND_IMAGE` 和 `NGINX_IMAGE` 后执行 `docker compose pull && docker compose run --rm backend-init && docker compose up -d`。
|
||||||
|
- 本地开发仍可继续使用 `docker compose up -d --build` 走本地构建。
|
||||||
|
|
||||||
## 账号与注册
|
## 账号与注册
|
||||||
- 初始化管理员:`admin@huapont.cn / admin123`(通过生产初始化命令显式创建)
|
- 初始化管理员:`admin@huapont.cn / admin123`(通过生产初始化命令显式创建)
|
||||||
- 自助注册:前端 `/register` 提交邮箱、密码、姓名、角色(CRA/PV/IMP/PM)、部门,状态为 PENDING。
|
- 自助注册:前端 `/register` 提交邮箱、密码、姓名、角色(CRA/PV/IMP/PM)、部门,状态为 PENDING。
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ services:
|
|||||||
- ctms_net
|
- ctms_net
|
||||||
|
|
||||||
backend:
|
backend:
|
||||||
|
image: ${BACKEND_IMAGE:-${REGISTRY_HOST:-127.0.0.1:5000}/ctms/ctms-backend:latest}
|
||||||
build:
|
build:
|
||||||
context: ./backend
|
context: ./backend
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
@@ -37,6 +38,7 @@ services:
|
|||||||
- ctms_net
|
- ctms_net
|
||||||
|
|
||||||
backend-init:
|
backend-init:
|
||||||
|
image: ${BACKEND_IMAGE:-${REGISTRY_HOST:-127.0.0.1:5000}/ctms/ctms-backend:latest}
|
||||||
build:
|
build:
|
||||||
context: ./backend
|
context: ./backend
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
@@ -51,6 +53,7 @@ services:
|
|||||||
- ctms_net
|
- ctms_net
|
||||||
|
|
||||||
nginx:
|
nginx:
|
||||||
|
image: ${NGINX_IMAGE:-${REGISTRY_HOST:-127.0.0.1:5000}/ctms/ctms-nginx:latest}
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: nginx/Dockerfile
|
dockerfile: nginx/Dockerfile
|
||||||
|
|||||||
@@ -9,6 +9,14 @@
|
|||||||
- [ ] `cd backend && python3 -m compileall app scripts`
|
- [ ] `cd backend && python3 -m compileall app scripts`
|
||||||
- [ ] `cd frontend && npm run build`
|
- [ ] `cd frontend && npm run build`
|
||||||
|
|
||||||
|
## 1.1 腾讯云私有镜像校验
|
||||||
|
- [ ] `dev` 推送后,`<IP>:5000/ctms/ctms-backend` 和 `ctms-nginx` 的 `dev-latest` / `dev-<short_sha>` 标签已出现在私有仓库
|
||||||
|
- [ ] `release` 推送后,`<IP>:5000/ctms/ctms-backend` 和 `ctms-nginx` 的 `rc-release` / `rc-<short_sha>` 标签已出现在私有仓库
|
||||||
|
- [ ] `release/*` 推送后,`<IP>:5000/ctms/ctms-backend` 和 `ctms-nginx` 的 `rc-<release-branch>` / `rc-<short_sha>` 标签已出现在私有仓库
|
||||||
|
- [ ] `main` 推送后,`<IP>:5000/ctms/ctms-backend` 和 `ctms-nginx` 的 `latest` / `sha-<short_sha>` 标签已出现在私有仓库
|
||||||
|
- [ ] GitHub Actions 已成功 SSH 登录腾讯云服务器并执行远程构建脚本
|
||||||
|
- [ ] 部署机已执行 `docker login <IP>:5000`,且使用的是私有仓库 `htpasswd` 账号密码
|
||||||
|
|
||||||
## 2. 接口与权限回归
|
## 2. 接口与权限回归
|
||||||
- [ ] ADMIN 账号可 `GET/PUT/PUBLISH/IMPORT-EXCEL/EXPORT-EXCEL`
|
- [ ] ADMIN 账号可 `GET/PUT/PUBLISH/IMPORT-EXCEL/EXPORT-EXCEL`
|
||||||
- [ ] PM 账号可 `GET/PUT/PUBLISH/IMPORT-EXCEL/EXPORT-EXCEL`
|
- [ ] PM 账号可 `GET/PUT/PUBLISH/IMPORT-EXCEL/EXPORT-EXCEL`
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
# Tencent Cloud Private Registry Design
|
||||||
|
|
||||||
|
**Goal:** Add CI that automatically builds and pushes private `backend` and `nginx` images to a self-hosted Docker Registry running on a Tencent Cloud CVM, with `dev` publishing test tags, `release` and `release/*` publishing release-candidate tags, and `main` publishing formal tags.
|
||||||
|
|
||||||
|
**Decisions**
|
||||||
|
- Publish only two runtime images: `<registry-host>/ctms/ctms-backend` and `<registry-host>/ctms/ctms-nginx`.
|
||||||
|
- Keep the private registry on the Tencent Cloud CVM as a self-hosted `registry:2` instance protected by `htpasswd`.
|
||||||
|
- Trigger automation on pushes to `dev`, `release`, `release/*`, and `main`.
|
||||||
|
- Use GitHub Actions only as the orchestrator. Actual Docker build and push happen on the Tencent Cloud server over SSH.
|
||||||
|
- Keep `docker-compose.yaml` compatible with both local `build` workflows and private registry pulls.
|
||||||
|
|
||||||
|
**Approaches Considered**
|
||||||
|
- Recommended: GitHub Actions connects to the Tencent Cloud server over SSH and runs a server-local build-and-push script. This avoids GitHub-hosted runner limitations around insecure or self-signed private registries and keeps registry access local to the server.
|
||||||
|
- Alternative: GitHub Actions builds and pushes directly to `<IP>:5000`. This is simpler on paper but is fragile when the registry is exposed only as an IP endpoint and may use insecure or non-public TLS.
|
||||||
|
- Alternative: move first to a domain-backed HTTPS registry and then push directly from GitHub Actions. This is the clean long-term path but adds infrastructure work that is not required for the current goal.
|
||||||
|
|
||||||
|
**Architecture**
|
||||||
|
- A new GitHub Actions workflow triggers on pushes to `dev`, `release`, `release/*`, and `main`.
|
||||||
|
- The workflow authenticates to the Tencent Cloud server using SSH credentials stored in GitHub Secrets.
|
||||||
|
- The workflow syncs the repository contents to a fixed build directory such as `/opt/ctms-build/<repo>`.
|
||||||
|
- A server-local script logs in to the private registry, builds `backend` and `nginx`, applies branch-specific tags, and pushes the images to the registry.
|
||||||
|
|
||||||
|
**Registry Naming**
|
||||||
|
- Backend image: `<registry-host>/ctms/ctms-backend`
|
||||||
|
- Nginx image: `<registry-host>/ctms/ctms-nginx`
|
||||||
|
- `frontend` is intentionally not published because the current runtime topology already builds the frontend assets into the `nginx` image.
|
||||||
|
|
||||||
|
**Tagging Strategy**
|
||||||
|
- `dev` branch pushes publish:
|
||||||
|
- `<registry-host>/ctms/ctms-backend:dev-latest`
|
||||||
|
- `<registry-host>/ctms/ctms-backend:dev-<short_sha>`
|
||||||
|
- `<registry-host>/ctms/ctms-nginx:dev-latest`
|
||||||
|
- `<registry-host>/ctms/ctms-nginx:dev-<short_sha>`
|
||||||
|
- `release` branch pushes publish:
|
||||||
|
- `<registry-host>/ctms/ctms-backend:rc-release`
|
||||||
|
- `<registry-host>/ctms/ctms-backend:rc-<short_sha>`
|
||||||
|
- `<registry-host>/ctms/ctms-nginx:rc-release`
|
||||||
|
- `<registry-host>/ctms/ctms-nginx:rc-<short_sha>`
|
||||||
|
- `release/*` branch pushes publish:
|
||||||
|
- `<registry-host>/ctms/ctms-backend:rc-<release-branch>`
|
||||||
|
- `<registry-host>/ctms/ctms-backend:rc-<short_sha>`
|
||||||
|
- `<registry-host>/ctms/ctms-nginx:rc-<release-branch>`
|
||||||
|
- `<registry-host>/ctms/ctms-nginx:rc-<short_sha>`
|
||||||
|
- `main` branch pushes publish:
|
||||||
|
- `<registry-host>/ctms/ctms-backend:latest`
|
||||||
|
- `<registry-host>/ctms/ctms-backend:sha-<short_sha>`
|
||||||
|
- `<registry-host>/ctms/ctms-nginx:latest`
|
||||||
|
- `<registry-host>/ctms/ctms-nginx:sha-<short_sha>`
|
||||||
|
|
||||||
|
**Server Requirements**
|
||||||
|
- Docker installed on the Tencent Cloud server.
|
||||||
|
- A private `registry:2` instance listening on `<IP>:5000`.
|
||||||
|
- `htpasswd` authentication configured for the registry.
|
||||||
|
- SSH access from GitHub Actions to the server.
|
||||||
|
- A writable build directory such as `/opt/ctms-build`.
|
||||||
|
|
||||||
|
**GitHub Secrets**
|
||||||
|
- `TCLOUD_HOST`
|
||||||
|
- `TCLOUD_PORT`
|
||||||
|
- `TCLOUD_USER`
|
||||||
|
- `TCLOUD_SSH_KEY`
|
||||||
|
- `REGISTRY_HOST`
|
||||||
|
- `REGISTRY_USERNAME`
|
||||||
|
- `REGISTRY_PASSWORD`
|
||||||
|
|
||||||
|
**Compose Integration**
|
||||||
|
- `docker-compose.yaml` should define `image:` for `backend`, `backend-init`, and `nginx`, with defaults based on private registry variables such as `REGISTRY_HOST`.
|
||||||
|
- Existing `build:` blocks stay in place so local `docker compose up -d --build` continues to work.
|
||||||
|
- Deployment hosts can export `REGISTRY_HOST`, then run `docker login`, `docker compose pull`, `docker compose run --rm backend-init`, and `docker compose up -d`.
|
||||||
|
|
||||||
|
**Operational Notes**
|
||||||
|
- This design assumes the server-local script runs on the same machine that can log in to the private registry reliably.
|
||||||
|
- The GitHub workflow should not embed long shell logic inline; the repository should own a script under `scripts/` so the build logic stays versioned and testable.
|
||||||
|
- Direct verification of actual image publication depends on GitHub Actions reaching the Tencent Cloud server and cannot be proven locally without those secrets and network access.
|
||||||
|
|
||||||
|
**Verification**
|
||||||
|
- Push to `dev` and confirm both images appear with `dev-latest` and `dev-<short_sha>`.
|
||||||
|
- Push to `release` and confirm both images appear with `rc-release` and `rc-<short_sha>`.
|
||||||
|
- Push to `release/*` and confirm both images appear with `rc-<release-branch>` and `rc-<short_sha>`.
|
||||||
|
- Push to `main` and confirm both images appear with `latest` and `sha-<short_sha>`.
|
||||||
|
- Run `docker compose config` after compose changes and confirm the private registry defaults render correctly.
|
||||||
|
- Parse the workflow YAML successfully and inspect the remote build script for the expected tag logic and registry login behavior.
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
# Tencent Cloud Private Registry Implementation Plan
|
||||||
|
|
||||||
|
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||||
|
|
||||||
|
**Goal:** Add CI that triggers remote builds on a Tencent Cloud CVM and pushes private `backend` and `nginx` images into a self-hosted Docker Registry protected by `htpasswd`, for `dev`, `release`, `release/*`, and `main`.
|
||||||
|
|
||||||
|
**Architecture:** GitHub Actions runs on pushes to `dev`, `release`, `release/*`, and `main`, connects to the Tencent Cloud server over SSH, syncs the repository into a fixed build directory, and invokes a repository-owned shell script that logs in to the private registry, builds the images locally on the server, tags them according to branch, and pushes them.
|
||||||
|
|
||||||
|
**Tech Stack:** GitHub Actions, SSH, Docker, self-hosted `registry:2`, Docker Compose, FastAPI, Nginx
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 1: Replace GHCR Workflow with Tencent Registry Publish Workflow
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `.github/workflows/publish-images.yml`
|
||||||
|
|
||||||
|
**Step 1: Define push triggers and remote execution secrets**
|
||||||
|
|
||||||
|
Ensure the workflow triggers on pushes to `dev`, `release`, `release/*`, and `main`, and uses repository secrets for SSH host, port, user, SSH key, registry host, registry username, and registry password.
|
||||||
|
|
||||||
|
**Step 2: Sync repository content to the Tencent Cloud server**
|
||||||
|
|
||||||
|
Use an SSH-capable action or shell step to create the remote build directory and copy the current repository contents into `/opt/ctms-build/<repo>`.
|
||||||
|
|
||||||
|
**Step 3: Invoke the remote publish script**
|
||||||
|
|
||||||
|
Run the repository-owned remote script over SSH with environment values for:
|
||||||
|
- branch name
|
||||||
|
- commit SHA
|
||||||
|
- registry host
|
||||||
|
- registry credentials
|
||||||
|
|
||||||
|
**Step 4: Verify workflow structure**
|
||||||
|
|
||||||
|
Run: `ruby -e 'require "yaml"; YAML.load_file(".github/workflows/publish-images.yml")'`
|
||||||
|
Expected: PASS
|
||||||
|
|
||||||
|
### Task 2: Add Remote Build-And-Push Script
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `scripts/build-and-push-registry.sh`
|
||||||
|
|
||||||
|
**Step 1: Implement branch-aware tag logic**
|
||||||
|
|
||||||
|
For `dev`, compute:
|
||||||
|
- `dev-latest`
|
||||||
|
- `dev-<short_sha>`
|
||||||
|
|
||||||
|
For `release`, compute:
|
||||||
|
- `rc-release`
|
||||||
|
- `rc-<short_sha>`
|
||||||
|
|
||||||
|
For `release/*`, compute:
|
||||||
|
- `rc-<release-branch>`
|
||||||
|
- `rc-<short_sha>`
|
||||||
|
|
||||||
|
For `main`, compute:
|
||||||
|
- `latest`
|
||||||
|
- `sha-<short_sha>`
|
||||||
|
|
||||||
|
Fail fast for unsupported branches.
|
||||||
|
|
||||||
|
**Step 2: Implement registry login and image builds**
|
||||||
|
|
||||||
|
Log in to `${REGISTRY_HOST}` using the supplied username and password, then build:
|
||||||
|
- `${REGISTRY_HOST}/ctms/ctms-backend`
|
||||||
|
- `${REGISTRY_HOST}/ctms/ctms-nginx`
|
||||||
|
|
||||||
|
**Step 3: Push both tags for both images**
|
||||||
|
|
||||||
|
Push every computed tag explicitly so the branch and immutable tags are both published.
|
||||||
|
|
||||||
|
**Step 4: Verify script syntax**
|
||||||
|
|
||||||
|
Run: `bash -n scripts/build-and-push-registry.sh`
|
||||||
|
Expected: PASS
|
||||||
|
|
||||||
|
### Task 3: Point Compose Defaults at the Private Registry
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `docker-compose.yaml`
|
||||||
|
|
||||||
|
**Step 1: Replace GHCR defaults with private registry defaults**
|
||||||
|
|
||||||
|
Set:
|
||||||
|
- `backend.image` to `${BACKEND_IMAGE:-${REGISTRY_HOST:-127.0.0.1:5000}/ctms/ctms-backend:latest}`
|
||||||
|
- `backend-init.image` to `${BACKEND_IMAGE:-${REGISTRY_HOST:-127.0.0.1:5000}/ctms/ctms-backend:latest}`
|
||||||
|
- `nginx.image` to `${NGINX_IMAGE:-${REGISTRY_HOST:-127.0.0.1:5000}/ctms/ctms-nginx:latest}`
|
||||||
|
|
||||||
|
Keep the current `build:` blocks intact.
|
||||||
|
|
||||||
|
**Step 2: Verify rendered compose**
|
||||||
|
|
||||||
|
Run: `docker compose config`
|
||||||
|
Expected: PASS with private registry image defaults rendered.
|
||||||
|
|
||||||
|
### Task 4: Update Deployment Documentation
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `README.md`
|
||||||
|
- Modify: `docs/guides/release-checklist.md`
|
||||||
|
|
||||||
|
**Step 1: Document the Tencent registry flow**
|
||||||
|
|
||||||
|
Explain that GitHub Actions triggers remote builds on the Tencent Cloud server and publishes to the private registry at `<IP>:5000`.
|
||||||
|
|
||||||
|
**Step 2: Document deployment commands**
|
||||||
|
|
||||||
|
Show that deployment hosts must run:
|
||||||
|
- `docker login <IP>:5000`
|
||||||
|
- `docker compose pull`
|
||||||
|
- `docker compose run --rm backend-init`
|
||||||
|
- `docker compose up -d`
|
||||||
|
|
||||||
|
**Step 3: Update release checklist**
|
||||||
|
|
||||||
|
Add checks for remote publish success on `dev`, `release`, `release/*`, and `main`, and for deployment-host registry authentication.
|
||||||
|
|
||||||
|
### Task 5: End-To-End Local Verification
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Verify only
|
||||||
|
|
||||||
|
**Step 1: Parse the workflow YAML**
|
||||||
|
|
||||||
|
Run: `ruby -e 'require "yaml"; YAML.load_file(".github/workflows/publish-images.yml")'`
|
||||||
|
Expected: PASS
|
||||||
|
|
||||||
|
**Step 2: Verify script syntax**
|
||||||
|
|
||||||
|
Run: `bash -n scripts/build-and-push-registry.sh`
|
||||||
|
Expected: PASS
|
||||||
|
|
||||||
|
**Step 3: Render compose**
|
||||||
|
|
||||||
|
Run: `docker compose config`
|
||||||
|
Expected: PASS
|
||||||
|
|
||||||
|
**Step 4: Inspect documentation**
|
||||||
|
|
||||||
|
Run: `sed -n '1,120p' README.md`
|
||||||
|
Expected: PASS with Tencent private registry deployment steps present.
|
||||||
|
|
||||||
|
Run: `sed -n '1,120p' docs/guides/release-checklist.md`
|
||||||
|
Expected: PASS with private registry release verification present.
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
required_vars=(
|
||||||
|
BRANCH_NAME
|
||||||
|
COMMIT_SHA
|
||||||
|
REGISTRY_HOST
|
||||||
|
REGISTRY_USERNAME
|
||||||
|
REGISTRY_PASSWORD
|
||||||
|
)
|
||||||
|
|
||||||
|
for var_name in "${required_vars[@]}"; do
|
||||||
|
if [[ -z "${!var_name:-}" ]]; then
|
||||||
|
echo "Missing required environment variable: ${var_name}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
short_sha="${COMMIT_SHA:0:7}"
|
||||||
|
|
||||||
|
case "${BRANCH_NAME}" in
|
||||||
|
dev)
|
||||||
|
mutable_tag="dev-latest"
|
||||||
|
immutable_tag="dev-${short_sha}"
|
||||||
|
;;
|
||||||
|
release)
|
||||||
|
mutable_tag="rc-release"
|
||||||
|
immutable_tag="rc-${short_sha}"
|
||||||
|
;;
|
||||||
|
release/*)
|
||||||
|
release_name="${BRANCH_NAME#release/}"
|
||||||
|
release_slug="${release_name//\//-}"
|
||||||
|
mutable_tag="rc-${release_slug}"
|
||||||
|
immutable_tag="rc-${short_sha}"
|
||||||
|
;;
|
||||||
|
main)
|
||||||
|
mutable_tag="latest"
|
||||||
|
immutable_tag="sha-${short_sha}"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unsupported branch for publishing: ${BRANCH_NAME}" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
backend_image="${REGISTRY_HOST}/ctms/ctms-backend"
|
||||||
|
nginx_image="${REGISTRY_HOST}/ctms/ctms-nginx"
|
||||||
|
|
||||||
|
echo "${REGISTRY_PASSWORD}" | docker login "${REGISTRY_HOST}" --username "${REGISTRY_USERNAME}" --password-stdin
|
||||||
|
|
||||||
|
docker build \
|
||||||
|
-t "${backend_image}:${mutable_tag}" \
|
||||||
|
-t "${backend_image}:${immutable_tag}" \
|
||||||
|
./backend
|
||||||
|
|
||||||
|
docker build \
|
||||||
|
-t "${nginx_image}:${mutable_tag}" \
|
||||||
|
-t "${nginx_image}:${immutable_tag}" \
|
||||||
|
-f ./nginx/Dockerfile \
|
||||||
|
.
|
||||||
|
|
||||||
|
docker push "${backend_image}:${mutable_tag}"
|
||||||
|
docker push "${backend_image}:${immutable_tag}"
|
||||||
|
docker push "${nginx_image}:${mutable_tag}"
|
||||||
|
docker push "${nginx_image}:${immutable_tag}"
|
||||||
Reference in New Issue
Block a user