mirror of
https://github.com/zyycn/codex-proxy-rs.git
synced 2026-11-06 16:06:08 +00:00
Allow staged or unstaged release notes and commit their final contents with the version update before tagging. Continue rejecting unrelated tracked changes and require notes to remain uncommitted. Update the release skill, skip duplicate push CI for release metadata alone, and check the publish script syntax in CI. Validated publication behavior in temporary Git repositories, Bash syntax, and Actionlint. Co-authored-by: Codex <noreply@openai.com>
211 lines
7.6 KiB
YAML
211 lines
7.6 KiB
YAML
name: Reusable Quality
|
|
|
|
on:
|
|
workflow_call:
|
|
inputs:
|
|
ref:
|
|
description: Exact commit SHA to validate
|
|
required: true
|
|
type: string
|
|
upload_frontend:
|
|
description: Upload the built frontend for release jobs
|
|
required: false
|
|
default: false
|
|
type: boolean
|
|
run_backend:
|
|
description: Run backend quality checks
|
|
required: false
|
|
default: true
|
|
type: boolean
|
|
run_frontend:
|
|
description: Run frontend quality checks
|
|
required: false
|
|
default: true
|
|
type: boolean
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
backend:
|
|
if: inputs.run_backend
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 30
|
|
env:
|
|
CARGO_TERM_COLOR: always
|
|
# Rust 1.97 编译 AWS SDK 调试信息需要更大的 codegen 线程栈。
|
|
RUST_MIN_STACK: 16777216
|
|
CPR_TEST_DATABASE_URL: postgres://codex_proxy:codex_proxy@127.0.0.1:5432/codex_proxy
|
|
CPR_TEST_REDIS_URL: redis://127.0.0.1:6379
|
|
services:
|
|
postgres:
|
|
image: postgres:18-bookworm@sha256:d9c83446333daec3f0588cc709adb80c26090b7f9f0f7ec8d43c243385d79818
|
|
env:
|
|
POSTGRES_DB: codex_proxy
|
|
POSTGRES_USER: codex_proxy
|
|
POSTGRES_PASSWORD: codex_proxy
|
|
POSTGRES_INITDB_ARGS: --auth-local=scram-sha-256 --auth-host=scram-sha-256
|
|
ports:
|
|
- 5432:5432
|
|
options: >-
|
|
--health-cmd "pg_isready -U codex_proxy -d codex_proxy"
|
|
--health-interval 5s
|
|
--health-timeout 5s
|
|
--health-retries 10
|
|
redis:
|
|
image: redis:8-alpine@sha256:9d317178eceac8454a2284a9e6df2466b93c745529947f0cd42a0fa9609d7005
|
|
ports:
|
|
- 6379:6379
|
|
options: >-
|
|
--health-cmd "redis-cli ping"
|
|
--health-interval 5s
|
|
--health-timeout 5s
|
|
--health-retries 10
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
ref: ${{ inputs.ref }}
|
|
# PR 场景需要 base 提交做冻结清单的 append-only 比对。
|
|
fetch-depth: ${{ github.event_name == 'pull_request' && 0 || 1 }}
|
|
|
|
# 已应用迁移的字节被 sqlx 启动校验钉死:改动已发布迁移会让所有
|
|
# 存量部署重启即失败。冻结清单保证旧文件不被改、新文件必须入册。
|
|
- name: Migration freeze check
|
|
working-directory: backend/migrations
|
|
shell: bash
|
|
env:
|
|
BASE_SHA: ${{ github.event.pull_request.base.sha }}
|
|
run: |
|
|
set -euo pipefail
|
|
sha256sum --check --strict .frozen-sha256
|
|
for file in *.sql; do
|
|
if ! awk '{print $2}' .frozen-sha256 | grep -Fxq "$file"; then
|
|
echo "::error file=backend/migrations/$file::migration $file is not frozen; append its sha256 to backend/migrations/.frozen-sha256"
|
|
exit 1
|
|
fi
|
|
done
|
|
# 清单自证不足以防「改迁移 + 同 PR 刷新清单行」:校验对新哈希通过。
|
|
# 对 PR,断言 .frozen-sha256 相对 base 只增不改——base 里的每一行
|
|
# 必须原样保留(改哈希=删行,删迁移=删行,都会被挡)。
|
|
if [ -n "${BASE_SHA:-}" ]; then
|
|
base_manifest="$(git show "${BASE_SHA}:backend/migrations/.frozen-sha256" 2>/dev/null || true)"
|
|
if [ -n "$base_manifest" ]; then
|
|
while IFS= read -r line; do
|
|
[ -z "$line" ] && continue
|
|
if ! grep -Fxq "$line" .frozen-sha256; then
|
|
file="$(printf '%s' "$line" | awk '{print $2}')"
|
|
echo "::error file=backend/migrations/.frozen-sha256::frozen migration $file was modified or removed; released migrations are append-only — add a new numbered migration instead"
|
|
exit 1
|
|
fi
|
|
done <<< "$base_manifest"
|
|
fi
|
|
fi
|
|
|
|
- name: Setup Rust
|
|
uses: dtolnay/rust-toolchain@1a3a6d54512beeaffd394f8d516ca16f2c506a20 # 1.97
|
|
with:
|
|
components: rustfmt,clippy
|
|
|
|
- name: Cache Rust
|
|
uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
|
|
with:
|
|
workspaces: backend -> target
|
|
|
|
- name: Rust format
|
|
working-directory: backend
|
|
run: cargo fmt --check
|
|
|
|
- name: Rust clippy
|
|
working-directory: backend
|
|
run: cargo clippy --all-targets --all-features --locked -- -D warnings
|
|
|
|
- name: Configure PostgreSQL and Redis test authentication
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
postgres_password="$(openssl rand -hex 24)"
|
|
redis_password="$(openssl rand -hex 24)"
|
|
echo "::add-mask::$postgres_password"
|
|
echo "::add-mask::$redis_password"
|
|
docker exec --env PGPASSWORD=codex_proxy "${{ job.services.postgres.id }}" psql \
|
|
--username=codex_proxy --dbname=codex_proxy \
|
|
--set=ON_ERROR_STOP=1 \
|
|
--command="ALTER USER codex_proxy WITH PASSWORD '${postgres_password}'" >/dev/null
|
|
docker exec --env PGPASSWORD="$postgres_password" "${{ job.services.postgres.id }}" psql \
|
|
--username=codex_proxy --dbname=codex_proxy \
|
|
--set=ON_ERROR_STOP=1 --command='SELECT 1' >/dev/null
|
|
docker exec "${{ job.services.redis.id }}" redis-cli CONFIG SET requirepass "$redis_password" >/dev/null
|
|
docker exec "${{ job.services.redis.id }}" redis-cli --no-auth-warning -a "$redis_password" ping >/dev/null
|
|
{
|
|
echo "CPR_TEST_DATABASE_URL=postgres://codex_proxy:${postgres_password}@127.0.0.1:5432/codex_proxy"
|
|
echo "CPR_TEST_REDIS_URL=redis://:${redis_password}@127.0.0.1:6379"
|
|
} >> "$GITHUB_ENV"
|
|
|
|
- name: Rust tests
|
|
working-directory: backend
|
|
run: cargo test --test main --locked
|
|
|
|
frontend:
|
|
if: inputs.run_frontend
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 15
|
|
env:
|
|
CI: 'true'
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
ref: ${{ inputs.ref }}
|
|
|
|
- name: Setup pnpm
|
|
uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
|
|
with:
|
|
version: 11.7.0
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
with:
|
|
node-version: 24
|
|
cache: pnpm
|
|
cache-dependency-path: frontend/pnpm-lock.yaml
|
|
|
|
- name: Install frontend dependencies
|
|
run: pnpm --dir frontend install --frozen-lockfile
|
|
|
|
- name: Frontend format
|
|
run: pnpm --dir frontend format:check
|
|
|
|
- name: Frontend build
|
|
run: pnpm --dir frontend build
|
|
|
|
- name: Upload frontend artifact
|
|
if: inputs.upload_frontend
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: frontend-dist
|
|
path: frontend/dist
|
|
if-no-files-found: error
|
|
retention-days: 1
|
|
|
|
workflow-lint:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 5
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
ref: ${{ inputs.ref }}
|
|
|
|
- name: Lint GitHub Actions workflows
|
|
run: >-
|
|
docker run --rm
|
|
--volume "$PWD:/repo"
|
|
--workdir /repo
|
|
rhysd/actionlint:1.7.7@sha256:887a259a5a534f3c4f36cb02dca341673c6089431057242cdc931e9f133147e9
|
|
-color
|
|
.github/workflows/*.yml
|
|
|
|
- name: Check release script syntax
|
|
run: bash -n release/publish
|