mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-27 21:07:01 -06:00
ci: make locale parity advisory before release (#105140)
This commit is contained in:
committed by
GitHub
parent
c0496ea96d
commit
91ca35ba58
@@ -827,10 +827,6 @@ jobs:
|
||||
NODE_OPTIONS: --max-old-space-size=8192
|
||||
run: pnpm build:ci-artifacts
|
||||
|
||||
- name: Check Control UI i18n
|
||||
if: needs.preflight.outputs.run_control_ui_i18n == 'true'
|
||||
run: pnpm ui:i18n:check
|
||||
|
||||
- name: Pack built runtime artifacts
|
||||
run: tar --posix -cf dist-runtime-build.tar.zst --use-compress-program zstdmt dist dist-runtime packages/*/dist
|
||||
|
||||
@@ -1065,6 +1061,28 @@ jobs:
|
||||
pnpm --dir ui test
|
||||
fi
|
||||
|
||||
control-ui-i18n:
|
||||
permissions:
|
||||
contents: read
|
||||
name: control-ui-i18n
|
||||
needs: [preflight]
|
||||
if: needs.preflight.outputs.run_control_ui_i18n == 'true'
|
||||
# Locale refresh runs separately on main and nightly. Keep drift visible on
|
||||
# automatic runs without blocking unrelated work; release CI stays strict.
|
||||
continue-on-error: ${{ github.event_name != 'workflow_dispatch' }}
|
||||
runs-on: ${{ github.event_name == 'workflow_dispatch' && 'ubuntu-24.04' || (github.repository == 'openclaw/openclaw' && 'blacksmith-4vcpu-ubuntu-2404' || 'ubuntu-24.04') }}
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- *linux_node_checkout_step
|
||||
- name: Setup Node environment
|
||||
uses: ./.github/actions/setup-node-env
|
||||
with:
|
||||
node-version: "24.x"
|
||||
install-bun: "false"
|
||||
|
||||
- name: Check Control UI locale parity
|
||||
run: pnpm ui:i18n:check
|
||||
|
||||
checks-fast-core:
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -1677,7 +1695,6 @@ jobs:
|
||||
env:
|
||||
ADDITIONAL_CHECK_GROUP: ${{ matrix.group }}
|
||||
OPENCLAW_ADDITIONAL_BOUNDARY_SHARD: ${{ matrix.boundary_shard || '' }}
|
||||
RUN_CONTROL_UI_I18N: ${{ needs.preflight.outputs.run_control_ui_i18n }}
|
||||
OPENCLAW_ADDITIONAL_BOUNDARY_CONCURRENCY: 4
|
||||
OPENCLAW_EXTENSION_BOUNDARY_CONCURRENCY: 6
|
||||
shell: bash
|
||||
@@ -2461,6 +2478,7 @@ jobs:
|
||||
- pnpm-store-warmup
|
||||
- build-artifacts
|
||||
- checks-ui
|
||||
- control-ui-i18n
|
||||
- checks-fast-core
|
||||
- checks-fast-plugin-contracts-shard
|
||||
- checks-fast-channel-contracts-shard
|
||||
|
||||
+5
-2
@@ -32,6 +32,7 @@ dispatch.
|
||||
| `security-fast` | Private key detection, changed-workflow audit via `zizmor`, and production lockfile audit | Always on non-draft pushes and PRs |
|
||||
| `pnpm-store-warmup` | Warm the lockfile-pinned pnpm store cache without blocking Linux Node shards | Node or docs-check lanes selected |
|
||||
| `build-artifacts` | Build `dist/`, Control UI, built-CLI smoke checks, startup memory, and embedded built-artifact checks | Node-relevant changes |
|
||||
| `control-ui-i18n` | Verify generated Control UI locale bundles, metadata, and translation memory; advisory on automatic runs, blocking on manual release CI | Control UI i18n-relevant changes and manual CI |
|
||||
| `checks-fast-core` | Fast Linux correctness lanes: bundled + protocol, Bun launcher, and the CI-routing fast task | Node-relevant changes |
|
||||
| `qa-smoke-ci-profile` | Two self-contained balanced parts of the bounded automatic QA Smoke representative set; full taxonomy coverage remains available through explicit QA profiles | Node-relevant changes |
|
||||
| `checks-fast-contracts-plugins-*` | Two weighted plugin contract shards | Node-relevant changes |
|
||||
@@ -56,7 +57,7 @@ dispatch.
|
||||
1. `runner-admission` waits only for canonical `main` pushes; a newer push cancels the run before Blacksmith registration.
|
||||
2. `preflight` decides which lanes exist at all. The `docs-scope` and `changed-scope` logic are steps inside this job, not standalone jobs.
|
||||
3. `security-fast`, `check-*`, `check-additional-*`, `check-docs`, and `skills-python` fail quickly without waiting on the heavier artifact and platform matrix jobs.
|
||||
4. `build-artifacts` overlaps with the fast Linux lanes so downstream consumers can start as soon as the shared build is ready.
|
||||
4. `build-artifacts` and the advisory `control-ui-i18n` check overlap with the fast Linux lanes. Generated locale drift stays visible while the standalone refresh workflow repairs it in the background.
|
||||
5. Heavier platform and runtime lanes fan out after that: `checks-fast-core`, `checks-fast-contracts-plugins-*`, `checks-fast-contracts-channels-*`, `checks-node-*`, `checks-windows`, `macos-node`, `macos-swift`, `ios-build`, and `android`.
|
||||
|
||||
GitHub may mark superseded jobs as `cancelled` when a newer push lands on the same PR or `main` ref. Treat that as CI noise unless the newest run for the same ref is also failing. Matrix jobs use `fail-fast: false`, and `build-artifacts` reports embedded channel, core-support-boundary, and gateway-watch failures directly instead of queuing tiny verifier jobs. The automatic CI concurrency key is versioned (`CI-v7-*`) so a GitHub-side zombie in an old queue group cannot indefinitely block newer main runs. Manual full-suite runs use `CI-manual-v1-*` and do not cancel in-progress runs. The plugin-list startup-memory guard keeps a 350 MiB ceiling on self-hosted Blacksmith Linux and allows 425 MiB on GitHub-hosted Linux, whose RSS baseline is higher for the same built CLI.
|
||||
@@ -131,7 +132,7 @@ Treat GitHub titles, comments, bodies, review text, branch names, and commit mes
|
||||
|
||||
## Manual dispatches
|
||||
|
||||
Manual CI dispatches run the same job graph as normal CI but force every non-Android scoped lane on: Linux Node shards, bundled-plugin shards, plugin and channel contract shards, Node 22 compatibility, `check-*`, `check-additional-*`, built-artifact smoke checks, docs checks, Python skills, Windows, macOS, iOS build, and Control UI i18n. Standalone manual CI dispatches run Android only with `include_android=true` (the `release_gate` input also forces Android); the full release umbrella enables Android by passing `include_android=true`. Plugin prerelease static checks, the release-only `agentic-plugins` shard, the full extension batch sweep, and plugin prerelease Docker lanes are excluded from CI. The Docker prerelease suite runs only when `Full Release Validation` dispatches the separate `Plugin Prerelease` workflow with the release-validation gate enabled.
|
||||
Manual CI dispatches run the same job graph as normal CI but force every non-Android scoped lane on: Linux Node shards, bundled-plugin shards, plugin and channel contract shards, Node 22 compatibility, `check-*`, `check-additional-*`, built-artifact smoke checks, docs checks, Python skills, Windows, macOS, iOS build, and Control UI i18n. Control UI locale parity is advisory on automatic PR and `main` runs because the standalone refresh workflow repairs generated drift in the background; it is blocking on manual CI and therefore on Full Release Validation. Standalone manual CI dispatches run Android only with `include_android=true` (the `release_gate` input also forces Android); the full release umbrella enables Android by passing `include_android=true`. Plugin prerelease static checks, the release-only `agentic-plugins` shard, the full extension batch sweep, and plugin prerelease Docker lanes are excluded from CI. The Docker prerelease suite runs only when `Full Release Validation` dispatches the separate `Plugin Prerelease` workflow with the release-validation gate enabled.
|
||||
|
||||
Manual runs use a unique concurrency group so a release-candidate full suite is not cancelled by another push or PR run on the same ref. The optional `target_ref` input lets a trusted caller run that graph against a branch, tag, or full commit SHA while using the workflow file from the selected dispatch ref. The `release_gate` input is an exact-SHA maintainer fallback for capacity-stalled PR CI: it requires `target_ref` to be a full commit SHA that matches the dispatched branch head.
|
||||
|
||||
@@ -196,6 +197,8 @@ pnpm test:gateway:watch-regression
|
||||
OPENCLAW_TUI_PTY_INCLUDE_LOCAL=1 node scripts/run-vitest.mjs run --config test/vitest/vitest.tui-pty.config.ts
|
||||
pnpm test # vitest tests
|
||||
pnpm test:changed # cheap smart changed Vitest targets
|
||||
pnpm test:ui # Control UI unit/browser suite
|
||||
pnpm ui:i18n:check # generated Control UI locale parity (release gate)
|
||||
pnpm test:channels
|
||||
pnpm test:contracts:channels
|
||||
pnpm check:docs # docs format + lint + broken links
|
||||
|
||||
+1
-1
@@ -1952,7 +1952,7 @@
|
||||
"test:startup:gateway": "node --import tsx scripts/bench-gateway-startup.ts",
|
||||
"test:restart:gateway": "node --import tsx scripts/bench-gateway-restart.ts",
|
||||
"test:startup:memory": "node scripts/ensure-cli-startup-build.mjs && node scripts/check-cli-startup-memory.mjs",
|
||||
"test:ui": "pnpm ui:i18n:check && pnpm lint:ui:no-raw-window-open && node scripts/ensure-playwright-chromium.mjs && pnpm --dir ui test",
|
||||
"test:ui": "pnpm lint:ui:no-raw-window-open && node scripts/ensure-playwright-chromium.mjs && pnpm --dir ui test",
|
||||
"test:ui:e2e": "node scripts/ensure-playwright-chromium.mjs && node scripts/run-vitest.mjs run --config test/vitest/vitest.ui-e2e.config.ts --configLoader runner",
|
||||
"test:unit": "pnpm test:unit:fast && node scripts/run-vitest.mjs run --config test/vitest/vitest.unit.config.ts",
|
||||
"test:unit:fast": "node scripts/run-vitest.mjs run --config test/vitest/vitest.unit-fast.config.ts",
|
||||
|
||||
@@ -1915,6 +1915,34 @@ describe("ci workflow guards", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps Control UI locale parity advisory until release CI", () => {
|
||||
const workflow = readCiWorkflow();
|
||||
const workflowSource = readFileSync(".github/workflows/ci.yml", "utf8");
|
||||
const buildArtifactSteps = workflow.jobs["build-artifacts"].steps;
|
||||
const localeJob = workflow.jobs["control-ui-i18n"];
|
||||
const localeStep = localeJob.steps.find(
|
||||
(step: WorkflowStep) => step.name === "Check Control UI locale parity",
|
||||
);
|
||||
|
||||
expect(buildArtifactSteps).not.toContainEqual(
|
||||
expect.objectContaining({ run: "pnpm ui:i18n:check" }),
|
||||
);
|
||||
expect(JSON.parse(readFileSync("package.json", "utf8")).scripts["test:ui"]).not.toContain(
|
||||
"ui:i18n:check",
|
||||
);
|
||||
expect(workflowSource.match(/pnpm ui:i18n:check/gu)).toHaveLength(1);
|
||||
expect(readFileSync("ui/src/i18n/test/translate.test.ts", "utf8")).not.toContain(
|
||||
"keeps shipped locales structurally aligned with English",
|
||||
);
|
||||
expect(localeJob.needs).toEqual(["preflight"]);
|
||||
expect(localeJob.if).toBe("needs.preflight.outputs.run_control_ui_i18n == 'true'");
|
||||
expect(localeJob["continue-on-error"]).toBe("${{ github.event_name != 'workflow_dispatch' }}");
|
||||
expect(localeStep.run).toBe("pnpm ui:i18n:check");
|
||||
expect(readFileSync(".github/workflows/full-release-validation.yml", "utf8")).toContain(
|
||||
'dispatch_and_wait ci.yml "$dispatch_run_name"',
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps the hosted plugin-list memory allowance scoped to GitHub-hosted runners", () => {
|
||||
const workflow = readCiWorkflow();
|
||||
const startupMemoryStep = workflow.jobs["build-artifacts"].steps.find(
|
||||
@@ -2077,6 +2105,7 @@ describe("ci workflow guards", () => {
|
||||
"pnpm-store-warmup",
|
||||
"build-artifacts",
|
||||
"checks-ui",
|
||||
"control-ui-i18n",
|
||||
"checks-fast-core",
|
||||
"checks-fast-plugin-contracts-shard",
|
||||
"checks-fast-channel-contracts-shard",
|
||||
|
||||
@@ -227,13 +227,4 @@ describe("i18n", () => {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it("keeps shipped locales structurally aligned with English", () => {
|
||||
const englishKeys = flatten(en);
|
||||
for (const [locale, value] of Object.entries(shippedLocales)) {
|
||||
expect(flatten(value as Record<string, string | Record<string, unknown>>), locale).toEqual(
|
||||
englishKeys,
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user