Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ jobs:
with:
toolchain: stable
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32
- name: bash syntax
run: bash -n scripts/mutation-smoke.sh
- name: cargo fmt
run: cargo fmt --check
- name: cargo clippy
Expand Down
48 changes: 48 additions & 0 deletions .github/workflows/mutation-smoke.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Apollo mutation smoke

on:
workflow_dispatch:
schedule:
- cron: "37 3 * * 1"

concurrency:
group: apollo-cli-mutation-smoke
cancel-in-progress: false

permissions:
contents: read

jobs:
mutation-smoke:
name: Portal + H2 mutation smoke
runs-on: ubuntu-24.04
timeout-minutes: 120
steps:
- name: Check out Apollo CLI
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false

- name: Set up JDK 17
uses: actions/setup-java@cf277c60eb25467037889841efdb72551f06f6c3 # v4
with:
distribution: temurin
java-version: 17

- name: Set up Rust
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8
with:
toolchain: stable

- name: Cache Rust build data
uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32
with:
shared-key: mutation-smoke

- name: Validate smoke script syntax
run: bash -n scripts/mutation-smoke.sh

- name: Run Apollo CLI mutation smoke
env:
CARGO_TERM_COLOR: always
run: ./scripts/mutation-smoke.sh
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ The CLI stores non-secret profile metadata in `config.toml` under the OS config
- Linux: `$XDG_CONFIG_HOME/apollo/config.toml` or `~/.config/apollo/config.toml`
- Windows: `%APPDATA%\apollo\config.toml`

Set `APOLLO_CLI_HOME` to an absolute directory to place `config.toml` and file-backed credentials
there instead. This is intended for isolated CI and smoke runs; normal interactive use should keep
the platform default.

The config file stores:

- `active_profile`
Expand Down Expand Up @@ -431,6 +435,13 @@ those checks pass does it create the `v<version>` tag at the exact workflow comm
notes, verify the complete draft asset set, and publish the Release. Versions containing a SemVer
prerelease suffix are published as prereleases.

Before starting a release, maintainers must also run **Actions → Apollo mutation smoke → Run
workflow** on the intended default-branch commit and require a successful result. The workflow is
also scheduled weekly. It builds a pinned Apollo revision with Portal, ConfigService, AdminService,
and disposable H2 databases, then exercises the real mutation contract described below. The Apollo
pin is deliberately stored in `scripts/mutation-smoke.sh`; update it only as a reviewed source
change.

## Local development

Build the CLI:
Expand All @@ -457,6 +468,26 @@ Run focused OpenAPI command integration tests with the local mock HTTP server:
cargo test --test openapi
```

Run the repeatable real-Portal mutation smoke from a clean checkout (requires Git, curl, jq, awk,
`sha256sum` or `shasum`, JDK 17, and the stable Rust toolchain):

```bash
./scripts/mutation-smoke.sh
```

The command fetches the pinned Apollo revision, builds its single-process assembly, starts Portal +
H2, builds the CLI, creates an isolated `APOLLO_CLI_HOME` profile and disposable app/namespaces, and
validates config diff/apply, confirmation rejection, permission failure, release creation/listing,
and rollback against real server state. Target-only keys are verified as preserved under the merge
contract, and no-op state is compared before and after the command. User tokens and config values
stay in a mode-`0700` temporary directory, failure diagnostics are dynamically redacted, and the
directory and assembly process are always removed. To reuse an already checked-out clean Apollo
tree at the same pinned commit:

```bash
APOLLO_SMOKE_APOLLO_SOURCE=/absolute/path/to/apollo ./scripts/mutation-smoke.sh
```

If you have a local Apollo Portal running, you can also smoke-test against it:

```bash
Expand Down Expand Up @@ -492,3 +523,4 @@ cargo clippy --all-targets --all-features -- -D warnings
- `tests/openapi.rs`: integration coverage for OpenAPI paths, auth headers, and confirmation guards
- `tests/profile.rs`: integration coverage for profile commands and context resolution
- `tests/redaction.rs`: integration coverage for redaction behavior
- `scripts/mutation-smoke.sh`: pinned Apollo Portal + H2 mutation smoke and state assertions
27 changes: 27 additions & 0 deletions README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ CLI 将非敏感 profile 元数据存储在操作系统配置目录下的 `confi
- Linux:`$XDG_CONFIG_HOME/apollo/config.toml` 或 `~/.config/apollo/config.toml`
- Windows:`%APPDATA%\apollo\config.toml`

如需在隔离的 CI 或 smoke 环境中保存 `config.toml` 和文件型凭据,可将
`APOLLO_CLI_HOME` 设置为绝对目录。日常交互式使用仍建议保留平台默认路径。

配置文件会存储:

- `active_profile`
Expand Down Expand Up @@ -357,6 +360,11 @@ checksum 与构建来源证明。全部检查通过后,才会在本次 workflo
`v<version>` tag,自动生成 release notes,核对草稿 Release 的完整附件集合并公开发布。版本中含有
SemVer 预发布后缀时,会发布为 prerelease。

发版前,维护者还必须在目标默认分支 commit 上运行 **Actions → Apollo mutation smoke → Run
workflow**,并确认执行成功;该 workflow 也会每周定时运行。它使用固定 Apollo revision 构建
Portal、ConfigService、AdminService 和一次性 H2 数据库,再执行下文所述的真实变更约定。Apollo
固定 revision 保存在 `scripts/mutation-smoke.sh` 中,更新它必须作为代码变更接受 review。

## 本地开发

构建 CLI:
Expand All @@ -383,6 +391,24 @@ cargo test
cargo test --test openapi
```

从干净 checkout 运行可重复的真实 Portal 变更 smoke(需要 Git、curl、jq、awk、
`sha256sum` 或 `shasum`、JDK 17 和稳定版 Rust 工具链):

```bash
./scripts/mutation-smoke.sh
```

该命令会拉取固定 Apollo revision、构建并启动单进程 Portal + H2 assembly、构建 CLI、创建隔离的
`APOLLO_CLI_HOME` profile 和一次性 app/namespace,并基于真实服务端状态验证 config diff/apply、
缺少确认时拒绝、权限失败、release 创建/列表以及回滚。测试会确认保守合并保留目标端独有 key,
并比较 no-op 前后的完整目标状态。User token 和配置值只保存在权限为 `0700` 的临时目录中,失败
诊断会动态脱敏,assembly 进程与临时目录始终会被清理。若本地已有同一固定 commit 的干净 Apollo
checkout,可以复用:

```bash
APOLLO_SMOKE_APOLLO_SOURCE=/absolute/path/to/apollo ./scripts/mutation-smoke.sh
```

如果本地运行了 Apollo Portal,也可以直接对它做 smoke test:

```bash
Expand Down Expand Up @@ -418,3 +444,4 @@ cargo clippy --all-targets --all-features -- -D warnings
- `tests/openapi.rs`:OpenAPI path、鉴权 header 和确认保护的集成覆盖
- `tests/profile.rs`:profile 命令和上下文解析的集成覆盖
- `tests/redaction.rs`:脱敏行为的集成覆盖
- `scripts/mutation-smoke.sh`:固定 Apollo Portal + H2 变更 smoke 与状态断言
Loading
Loading