620 Commits
Author SHA1 Message Date
discord9 ee9ad87fa1 Merge upstream/main into narthex (pre-merge rehearsal, not for push)
Rehearsal merge of main (f8d8fe1071) into narthex (115d85b669) on a throwaway
local branch. 31 semantic conflicts resolved; workspace and all test targets
compile; promql 1215/1215 and mito2 series_index 185/185 pass.

Pre-merge pins and follow-ups are marked with TODO(narthex-merge):
- greptime-proto is temporarily pinned to the fork branch carrying
  GreptimeTeam/greptime-proto#355; replace with the upstream rev once it lands.
- native payload byte cache is disabled (main removed PageRangeCache); two
  samples tests are #[ignore]d until it gets a dedicated page-cache budget.
- columnar metadata now has its own CacheManager tier (a quarter of
  sst_meta_cache_size); the unified decoded tier was not kept.
- query.experimental_native_promql is registered as a query option, otherwise
  the native route is silently rejected by the option snapshot.

Signed-off-by: discord9 <discord9@163.com>
2026-11-12 15:45:04 +08:00
Weny Xu c85a92ac57 ci: add Prometheus and align Traces benchmark artifact auditing (#10188)
* ci: add Prometheus to the long-range metrics benchmark

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: validate Prometheus with the File/S3 benchmark runtime

Signed-off-by: WenyXu <wenymedia@gmail.com>

* fix(ci): allow recorded partial Traces query results in artifact audit

Signed-off-by: WenyXu <wenymedia@gmail.com>

---------

Signed-off-by: WenyXu <wenymedia@gmail.com>
2026-11-06 18:19:49 +00:00
Weny Xu bba6818c38 fix(ci): honor configured region in metric snapshot benchmark (#10157)
* fix(ci): honor configured region in metric snapshot benchmark

Signed-off-by: WenyXu <wenymedia@gmail.com>

* docs(ci): clarify AWS runner region configuration

Include the documentation changes from #10158 alongside the region fix.

Signed-off-by: Weny Xu <wenymedia@gmail.com>

---------

Signed-off-by: WenyXu <wenymedia@gmail.com>
Signed-off-by: Weny Xu <wenymedia@gmail.com>
2026-11-06 04:06:14 +00:00
Weny Xu 5bcb576b49 ci: compare GreptimeDB File and S3 in observability benchmarks (#10187)
* ci: compare GreptimeDB File and S3 in observability benchmarks

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: separate File and S3 benchmark steps and verify report artifacts

Signed-off-by: WenyXu <wenymedia@gmail.com>

---------

Signed-off-by: WenyXu <wenymedia@gmail.com>
2026-11-05 18:19:56 +00:00
Weny Xu c02e1f58af fix(ci): prepare Ubuntu build runners and default EC2 disks to 500 GiB (#10156)
* ci: share Linux runner dependency setup for builds and benchmarks

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: configure EC2 build runner volumes with a 500 GiB default

Signed-off-by: WenyXu <wenymedia@gmail.com>

---------

Signed-off-by: WenyXu <wenymedia@gmail.com>
2026-11-05 02:40:14 +00:00
LFC e80cf9a9ae fix(ci): increase nightly JSONBench runner root volume (#10146)
Signed-off-by: luofucong <luofc@foxmail.com>
2026-11-04 08:23:09 +00:00
liyang f58d598ca7 chore(ci): use standard AWS secrets in CI workflows (#10116) 2026-11-03 10:42:50 +00:00
Weny Xu eef2d58a48 fix(ci): skip unsupported stacked PRs in nightly merge (#10063)
Signed-off-by: WenyXu <wenymedia@gmail.com>
2026-11-02 18:19:28 +00:00
dennis zhuang 00b2c57c0a docs: link the observability database definition from README (#10061)
* docs: link the observability database definition from README

Signed-off-by: Dennis Zhuang <killme2008@gmail.com>

* ci: add the new required checks to the Docs CI placeholders

The main ruleset now requires five more checks. Their workflows skip
docs-only PRs via paths-ignore, so without placeholders those PRs can
never satisfy the required checks.

Signed-off-by: Dennis Zhuang <killme2008@gmail.com>

---------

Signed-off-by: Dennis Zhuang <killme2008@gmail.com>
2026-10-31 15:38:08 +00:00
zhaiAohan 8a38b90135 feat: add relational region engine skeleton and registration (#9953)
* feat: add relational region engine skeleton and registration

Add a read-only relational RegionEngine (create/open/drop lifecycle) and register it as the 4th engine in build_store_engines alongside mito/metric/file. Add a datanode-level test asserting all 4 engines are registered.

Signed-off-by: tian1220A <1573612521@qq.com>

* feat: add relational connection and idempotent region lifecycle

Move ConnectionInfo into relational-engine (DSN parsing + redacted rendering), place the RelationalOptions/RELATIONAL_META_KEY serialization contract in table::requests, make CREATE idempotent by comparing the persisted manifest definition against the incoming request (RegionExists on mismatch), and drop the empty EngineConfig placeholder.

Signed-off-by: tian1220A <1573612521@qq.com>

* refactor: address review comments on relational region engine

- remove connection.rs (only used by its own tests); it will be
  reintroduced when connection handling is wired up
- drop RelationalOptions::version (not validated or used to select a
  deserialization format)
- validate an idempotent create against the existing region definition
  (region id / schema / primary key / options) and return Unexpected on
  mismatch, with a reason field on RegionExists
- use serde.workspace and remove the empty [features] section
- cargo fmt

Signed-off-by: tian1220A <1573612521@qq.com>

* fix: adapt relational engine to latest main

- implement RegionEngine::set_region_role_with_lease (no-op lease, the
  engine takes no writes so no lease is needed)
- pass node_id to build_object_store_manager in the registration test
- drop stale url dependency from the relational-engine lock entry

Signed-off-by: tian1220A <1573612521@qq.com>

* ci: register relational-engine in scope rules

Signed-off-by: tian1220A <1573612521@qq.com>

* fix: remove table self-dependency from Cargo.lock

Signed-off-by: tian1220A <1573612521@qq.com>

---------

Signed-off-by: tian1220A <1573612521@qq.com>
2026-10-30 04:06:01 +00:00
Weny Xu ec59131d39 feat(ci): support optional Docker targets for query regression (#10028)
* feat(ci): support optional Docker targets for query regression

Signed-off-by: WenyXu <wenymedia@gmail.com>

* fix(ci): enable Docker when provisioning image regression runners

Signed-off-by: WenyXu <wenymedia@gmail.com>

* feat(ci): publish precompiled query regression helpers with pin update PRs

Signed-off-by: WenyXu <wenymedia@gmail.com>

* fix(ci): retry helper image publication on registry timeouts

Signed-off-by: WenyXu <wenymedia@gmail.com>

* fix(ci): publish helper artifacts with hosted Skopeo job

Signed-off-by: WenyXu <wenymedia@gmail.com>

* refactor(ci): update helper image through repository variable

Signed-off-by: WenyXu <wenymedia@gmail.com>

---------

Signed-off-by: WenyXu <wenymedia@gmail.com>
2026-10-30 00:23:47 +00:00
Weny Xu 00cda3853a ci: reduce duplicate and PR-scoped Rust cache writes (#10047)
* ci: reduce duplicate and PR-scoped Rust cache writes

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: warm shared caches through scheduled integration jobs

Signed-off-by: WenyXu <wenymedia@gmail.com>

---------

Signed-off-by: WenyXu <wenymedia@gmail.com>
2026-10-30 00:11:18 +00:00
Weny Xu 8ecf49dca0 ci: authenticate ECR Public pulls in benchmark workflows (#10056)
* ci: authenticate agent benchmark pulls to ECR Public

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: authenticate remaining ECR Public benchmark pulls

Signed-off-by: WenyXu <wenymedia@gmail.com>

---------

Signed-off-by: WenyXu <wenymedia@gmail.com>
2026-10-29 19:16:19 +00:00
Weny Xu eb8e4316ec ci: backport scoped heavy CI to narthex (#10053)
* ci: backport scoped heavy CI to narthex

Backport #9927 and the CI-only changes from #10043. Adapt script references to narthex, preserve manual platform checks, and document the default-branch schedule limitation.

Upstream-Commit: ebb7e22566
Upstream-Commit: e87766d7ef
Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: refresh narthex compatibility release window

Signed-off-by: WenyXu <wenymedia@gmail.com>

---------

Signed-off-by: WenyXu <wenymedia@gmail.com>
2026-10-29 13:06:14 +08:00
Weny Xu e87766d7ef ci: reduce repeated Windows and fuzz tests on pull requests (#10043)
* ci: reduce repeated Windows and fuzz tests on pull requests

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: use the nightly merge label as the enqueue opt-in

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: log nightly merge decisions for dry-run verification

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: gate expensive jobs on GitHub script tests

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: grant pull request write permission for nightly label sync

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: run platform checks on schedule or manual dispatch

Signed-off-by: WenyXu <wenymedia@gmail.com>

* test(ci): update PR gate count for scheduled platform checks

Signed-off-by: WenyXu <wenymedia@gmail.com>

---------

Signed-off-by: WenyXu <wenymedia@gmail.com>
2026-10-29 00:00:07 +00:00
Weny Xu b83ceb5e7b feat: add reusable paged byte cache (#9791)
* feat: add reusable paged byte cache

Signed-off-by: WenyXu <wenymedia@gmail.com>

* fix(ci): include common cache in scope rules

Signed-off-by: WenyXu <wenymedia@gmail.com>

---------

Signed-off-by: WenyXu <wenymedia@gmail.com>
2026-10-28 17:09:23 +00:00
Weny Xu f646f06430 ci: enqueue eligible pull requests during the nightly window (#10040)
* ci: enqueue eligible pull requests during the nightly window

Signed-off-by: WenyXu <wenymedia@gmail.com>

* docs: hide nightly merge instructions in PR template

Signed-off-by: WenyXu <wenymedia@gmail.com>

---------

Signed-off-by: WenyXu <wenymedia@gmail.com>
2026-10-28 13:32:23 +00:00
Weny Xu ebb7e22566 chore(ci): gate fuzz, E2E and KV backends by diff scope (#9927)
* ci: gate the integration CI long tail by diff scope

`integration.yml` starts its long tail on every pull request: the three fuzz
families, the chaos legs, the export/import E2E job and the two sqlness
KvBackend legs. Most diffs cannot affect them, so a `scope` job now classifies
the pull request and tells those jobs whether to start.

The classifier is deterministic and fail-open. Forced modes (merge queue,
`schedule`, `workflow_dispatch`, `ci:full`, `CI_SCOPE_FORCE_ALL`) and three
floors -- always-run paths, an uncovered `src/` change, and a PromQL/flow
filter -- can only widen the result; everything else is a glob match against the
suite catalog. Every step of the job is `continue-on-error` and every gate reads
`needs.scope.outputs.<key> != 'false'`, so a classifier crash runs the jobs
instead of skipping them. The rules are checked out from the pull request base,
so a pull request cannot relax its own gate.

The policy is data: `.github/ci/scope-rules.toml` holds the path groups, the
suite catalog and the always-run list, with a `reason` on every exclusion.
`ci_scope_rules.py` loads it with the stdlib `tomllib` and validates the shape
(unknown or cyclic `@group` references, a `family` that disagrees with the suite
id, an empty reason) and that every glob's literal prefix still exists, so a
renamed crate cannot leave a rule that matches nothing. `make check-ci-scope`
runs that check locally; the `CI Scope Rules` job runs it on `ubuntu-slim`, the
same image the classifier uses. `.github/ci/scope-cases.toml` holds golden cases
that `test_ci_scope.py` replays through the real classifier.

The PostgreSQL and MySQL sqlness legs move into their own `sqlness-kvbackend`
job so they can be gated: a job-level `if:` cannot read the matrix, and gating
them inside `sqlness` would skip required checks and block the merge. They run
the same cases as the required Basic leg, so only the backend itself matters.

The verdict is visible where triage looks: one log line per suite, the exact
gate values, `::warning::` when a lookup fails and the gate widens, and a job
summary that lists each suite with the rule that decided it and the changed
files that matched.

Measured on 200 merged and open pull requests: 27.5% always run, 41% decided by
path rules, 31.5% skip every gated job; 995 of 2600 suite selections are
skipped, with no selection that a path rule makes. The classifier itself runs
in about ten seconds on a single-vCPU runner.

Signed-off-by: WenyXu <wenymedia@gmail.com>

* fix(ci): let the scope job read pull requests

The `scope` job declared `permissions: contents: read`, and an explicit block
sets every unlisted permission to `none`. `GET /pulls/{n}` therefore answered
403, `build_plan` widened to a full run as designed, and every gate read an
absent output as "run": the gate could never skip anything.

- `pull-requests: read` on the `scope` job.
- `tests/runner/**` joins `@kv-backend`: the runner implements
  `--setup-pg`/`--setup-mysql`, which only the KV-backend legs pass, so a
  change there must not skip the only job that exercises it. The
  `UNMAPPED_CRATES` excuse is gone with it.
- The README no longer claims a queue failure blocks the merge: the gated jobs
  are not required checks.

Signed-off-by: WenyXu <wenymedia@gmail.com>

* fix(ci): run every suite when the kind registry script changes

The distributed and chaos fuzz jobs start their cluster through
`.github/actions/setup-kind`, which runs `.github/scripts/kind-with-registry.sh`.
`.github/actions/**` is in `ALWAYS_RUN` but the script is not, so a change
confined to it selected no suite at all and every gate stayed `false`: the
jobs that exercise the changed cluster setup were skipped.

The script joins `ALWAYS_RUN`, consistent with the action that calls it, and a
golden case pins it.

Signed-off-by: WenyXu <wenymedia@gmail.com>

* fix(ci): widen the gate for the fuzz corpus seeding script

`fuzz-test/action.yaml` runs `.github/scripts/prepare-fuzz-corpus.sh` before
the cache restore in every fuzz job, but the script was not in `ALWAYS_RUN`.
A change confined to it therefore selected no suite: `any_fuzz` stayed
`false` and every fuzz job that runs it was skipped.

The script joins `ALWAYS_RUN` next to the other scripts the fuzz jobs execute,
with a golden case for it.

Both misses so far (this one and `kind-with-registry.sh`) came through a
composite action, which the workflow never names. `WorkflowContractTests`
now resolves `uses: ./.github/actions/<name>` transitively for the gated jobs
and fails when one of the scripts they run is not in `ALWAYS_RUN`.

Signed-off-by: WenyXu <wenymedia@gmail.com>

---------

Signed-off-by: WenyXu <wenymedia@gmail.com>
2026-10-28 12:51:52 +00:00
Dhruv Vaishnav 3c490bd2dc ci: reuse fuzz corpora across integration runs (#9979)
ci: persist fuzz corpora between runs

Signed-off-by: dhruvxvaishnav <dhruvvaishnav687@gmail.com>
2026-10-28 02:37:49 +00:00
LFCandgreptimedb-ci 9fc396c148 ci(query-regression): bump RUNNER_IMAGE_EPOCH to 8 (#10019)
ci(query-regression): bump RUNNER_IMAGE_EPOCH to 8 for image m-0xihwmu1dxusb9vuf13q

Signed-off-by: greptimedb-ci <greptimedb-ci@greptime.com>
Co-authored-by: greptimedb-ci <greptimedb-ci@greptime.com>
2026-10-28 01:04:44 +00:00
Weny Xu 8170d0458a fix(ci): scope Aliyun janitor sweeps to the owning repository (#9966)
Signed-off-by: WenyXu <wenymedia@gmail.com>
2026-10-26 09:36:49 +00:00
Weny Xu de0fea673e fix(ci): specify Kind storage class for datanodes (#9908)
Signed-off-by: WenyXu <wenymedia@gmail.com>
(cherry picked from commit 567849908e)
2026-10-23 14:43:12 +08:00
liyang 6e40daed98 fix(ci): move monitoring datanodeStorage out of standalone base (#9902)
The `datanodeStorage` field belongs directly under `monitoring.standalone`
(GreptimeDBStandaloneSpec), not under `monitoring.standalone.base`
(PodTemplateSpec). Nesting it under `base` renders an invalid
GreptimeDBCluster resource and the CRD schema rejects it during
server-side apply:

  .spec.monitoring.standalone.base.datanodeStorage: field not declared in schema

(cherry picked from commit 3483f4a284)
2026-10-23 14:43:12 +08:00
dennis zhuang 99d907cf1d ci: fix CI setup steps that fail on Ubuntu 26.04 runners (#9901)
* ci: install protoc with taiki-e/install-action

Signed-off-by: Dennis Zhuang <killme2008@gmail.com>

* ci: run multi-language SDK tests on Python 3.13

Signed-off-by: Dennis Zhuang <killme2008@gmail.com>

* ci: drop the unused libfuzzer-14-dev package from fuzz builds

Signed-off-by: Dennis Zhuang <killme2008@gmail.com>

* ci: build fuzz targets with the bundled libFuzzer

Signed-off-by: Dennis Zhuang <killme2008@gmail.com>

---------

Signed-off-by: Dennis Zhuang <killme2008@gmail.com>
(cherry picked from commit 00ab09012d)
2026-10-23 14:43:12 +08:00
Yingwen 630cca3395 fix(ci): align nightly Windows and macOS artifact test stack sizes (#9860)
* fix(ci): increase Windows nightly test stack size

Signed-off-by: evenyag <realevenyag@gmail.com>

* fix(ci): align optional macOS artifact test stack size

Signed-off-by: evenyag <realevenyag@gmail.com>

---------

Signed-off-by: evenyag <realevenyag@gmail.com>
(cherry picked from commit 8b1d68369b)
2026-10-23 14:43:12 +08:00
Weny Xu f855355ed0 ci: allow independent Linux release architecture selection (#9865)
* ci: allow independent Linux release architecture selection

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: use Linux architecture checkboxes and preserve release defaults

Signed-off-by: WenyXu <wenymedia@gmail.com>

---------

Signed-off-by: WenyXu <wenymedia@gmail.com>
(cherry picked from commit f595e9bbf0)
2026-10-23 14:43:12 +08:00
Yingwen fdb8ceeb54 fix(ci): increase release integration test stack size (#9817)
Signed-off-by: evenyag <realevenyag@gmail.com>
(cherry picked from commit e6fa1a0b21)
2026-10-23 14:43:12 +08:00
jeremyhi a0a7ec02b5 ci: compare several images in one object store WAL S3 benchmark run (#9691)
* ci: compare several images in one object store WAL S3 benchmark run

A new `images` input takes a JSON list of 2..4 {label, image}. Every
cell then runs once per image, back to back, and the image order
reverses with the configuration order every other round. The cell id
gains the label. The single-image inputs keep their meaning and cell ids.

The validate job pulls every image before an instance is allocated. It
pins each image to its digest and records the version and commit that
the image reports. Each cell starts the image of its label. An optional
`warmup` runs the first load cell once per image as round 0, and no
statistic uses it.

The plan step estimates the benchmark job's minutes on c6id.2xlarge
from the cell times of earlier runs. It refuses a plan that does not
fit the job timeout.

The summary keeps the Raft Engine ratios within each image. With
several images it also reports, per group, concurrency and config:

- every round's rows/s and client p50/p99;
- each image's ratio to the first, with the geometric mean, minimum
  and maximum over the rounds.

Every cell records the host load averages at its start and end.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: scale the S3 benchmark time estimate with the batch size

The per-cell rates were measured with 1000-row batches. A smaller batch
keeps about the request rate, not the row rate, so the estimate now
shrinks rows/s with the batch. A one-row durable plan is refused instead
of passing a timeout it cannot fit.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: pin the S3 benchmark runtime image without pulling it in validate

An anonymous pull from ECR Public on a hosted runner can exceed the
registry's data limit, and it failed the validate job of several
dispatches with "toomanyrequests: Data limit exceeded". Validate now
reads only the registry manifest to pin the runtime image's digest. A
reference that names a digest must be served under that digest.

The check that the image holds the loader and the generator moves to
the benchmark host. It runs right after the runtime pull and before any
GreptimeDB image is pulled or any cell starts.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* test: run the S3 benchmark runtime content check against both files

The fake docker now runs the pull step's own check in a directory that stands in for the runtime image. It covers both files present, the loader missing and the generator missing, so dropping either file check fails the test.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: pin a digest-named S3 benchmark runtime image without the registry

ECR Public's anonymous data limit now refuses hosted runners even the
manifest read, and validate failed in "Pin the runtime image digest".
A runtime reference that names its sha256 digest, like the default one,
is already pinned, so validate takes that digest with no network call.
The format checks stay. Only a tag-only reference is resolved through
the registry. The content check on the benchmark host is unchanged.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: check the full S3 benchmark runtime reference before pinning it offline

A named digest no longer reaches the registry, so nothing parsed the rest of the reference. Validate now checks the whole reference against Docker's reference grammar first. It refuses an empty repository, a doubled '@' or a bad tag before any pin is emitted or any instance is allocated.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

---------

Signed-off-by: jeremyhi <fengjiachun@gmail.com>
(cherry picked from commit a436213bf3)
2026-10-23 14:43:10 +08:00
yihong db61aecadb ci: do not run these actions on fork (#9721)
Signed-off-by: yihong0618 <zouzou0208@gmail.com>
(cherry picked from commit 4684b95f72)
2026-10-23 14:43:10 +08:00
jeremyhi b2b606115b ci: add crash, restart, multi-region and drop cells to the S3 WAL benchmark (#9632)
* ci: add crash, restart, multi-region and drop cells to the S3 WAL benchmark

Extend the object store WAL S3 benchmark beyond one load per configuration:

- Inputs for a full image reference, the configurations to run (R0 adds Raft
  Engine with the standalone default sync_write = false), extra environment
  for every server container, a restart after each load, and a JSON list of
  named cell groups that override those inputs.
- Restart cells SIGKILL the loaded server, restart it on the same prefix and
  data home, and time /health, the first correct count and the log store
  recovery; min_objects fails a cell that left too few objects indexed.
- Crash groups write striped 1000-row batches from several writers, kill the
  server at a random point, restart it and check every acknowledged batch
  against the table (durable: present exactly once; enqueued: no duplicate,
  no partial batch, losses counted). A pinned variant keeps one row of a
  second table unflushed and samples the indexed objects while it runs.
- Idle windows scrape the server before and after a quiet period.
- A load group may split the loaded table into equal event_time ranges, so
  every batch writes to every region, and checks that each region took rows.
- Drop groups write a table, drop it, kill and restart the server, then
  write and flush another table and wait for the dropped table's objects to
  be collected.
- The summary adds WAL traffic, objects per second, mean object size,
  entries and appends per object, S3 requests per operation, server and host
  CPU, the loader's own request latency, rows per region, crash cycles, and
  each restart's replay per region from the server log.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: report the object sequences a replay spans instead of objects replayed

The width of a region's replayed entry range counts every object sequence in it, including objects that hold no entry of the region and are skipped, so the summary labels it as a span.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: fail a crash cycle that loses a batch an earlier restart recovered

The oracle accepted every missing acknowledged batch in the enqueued mode,
so a batch that one restart recovered and a later restart no longer found
passed. Every cycle keeps what its restart found, and a cycle now fails in
either mode unless every batch an earlier restart recovered is still
present, so only the current cycle's backlog that was not durable at its
kill may be missing.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: keep the pinned WAL pinned and label OpenDAL operations as such

The pin table inherited the engine's 10-minute auto flush, so a longer
pinned cycle could flush its row and release the WAL before the kill. It now
sets its own auto_flush_interval of one day, longer than any crash group can
run, and a pinned cycle fails unless its indexed objects never fall while
it runs.

The summary's request counts come from opendal_operation_duration_seconds,
which counts OpenDAL calls rather than HTTP requests (a paginated list or a
multipart write is one operation), so the fields and columns now say S3
operations.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: check a pinned cycle's retention by the collected-object counter

Net growth of the indexed objects can hide collection, and short cycles take no periodic sample, so a pinned cycle now fails unless deleted_objects_total is the same in the scrape before its writers start and in the one before the kill, both of the same server process. The operation columns name OpenDAL.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: let a pinned cell collect only the objects below its pin

The first write after a start lets the store collect the empty start object asynchronously, so a deletion after a cycle's baseline does not mean the pin let go. A pinned cell now scrapes the server before it writes the pin row and fails only once its servers together have collected more objects than were indexed then, counting the first server from that scrape and every restarted one from its start.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: test that a pinned cell's allowance spans its server restarts

Two servers that each collect fewer objects than lie below the pin but more together now fail the cell in the second cycle.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

---------

Signed-off-by: jeremyhi <fengjiachun@gmail.com>
(cherry picked from commit 0e82b29b23)
2026-10-23 14:43:10 +08:00
localhost 813b132221 fix(ci): compare release validation against the previous stable version (#9636)
Ancestry-based tag selection skips stable tags that live only on older release branches.

Signed-off-by: paomian <xpaomian@gmail.com>
(cherry picked from commit 3de8610e2e)
2026-10-23 14:43:10 +08:00
discord9 f1fb5e4e7a ci(coverage): set RUST_MIN_STACK=8MB in merge_group coverage job (#9615)
The merge_group coverage job did not set RUST_MIN_STACK, so test threads
ran with the default 2MiB stack while the regular test job (and the
production runtime in debug) use 8MiB. The deeper PromQL planning chain
from #9494 overflows 2MiB under llvm-cov instrumentation, aborting
tests::promql_test::anon_promql_ratio_repro::case_1_test_with_standalone
with SIGABRT (12/12 failures across three merge-queue candidates).
Align the coverage job with the existing 8MiB test policy.

Signed-off-by: discord9 <discord9@163.com>
(cherry picked from commit 60097a0628)
2026-10-23 14:43:10 +08:00
jeremyhi 97e3bfd547 test: add manual S3 metric snapshot benchmark (#9573)
* test: add repeatable metric snapshot S3 benchmark

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* test: use only existing CI S3 permissions in the metric snapshot benchmark

The CI S3 user is not allowed GetBucketLocation or ListBucketMultipartUploads,
so the bucket probe and the prefix cleanup failed with AccessDenied. Use only
list, put, get and delete under the run prefix, as the object store WAL
benchmark does, and probe S3 before allocating the EC2 runner.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* test: scope metric snapshot inventory to the current round

The full round's S3 inventory listed the whole run prefix, so it also counted
the smoke snapshot. List only the round's snapshot prefix while cleanup still
covers the run, and assert that the teardown's S3 cleanup step runs always()
with the validated run prefix.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* docs: record the AWS validation run of the metric snapshot benchmark

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

---------

Signed-off-by: jeremyhi <fengjiachun@gmail.com>
(cherry picked from commit 7df99f946e)
2026-10-23 14:43:10 +08:00
Weny Xu 567849908e fix(ci): specify Kind storage class for datanodes (#9908)
Signed-off-by: WenyXu <wenymedia@gmail.com>
2026-10-23 06:13:54 +00:00
liyang 3483f4a284 fix(ci): move monitoring datanodeStorage out of standalone base (#9902)
The `datanodeStorage` field belongs directly under `monitoring.standalone`
(GreptimeDBStandaloneSpec), not under `monitoring.standalone.base`
(PodTemplateSpec). Nesting it under `base` renders an invalid
GreptimeDBCluster resource and the CRD schema rejects it during
server-side apply:

  .spec.monitoring.standalone.base.datanodeStorage: field not declared in schema
2026-10-23 03:06:23 +00:00
dennis zhuang 00ab09012d ci: fix CI setup steps that fail on Ubuntu 26.04 runners (#9901)
* ci: install protoc with taiki-e/install-action

Signed-off-by: Dennis Zhuang <killme2008@gmail.com>

* ci: run multi-language SDK tests on Python 3.13

Signed-off-by: Dennis Zhuang <killme2008@gmail.com>

* ci: drop the unused libfuzzer-14-dev package from fuzz builds

Signed-off-by: Dennis Zhuang <killme2008@gmail.com>

* ci: build fuzz targets with the bundled libFuzzer

Signed-off-by: Dennis Zhuang <killme2008@gmail.com>

---------

Signed-off-by: Dennis Zhuang <killme2008@gmail.com>
2026-10-23 02:27:21 +00:00
Yingwen 8b1d68369b fix(ci): align nightly Windows and macOS artifact test stack sizes (#9860)
* fix(ci): increase Windows nightly test stack size

Signed-off-by: evenyag <realevenyag@gmail.com>

* fix(ci): align optional macOS artifact test stack size

Signed-off-by: evenyag <realevenyag@gmail.com>

---------

Signed-off-by: evenyag <realevenyag@gmail.com>
2026-10-22 06:45:25 +00:00
Weny Xu f595e9bbf0 ci: allow independent Linux release architecture selection (#9865)
* ci: allow independent Linux release architecture selection

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: use Linux architecture checkboxes and preserve release defaults

Signed-off-by: WenyXu <wenymedia@gmail.com>

---------

Signed-off-by: WenyXu <wenymedia@gmail.com>
2026-10-22 06:19:13 +00:00
Yingwen e6fa1a0b21 fix(ci): increase release integration test stack size (#9817)
Signed-off-by: evenyag <realevenyag@gmail.com>
2026-10-21 06:07:58 +00:00
jeremyhi a436213bf3 ci: compare several images in one object store WAL S3 benchmark run (#9691)
* ci: compare several images in one object store WAL S3 benchmark run

A new `images` input takes a JSON list of 2..4 {label, image}. Every
cell then runs once per image, back to back, and the image order
reverses with the configuration order every other round. The cell id
gains the label. The single-image inputs keep their meaning and cell ids.

The validate job pulls every image before an instance is allocated. It
pins each image to its digest and records the version and commit that
the image reports. Each cell starts the image of its label. An optional
`warmup` runs the first load cell once per image as round 0, and no
statistic uses it.

The plan step estimates the benchmark job's minutes on c6id.2xlarge
from the cell times of earlier runs. It refuses a plan that does not
fit the job timeout.

The summary keeps the Raft Engine ratios within each image. With
several images it also reports, per group, concurrency and config:

- every round's rows/s and client p50/p99;
- each image's ratio to the first, with the geometric mean, minimum
  and maximum over the rounds.

Every cell records the host load averages at its start and end.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: scale the S3 benchmark time estimate with the batch size

The per-cell rates were measured with 1000-row batches. A smaller batch
keeps about the request rate, not the row rate, so the estimate now
shrinks rows/s with the batch. A one-row durable plan is refused instead
of passing a timeout it cannot fit.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: pin the S3 benchmark runtime image without pulling it in validate

An anonymous pull from ECR Public on a hosted runner can exceed the
registry's data limit, and it failed the validate job of several
dispatches with "toomanyrequests: Data limit exceeded". Validate now
reads only the registry manifest to pin the runtime image's digest. A
reference that names a digest must be served under that digest.

The check that the image holds the loader and the generator moves to
the benchmark host. It runs right after the runtime pull and before any
GreptimeDB image is pulled or any cell starts.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* test: run the S3 benchmark runtime content check against both files

The fake docker now runs the pull step's own check in a directory that stands in for the runtime image. It covers both files present, the loader missing and the generator missing, so dropping either file check fails the test.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: pin a digest-named S3 benchmark runtime image without the registry

ECR Public's anonymous data limit now refuses hosted runners even the
manifest read, and validate failed in "Pin the runtime image digest".
A runtime reference that names its sha256 digest, like the default one,
is already pinned, so validate takes that digest with no network call.
The format checks stay. Only a tag-only reference is resolved through
the registry. The content check on the benchmark host is unchanged.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: check the full S3 benchmark runtime reference before pinning it offline

A named digest no longer reaches the registry, so nothing parsed the rest of the reference. Validate now checks the whole reference against Docker's reference grammar first. It refuses an empty repository, a doubled '@' or a bad tag before any pin is emitted or any instance is allocated.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

---------

Signed-off-by: jeremyhi <fengjiachun@gmail.com>
2026-10-20 02:31:42 +00:00
yihong 4684b95f72 ci: do not run these actions on fork (#9721)
Signed-off-by: yihong0618 <zouzou0208@gmail.com>
2026-10-19 07:17:58 +00:00
jeremyhi 0e82b29b23 ci: add crash, restart, multi-region and drop cells to the S3 WAL benchmark (#9632)
* ci: add crash, restart, multi-region and drop cells to the S3 WAL benchmark

Extend the object store WAL S3 benchmark beyond one load per configuration:

- Inputs for a full image reference, the configurations to run (R0 adds Raft
  Engine with the standalone default sync_write = false), extra environment
  for every server container, a restart after each load, and a JSON list of
  named cell groups that override those inputs.
- Restart cells SIGKILL the loaded server, restart it on the same prefix and
  data home, and time /health, the first correct count and the log store
  recovery; min_objects fails a cell that left too few objects indexed.
- Crash groups write striped 1000-row batches from several writers, kill the
  server at a random point, restart it and check every acknowledged batch
  against the table (durable: present exactly once; enqueued: no duplicate,
  no partial batch, losses counted). A pinned variant keeps one row of a
  second table unflushed and samples the indexed objects while it runs.
- Idle windows scrape the server before and after a quiet period.
- A load group may split the loaded table into equal event_time ranges, so
  every batch writes to every region, and checks that each region took rows.
- Drop groups write a table, drop it, kill and restart the server, then
  write and flush another table and wait for the dropped table's objects to
  be collected.
- The summary adds WAL traffic, objects per second, mean object size,
  entries and appends per object, S3 requests per operation, server and host
  CPU, the loader's own request latency, rows per region, crash cycles, and
  each restart's replay per region from the server log.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: report the object sequences a replay spans instead of objects replayed

The width of a region's replayed entry range counts every object sequence in it, including objects that hold no entry of the region and are skipped, so the summary labels it as a span.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: fail a crash cycle that loses a batch an earlier restart recovered

The oracle accepted every missing acknowledged batch in the enqueued mode,
so a batch that one restart recovered and a later restart no longer found
passed. Every cycle keeps what its restart found, and a cycle now fails in
either mode unless every batch an earlier restart recovered is still
present, so only the current cycle's backlog that was not durable at its
kill may be missing.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: keep the pinned WAL pinned and label OpenDAL operations as such

The pin table inherited the engine's 10-minute auto flush, so a longer
pinned cycle could flush its row and release the WAL before the kill. It now
sets its own auto_flush_interval of one day, longer than any crash group can
run, and a pinned cycle fails unless its indexed objects never fall while
it runs.

The summary's request counts come from opendal_operation_duration_seconds,
which counts OpenDAL calls rather than HTTP requests (a paginated list or a
multipart write is one operation), so the fields and columns now say S3
operations.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: check a pinned cycle's retention by the collected-object counter

Net growth of the indexed objects can hide collection, and short cycles take no periodic sample, so a pinned cycle now fails unless deleted_objects_total is the same in the scrape before its writers start and in the one before the kill, both of the same server process. The operation columns name OpenDAL.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: let a pinned cell collect only the objects below its pin

The first write after a start lets the store collect the empty start object asynchronously, so a deletion after a cycle's baseline does not mean the pin let go. A pinned cell now scrapes the server before it writes the pin row and fails only once its servers together have collected more objects than were indexed then, counting the first server from that scrape and every restarted one from its start.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: test that a pinned cell's allowance spans its server restarts

Two servers that each collect fewer objects than lie below the pin but more together now fail the cell in the second cycle.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

---------

Signed-off-by: jeremyhi <fengjiachun@gmail.com>
2026-10-16 09:57:50 +00:00
localhost 3de8610e2e fix(ci): compare release validation against the previous stable version (#9636)
Ancestry-based tag selection skips stable tags that live only on older release branches.

Signed-off-by: paomian <xpaomian@gmail.com>
2026-10-16 07:01:29 +00:00
discord9 60097a0628 ci(coverage): set RUST_MIN_STACK=8MB in merge_group coverage job (#9615)
The merge_group coverage job did not set RUST_MIN_STACK, so test threads
ran with the default 2MiB stack while the regular test job (and the
production runtime in debug) use 8MiB. The deeper PromQL planning chain
from #9494 overflows 2MiB under llvm-cov instrumentation, aborting
tests::promql_test::anon_promql_ratio_repro::case_1_test_with_standalone
with SIGABRT (12/12 failures across three merge-queue candidates).
Align the coverage job with the existing 8MiB test policy.

Signed-off-by: discord9 <discord9@163.com>
2026-10-15 11:17:18 +00:00
jeremyhi 7df99f946e test: add manual S3 metric snapshot benchmark (#9573)
* test: add repeatable metric snapshot S3 benchmark

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* test: use only existing CI S3 permissions in the metric snapshot benchmark

The CI S3 user is not allowed GetBucketLocation or ListBucketMultipartUploads,
so the bucket probe and the prefix cleanup failed with AccessDenied. Use only
list, put, get and delete under the run prefix, as the object store WAL
benchmark does, and probe S3 before allocating the EC2 runner.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* test: scope metric snapshot inventory to the current round

The full round's S3 inventory listed the whole run prefix, so it also counted
the smoke snapshot. List only the round's snapshot prefix while cleanup still
covers the run, and assert that the teardown's S3 cleanup step runs always()
with the validated run prefix.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* docs: record the AWS validation run of the metric snapshot benchmark

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

---------

Signed-off-by: jeremyhi <fengjiachun@gmail.com>
2026-10-15 09:52:28 +00:00
jeremyhi c1a0ca9595 ci: benchmark the object store WAL against S3 from an EC2 runner (#9536)
* ci: benchmark the object store WAL against S3 from an EC2 runner

Add a workflow_dispatch workflow that loads the o11ybench agent observability
dataset into a fresh GreptimeDB container per cell and compares three WAL
configurations that differ only in [wal]: Raft Engine with sync_write on the
instance store, and the object store WAL in durable and enqueued mode, with
the data files on S3 in the runner's region for all three. Rounds alternate
the configuration order. A summary reports rows per second, D/R and E/R as
the geometric mean over rounds, append acknowledgement p50 and p99, and the
object store WAL counters. A smoke mode runs the same chain on ubuntu-latest
against the MinIO fixture.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: scrape WAL metrics on failed loads and keep logic out of the benchmark YAML

Scrape the object store WAL metrics before stopping a cell's server whether
the load succeeded or failed, so failed cells keep their stall, poison and
create failure counters. Build the summary from the plan so that cells which
never ran are listed and leave their ratios undefined. Move budget, region,
runtime image, manifest and credential scan logic from the workflow into the
helper scripts, and drive the cell lifecycle in the tests through fake docker
and curl binaries.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: drop redundant required flags from benchmark inputs

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: fail a benchmark cell whose metrics scrape fails and zero untouched WAL counters

A load that succeeds without its metrics scrape now fails the cell with exit
code 4 and records metrics_scraped in cell.json. The summary reports an
event counter that never registered as zero when the cell is an object store
WAL cell whose scrape succeeded and created objects, and as unknown otherwise.
Planned cells that never ran are read through the same path as recorded ones.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: register the S3 benchmark workflow for dispatch from its branch

A workflow_dispatch workflow can only be dispatched once GitHub has
registered it, which happens on the default branch or when one of its
triggers fires. A push trigger limited to this branch registers it; validate
runs only for workflow_dispatch, so a push run skips every job.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: delete the benchmark S3 prefix one object at a time

boto3 now sends a CRC checksum instead of Content-MD5 with DeleteObjects,
which the MinIO fixture of the smoke run rejects. DeleteObject needs neither
and the prefix of one run holds at most a few thousand objects.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: default the S3 benchmark to c6id.2xlarge

c7id is not offered in the runner region ap-southeast-1, where DescribeInstanceTypes
rejects it. c6id is the compute optimized x86 family with a local NVMe instance
store that the region offers, with the same 8 vCPU and 16 GiB at 2xlarge.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: drop the registration trigger of the S3 benchmark workflow

The workflow is registered now, so dispatches no longer need a push trigger
on its branch.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: fail an S3 benchmark run on EC2 without a local instance store

Without an instance store the Raft Engine WAL of the R cells silently stayed
on the root EBS volume, so the run measured a different baseline. Only a smoke
run may keep it on the root volume now.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

* ci: let the instance store check fail its workflow step

The step piped wal-disk into tee without pipefail, so a rejected host still
passed. wal-disk now writes its record itself and the step runs it alone.

Signed-off-by: jeremyhi <fengjiachun@gmail.com>

---------

Signed-off-by: jeremyhi <fengjiachun@gmail.com>
2026-10-12 13:36:55 +00:00
Weny Xu 6e1a137411 ci: enhance benchmark workflows with version comparisons and diagnostics (#9383)
* ci: update Agent and Traces benchmark runtime

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: use unrestricted benchmark runtimes by default

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: retry benchmark image pulls before generating datasets

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: increase tracesbench defaults to 8 CPU and 32 GiB

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: configure tracesbench query timeout and update runtime

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: update tracesbench runtime and configure import scan workers

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: use shared parallel tracesbench import preparation

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: update tracesbench runtime to preserve Tempo trace requests

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: summarize tracesbench query results and lifecycle

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: show benchmark resource usage and update parallel loader runtime

Signed-off-by: WenyXu <wenymedia@gmail.com>

* fix(ci): resolve shared summary module in existing test harness

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: select tracesbench engines and GreptimeDB image version

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: update benchmark runtime with parallel Agent preparation

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: select benchmark runtime registry by cloud provider

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: retry long-range benchmark image pulls

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: compare baseline and candidate GreptimeDB benchmarks

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: pin published dual-version benchmark runtime

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: prepare agent benchmark indexes with updated runtime

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: validate agent admission and render traces version comparison

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: use runtime with traces index preparation

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: use consolidated runtime for benchmark version reports

Signed-off-by: WenyXu <wenymedia@gmail.com>

* test: add license header to benchmark comparison tests

Signed-off-by: WenyXu <wenymedia@gmail.com>

* fix(ci): read legacy Tempo ingestion metrics in traces summaries

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: require tracesbench query plan artifacts

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: use optimized tracesbench report runtime

Signed-off-by: WenyXu <wenymedia@gmail.com>

* ci: update tracesbench runtime to merged report validation

Signed-off-by: WenyXu <wenymedia@gmail.com>

---------

Signed-off-by: WenyXu <wenymedia@gmail.com>
2026-10-09 12:39:51 +00:00
Ning Sunandevenyag a9ce6e2d01 ci: make query regression non-blocking for scheduled nightly releases (#9434)
* ci: make query regression non-blocking for scheduled nightly releases

Scheduled nightly releases no longer gate publishing on the query
regression release test. The test still runs (validation policy stays
'all' for automatic releases) and uploads its report, but any result -
failure, timeout, cancellation, or skip - no longer blocks image
publishing or the GitHub release for schedule-triggered runs.

Since reusable-workflow caller jobs cannot use continue-on-error, the
gate is relaxed at the consumers instead: the if conditions of
release-images-to-dockerhub and publish-github-release now also pass
when github.event_name == 'schedule' regardless of the query-regression
result. All other gates (runner allocation, artifact builds,
prepare-release-validation) are unchanged.

Tag-push and manual-dispatch releases remain fully blocking unless a
skip policy is explicitly chosen via the release_validation input.

Signed-off-by: Ning Sun <sunning@greptime.com>

* ci: preserve downstream nightly release jobs after regression failures

Signed-off-by: evenyag <realevenyag@gmail.com>

---------

Signed-off-by: Ning Sun <sunning@greptime.com>
Signed-off-by: evenyag <realevenyag@gmail.com>
Co-authored-by: evenyag <realevenyag@gmail.com>
2026-10-02 10:19:50 +00:00
Yingwen 0d502e1fc1 ci: upgrade EC2 runner action to restore runner registration (#9430)
ci: update EC2 runner action for minimum runner version enforcement

Signed-off-by: evenyag <realevenyag@gmail.com>
2026-10-01 07:04:10 +00:00
Ning Sun a7f99b3425 ci: retry failed nightly release on following weekdays (#9394)
Previously the nightly release was scheduled only on Mondays, so a
failed run left users without nightly builds for a whole week.

Now the schedule triggers every weekday at 00:00 UTC, but the release
only proceeds when the latest published nightly release is older than
NIGHTLY_RELEASE_MAX_AGE_DAYS (5) days. The check runs in
allocate-runners before any EC2 runner is allocated, and gates all
schedule-driven jobs (including the Slack notification, so a skipped
nightly is silent). Tag pushes and manual dispatches are unaffected.

Signed-off-by: Ning Sun <sunning@greptime.com>
2026-09-29 07:48:29 +00:00