Skip to content

detached table commits replace recovery sidecars #430

detached table commits replace recovery sidecars

detached table commits replace recovery sidecars #430

Workflow file for this run

name: GQ Logic Tests
on:
# Code-bearing events only. The body and label events belong to
# `fix-regression-gate.yml`, which builds nothing; listing them here
# would re-run this Rust build on every label change.
pull_request:
types:
- opened
- synchronize
- reopened
# `GQ Logic Tests` is a required context, so it must also report on the
# merge queue's temporary branch (docs/dev/branch-protection.md, Merge queue).
merge_group:
types: [checks_requested]
push:
branches:
- main
workflow_dispatch:
concurrency:
group: gq-logic-tests-${{ github.ref }}
# Superseded PR runs are safe to cancel; post-merge main runs stay alive.
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
# A job cannot depend on another workflow's job, so this is a verbatim
# copy of `ci.yml`'s `classify_changes`; `ci.yml` is the source of truth,
# and an unconditional step at the top of the test job, right after
# checkout, asserts every copy stays identical (the copies are discovered
# by `scripts/check-classify-copy.py`, which globs the workflows).
classify_changes:
name: Classify Changes (GQ Logic Tests)
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: read
outputs:
run_full_ci: ${{ steps.filter.outputs.run_full_ci }}
run_gqt: ${{ steps.filter.outputs.run_gqt }}
run_deployment: ${{ steps.filter.outputs.run_deployment }}
steps:
- name: Checkout source
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
fetch-depth: 0
- name: Classify changed paths
id: filter
env:
BEFORE_SHA: ${{ github.event.before }}
EVENT_NAME: ${{ github.event_name }}
MERGE_GROUP_BASE_SHA: ${{ github.event.merge_group.base_sha }}
MERGE_GROUP_HEAD_SHA: ${{ github.event.merge_group.head_sha }}
PR_BASE_SHA: ${{ github.event.pull_request.base.sha }}
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
REF_TYPE: ${{ github.ref_type }}
run: |
set -euo pipefail
# No diff to classify (dispatch, tag, unknown base, empty diff):
# every job runs.
run_everything() {
printf 'run_full_ci=true\nrun_gqt=true\nrun_deployment=true\n' >> "$GITHUB_OUTPUT"
exit 0
}
if [[ "$EVENT_NAME" == "workflow_dispatch" || "$REF_TYPE" == "tag" ]]; then
run_everything
fi
if [[ "$EVENT_NAME" == "pull_request" ]]; then
base="$PR_BASE_SHA"
head="$PR_HEAD_SHA"
elif [[ "$EVENT_NAME" == "merge_group" ]]; then
base="$MERGE_GROUP_BASE_SHA"
head="$MERGE_GROUP_HEAD_SHA"
else
base="$BEFORE_SHA"
head="$GITHUB_SHA"
if [[ "$base" == "0000000000000000000000000000000000000000" ]]; then
base="$(git rev-parse "${head}^" 2>/dev/null || true)"
fi
fi
if [[ -z "${base:-}" ]]; then
run_everything
fi
# Merge base (a branch behind main must not inherit its newer files),
# no rename collapsing (a source file moved into docs keeps its
# deletion), no path quoting (a non-ASCII name reaches the arms raw).
mapfile -t changed < <(git -c core.quotePath=false diff --name-only --no-renames --merge-base "$base" "$head")
if [[ "${#changed[@]}" -eq 0 ]]; then
run_everything
fi
run_full_ci=false
run_gqt=false
run_deployment=false
for path in "${changed[@]}"; do
case "$path" in
docs/*.md|docs/*.mdx|docs/*.rst|docs/*.adoc) ;;
README.md|AGENTS.md|CLAUDE.md|CHANGELOG.md|CONTRIBUTING.md|CODE_OF_CONDUCT.md) ;;
LICENSE|LICENSE.md) ;;
crates/omnigraph-gqt/cases/*.gqt) run_gqt=true ;;
Dockerfile|.dockerignore|docker/*|deploy/*) run_deployment=true ;;
*)
run_full_ci=true
;;
esac
done
if [[ "$run_full_ci" == "true" ]]; then
run_gqt=true
run_deployment=true
fi
printf 'Changed files:\n'
printf ' %s\n' "${changed[@]}"
printf 'run_full_ci=%s\nrun_gqt=%s\nrun_deployment=%s\n' \
"$run_full_ci" "$run_gqt" "$run_deployment" | tee -a "$GITHUB_OUTPUT"
qualification:
name: GQT (${{ matrix.mode }})
needs: classify_changes
runs-on: ubuntu-latest
# Cold-build budget and observations: docs/dev/ci.md, GQ Logic Tests.
timeout-minutes: 60
strategy:
fail-fast: true
matrix:
mode: [ordinary, dst, engine-v2, dst-clippy]
permissions:
contents: read
env:
CARGO_TERM_COLOR: always
# Same floor as the Test Workspace job: unoptimized builds keep every
# nested async engine frame, deeper than a default 2 MiB thread stack.
RUST_MIN_STACK: 16777216
steps:
# Check the classification copies on skipped changes too.
- name: Checkout source
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
- name: Assert the classification copies match ci.yml
run: python3 scripts/check-classify-copy.py
# No GQT input changed (engine code or a `.gqt` case): report success
# without building, so the required context is never left pending.
- name: Skip when no GQT input changed
if: needs.classify_changes.outputs.run_gqt != 'true'
run: echo "No GQT input changed; skipping the GQ logic tests."
- name: Install system dependencies
if: needs.classify_changes.outputs.run_gqt == 'true'
run: |
sudo apt-get update
sudo apt-get install -y protobuf-compiler libprotobuf-dev
# The `rust-toolchain.toml` pin, not a floating `stable` action (see
# the `fmt` job in ci.yml): rustc is part of the cache key.
- name: Install pinned toolchain
if: needs.classify_changes.outputs.run_gqt == 'true'
run: rustup toolchain install
- name: Cache Rust build data
if: needs.classify_changes.outputs.run_gqt == 'true'
uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
with:
workspaces: |
. -> target
key: gqt-${{ matrix.mode }}
# Save only from main, red or green (same rule as ci.yml's `lint`).
save-if: ${{ github.ref == 'refs/heads/main' }}
cache-on-failure: true
- name: Test unavailable DST runtime refusal
if: needs.classify_changes.outputs.run_gqt == 'true' && matrix.mode == 'ordinary'
# The flagless build shape this test exists for: an env RUSTFLAGS,
# empty included, replaces the workspace `[build] rustflags`.
env:
RUSTFLAGS: ""
run: cargo test -p omnigraph-gqt --locked --timings --lib --test runner_dispatch -- --nocapture
# A case's `at:` name arms a seam in the seam guard, so a cases-only
# diff can change its verdict while `Test Workspace` is skipped.
- name: Run the seam guard the case corpus arms
if: needs.classify_changes.outputs.run_gqt == 'true' && matrix.mode == 'ordinary'
env:
RUSTFLAGS: ""
run: cargo test -p omnigraph-seams --locked --timings --test failpoint_names_guard
# The workspace .cargo/config.toml enables the seeded Tokio runtime
# from any directory; these steps run from the repo root.
- name: Run complete GQ logic tests with DST
if: needs.classify_changes.outputs.run_gqt == 'true' && matrix.mode == 'dst'
run: cargo test -p omnigraph-gqt --locked --timings -- --nocapture
# The same corpus on the plan route (RFC 0068 milestone 3): every
# embedded-engine case must answer the same rows on both routes.
- name: Run complete GQ logic tests on engine v2
if: needs.classify_changes.outputs.run_gqt == 'true' && matrix.mode == 'engine-v2'
env:
OMNIGRAPH_GQ_ENGINE: v2
run: cargo test -p omnigraph-gqt --locked --timings -- --nocapture
- name: Clippy GQT with DST
if: needs.classify_changes.outputs.run_gqt == 'true' && matrix.mode == 'dst-clippy'
run: cargo clippy -p omnigraph-gqt --all-targets --locked --timings -- -D warnings -W clippy::dbg_macro
- name: Retain GQT invocation reports
if: always() && needs.classify_changes.outputs.run_gqt == 'true' && matrix.mode != 'dst-clippy'
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: gqt-invocation-reports-${{ matrix.mode }}
path: target/gqt-artifacts/*.json
if-no-files-found: error
- name: Retain Cargo build timings
if: always() && needs.classify_changes.outputs.run_gqt == 'true'
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: gqt-build-timings-${{ matrix.mode }}
path: target/cargo-timings/*.html
if-no-files-found: warn
gq_logic_tests:
name: GQ Logic Tests
needs: [classify_changes, qualification]
if: always()
runs-on: ubuntu-latest
timeout-minutes: 5
permissions: {}
steps:
- name: Require all GQT qualification jobs
env:
CLASSIFICATION_RESULT: ${{ needs.classify_changes.result }}
QUALIFICATION_RESULT: ${{ needs.qualification.result }}
run: |
if [[ "$CLASSIFICATION_RESULT" != "success" || "$QUALIFICATION_RESULT" != "success" ]]; then
echo "GQT qualification failed: classification=$CLASSIFICATION_RESULT qualification=$QUALIFICATION_RESULT"
exit 1
fi