From edb0f733e21281870ae703a58997f0b87fd9cee5 Mon Sep 17 00:00:00 2001 From: Shawn Chen Date: Wed, 12 Aug 2026 14:38:09 +1200 Subject: [PATCH 1/9] Run the suite against each new chdb-core release MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The test job builds against the engine pinned in update_libchdb.sh, so it stays green through anything chdb-core changes after that pin. The addon's C++ does get a compile error out of a changed signature, but only against the header it was handed; a struct that changes layout without changing its declaration produces no error at all. Either way nobody finds out until the pin moves. chdb-core now dispatches here when it publishes a release. This runs the suite against that engine on all four platforms and opens an issue with the verdict, closing it again when green. A red result does not mean the pinned engine broke — update_libchdb.sh is untouched — it means adopting the new one needs addon work first. One Node version rather than three: what is under test is the C ABI, and that does not vary by Node version. Platform does, so all four stay. CHDB_ENGINE_VERSION is deliberately not CHDB_LIB_VERSION, which already means the npm subpackage version and is read from LIBCHDB_NPM_VERSION. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/engine-release-check.yml | 127 +++++++++++++++++++++ update_libchdb.sh | 6 +- 2 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/engine-release-check.yml diff --git a/.github/workflows/engine-release-check.yml b/.github/workflows/engine-release-check.yml new file mode 100644 index 0000000..63ab436 --- /dev/null +++ b/.github/workflows/engine-release-check.yml @@ -0,0 +1,127 @@ +name: Engine release check + +# chdb-core publishes an engine and dispatches here; this runs the suite against +# that engine and records the verdict in an issue. It gates nothing — the engine +# has already shipped by the time this starts. +# +# The regular test job builds against the engine this repository pinned in +# update_libchdb.sh, so it stays green through any change chdb-core makes after +# that pin. The addon's C++ does get a compile error out of a changed signature, +# but only against the header it was handed, and a struct that changes layout +# without changing its declaration produces no error at all. +# +# One Node version per platform on purpose: what is under test is the C ABI, and +# that does not vary by Node version. Platform does vary, so all four stay. + +on: + repository_dispatch: + types: [chdb-core-release] + workflow_dispatch: + inputs: + engine_version: + description: "chdb-core release tag, e.g. v26.5.0" + required: true + +permissions: + contents: read + +env: + npm_config_fetch_retries: "5" + npm_config_fetch_retry_mintimeout: "20000" + npm_config_fetch_retry_maxtimeout: "120000" + npm_config_fetch_timeout: "600000" + +jobs: + test: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, ubuntu-24.04-arm, macos-14, macos-15-intel] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + + - name: Resolve the engine version + shell: bash + env: + ENGINE_VERSION: ${{ github.event.client_payload.tag || github.event.inputs.engine_version }} + run: | + if [ -z "$ENGINE_VERSION" ]; then + echo "::error::no engine version in the dispatch payload or the manual input" + exit 1 + fi + echo "CHDB_ENGINE_VERSION=$ENGINE_VERSION" >> "$GITHUB_ENV" + echo "Testing against chdb-core $ENGINE_VERSION" + + - uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - uses: actions/setup-node@v4 + with: + node-version: 20.x + cache: npm + + - name: Install JS deps (no compile-on-install) + run: npm install --ignore-scripts + + - name: Fetch the published engine + run: npm run libchdb + + - name: Build (addon + dist) + run: npm run build + + - name: Exercise the freshly built addon (not the published prebuilt) + # loadNative() prefers the published @chdb/lib- subpackage, + # which carries its own engine and would mask the one under test. + shell: bash + run: rm -rf node_modules/@chdb/lib-* + + - name: Test (v2 mocha + v3 vitest) + run: npm run test:all + + report: + needs: test + if: always() + runs-on: ubuntu-latest + permissions: + issues: write + steps: + - name: Open an issue with the verdict + env: + GH_TOKEN: ${{ github.token }} + RESULT: ${{ needs.test.result }} + ENGINE_VERSION: ${{ github.event.client_payload.tag || github.event.inputs.engine_version }} + RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + run: | + set -euo pipefail + + if [ "$RESULT" = success ]; then + verdict="passes" + else + verdict="FAILS" + fi + + { + echo "chdb-node $verdict against chdb-core \`$ENGINE_VERSION\`." + echo + echo "$RUN_URL" + if [ "$RESULT" != success ]; then + echo + echo "This does not mean the pinned engine is broken — update_libchdb.sh is" + echo "untouched. It means adopting \`$ENGINE_VERSION\` needs addon work first." + echo "Start with the C declarations the addon uses against" + echo "\`programs/local/chdb.h\` at this tag." + fi + echo + echo "cc @auxten @wudidapaopao @ShawnChen-Sirius" + } > body.md + + url=$(gh issue create \ + --title "Engine check: chdb-core $ENGINE_VERSION — $verdict" \ + --body-file body.md) + echo "$url" + + if [ "$RESULT" = success ]; then + gh issue close "$url" --comment "Green, closing. The run is linked above." + fi diff --git a/update_libchdb.sh b/update_libchdb.sh index 9cdd83b..fa7d55c 100755 --- a/update_libchdb.sh +++ b/update_libchdb.sh @@ -13,7 +13,11 @@ set -e # Pre-release engine for the 3.1.0-rc.1 test line (carries the written-rows # accessors the raw/streaming insert needs; absent in the v26.5.0 stable line). -LATEST_RELEASE=v26.5.1-rc.1 +# +# CHDB_ENGINE_VERSION overrides it, which is how the release-check workflow runs +# the suite against an engine this repository has not adopted yet. It is a +# different thing from CHDB_LIB_VERSION below, which names the npm subpackage. +LATEST_RELEASE="${CHDB_ENGINE_VERSION:-v26.5.1-rc.1}" # Version published for the @chdb/lib- native subpackages on npm. # DECOUPLED from LATEST_RELEASE on purpose: chdb-core has no 26.5.2/26.5.3 From 67dfa3417b19cf3492aa43f4fe27a60b7dc35880 Mon Sep 17 00:00:00 2001 From: Shawn Chen Date: Wed, 12 Aug 2026 18:59:49 +1200 Subject: [PATCH 2/9] Propose the engine bump when a release passes The pinned engine moves to CHDB_ENGINE_PIN, a literal line of its own, so the release check can find and rewrite it. The value and the behaviour are unchanged. When the check passes it opens a pull request moving that line, which is the only edit adopting an engine requires. Green says the engine can be adopted, not that it has been; that stays a review. LIBCHDB_NPM_VERSION is deliberately left alone. It names the @chdb/lib- subpackages, which are decoupled from the engine on purpose, and publishing new ones carrying a new engine is a separate decision from testing against it. Those pull requests carry no checks. GitHub does not start workflow runs for commits a workflow pushed with GITHUB_TOKEN, and re-running CI on the branch would exercise the same suites against the same engine the check just finished with. The body says so rather than leaving a reviewer to wonder. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/engine-release-check.yml | 73 +++++++++++++++++++++- update_libchdb.sh | 12 ++-- 2 files changed, 80 insertions(+), 5 deletions(-) diff --git a/.github/workflows/engine-release-check.yml b/.github/workflows/engine-release-check.yml index 63ab436..a0ae844 100644 --- a/.github/workflows/engine-release-check.yml +++ b/.github/workflows/engine-release-check.yml @@ -80,8 +80,74 @@ jobs: - name: Test (v2 mocha + v3 vitest) run: npm run test:all - report: + # Green means the engine can be adopted, not that it has been. Adoption is a + # one-line change to a pinned version and goes through review like any other + # dependency bump; this only writes the line. LIBCHDB_NPM_VERSION is left + # alone — it tracks the npm subpackage, not the engine. + propose_bump: needs: test + if: needs.test.result == 'success' + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + outputs: + pr: ${{ steps.bump.outputs.pr }} + steps: + - uses: actions/checkout@v4 + + - id: bump + name: Open a PR moving the pin to this engine + env: + GH_TOKEN: ${{ github.token }} + ENGINE_VERSION: ${{ github.event.client_payload.tag || github.event.inputs.engine_version }} + RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + run: | + set -euo pipefail + + current=$(grep -E '^CHDB_ENGINE_PIN=' update_libchdb.sh | cut -d= -f2) + if [ "$current" = "$ENGINE_VERSION" ]; then + echo "already pinned to $ENGINE_VERSION, nothing to propose" + exit 0 + fi + + branch="engine-pin-$ENGINE_VERSION" + if [ "$(gh pr list --head "$branch" --state open --json number --jq 'length')" != 0 ]; then + echo "a PR for $ENGINE_VERSION is already open" + exit 0 + fi + + git switch -c "$branch" + sed -i "s|^CHDB_ENGINE_PIN=.*|CHDB_ENGINE_PIN=$ENGINE_VERSION|" update_libchdb.sh + git -c user.name="github-actions[bot]" \ + -c user.email="41898282+github-actions[bot]@users.noreply.github.com" \ + commit -am "Move the engine pin from $current to $ENGINE_VERSION" + git push -u origin "$branch" + + { + echo "The release check ran the v2 and v3 suites against \`$ENGINE_VERSION\` on" + echo "all four platforms and they passed, so the engine can be adopted. This" + echo "moves the pin $current → \`$ENGINE_VERSION\`." + echo + echo "\`LIBCHDB_NPM_VERSION\` is untouched. Publishing new \`@chdb/lib-\`" + echo "subpackages carrying this engine is a separate decision." + echo + echo "$RUN_URL" + echo + echo "No checks will appear here. GitHub does not start workflow runs for" + echo "commits a workflow pushed with \`GITHUB_TOKEN\`, and running CI on this" + echo "branch would exercise the same suites against the same engine the check" + echo "just used." + } > pr-body.md + + url=$(gh pr create --base "$GITHUB_REF_NAME" --head "$branch" \ + --title "Move the engine pin to $ENGINE_VERSION" \ + --body-file pr-body.md) + echo "pr=$url" >> "$GITHUB_OUTPUT" + echo "$url" + + report: + needs: [test, propose_bump] if: always() runs-on: ubuntu-latest permissions: @@ -91,6 +157,7 @@ jobs: env: GH_TOKEN: ${{ github.token }} RESULT: ${{ needs.test.result }} + BUMP_PR: ${{ needs.propose_bump.outputs.pr }} ENGINE_VERSION: ${{ github.event.client_payload.tag || github.event.inputs.engine_version }} RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} run: | @@ -106,6 +173,10 @@ jobs: echo "chdb-node $verdict against chdb-core \`$ENGINE_VERSION\`." echo echo "$RUN_URL" + if [ -n "$BUMP_PR" ]; then + echo + echo "Adopting it: $BUMP_PR" + fi if [ "$RESULT" != success ]; then echo echo "This does not mean the pinned engine is broken — update_libchdb.sh is" diff --git a/update_libchdb.sh b/update_libchdb.sh index fa7d55c..fbebbb1 100755 --- a/update_libchdb.sh +++ b/update_libchdb.sh @@ -14,10 +14,14 @@ set -e # Pre-release engine for the 3.1.0-rc.1 test line (carries the written-rows # accessors the raw/streaming insert needs; absent in the v26.5.0 stable line). # -# CHDB_ENGINE_VERSION overrides it, which is how the release-check workflow runs -# the suite against an engine this repository has not adopted yet. It is a -# different thing from CHDB_LIB_VERSION below, which names the npm subpackage. -LATEST_RELEASE="${CHDB_ENGINE_VERSION:-v26.5.1-rc.1}" +# Keep the pin on its own line and literal: the release check greps for it when +# it proposes a bump. +CHDB_ENGINE_PIN=v26.5.1-rc.1 + +# CHDB_ENGINE_VERSION overrides the pin, which is how the release check runs the +# suite against an engine this repository has not adopted yet. It is a different +# thing from CHDB_LIB_VERSION below, which names the npm subpackage. +LATEST_RELEASE="${CHDB_ENGINE_VERSION:-$CHDB_ENGINE_PIN}" # Version published for the @chdb/lib- native subpackages on npm. # DECOUPLED from LATEST_RELEASE on purpose: chdb-core has no 26.5.2/26.5.3 From 064157c8b6612b266be9819452ed7b393d130c3a Mon Sep 17 00:00:00 2001 From: Shawn Chen Date: Wed, 12 Aug 2026 19:07:27 +1200 Subject: [PATCH 3/9] Tell gh which repository to open the verdict issue in MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The report job checks nothing out, and gh does not fall back to GITHUB_REPOSITORY. Every run would have failed at gh issue create, before reaching the close, so the whole reporting path was dead — and it never showed up in CI, because this workflow only runs from a dispatch. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/engine-release-check.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/engine-release-check.yml b/.github/workflows/engine-release-check.yml index a0ae844..730992f 100644 --- a/.github/workflows/engine-release-check.yml +++ b/.github/workflows/engine-release-check.yml @@ -156,6 +156,10 @@ jobs: - name: Open an issue with the verdict env: GH_TOKEN: ${{ github.token }} + # This job has nothing checked out, and gh does not read + # GITHUB_REPOSITORY. Without this it cannot tell which repository to + # open the issue in and every run reports nothing. + GH_REPO: ${{ github.repository }} RESULT: ${{ needs.test.result }} BUMP_PR: ${{ needs.propose_bump.outputs.pr }} ENGINE_VERSION: ${{ github.event.client_payload.tag || github.event.inputs.engine_version }} From f29b3dc59661ced9153bc6633c37c2f8e30d3e99 Mon Sep 17 00:00:00 2001 From: Shawn Chen Date: Wed, 12 Aug 2026 19:12:55 +1200 Subject: [PATCH 4/9] Propose the bump against the default branch, not the current ref $GITHUB_REF_NAME is the default branch for a repository_dispatch, but a manual run from another branch would root the bump commit there and open the pull request against it, and a run from a tag would fail outright. Both the checkout and the base now name the default branch explicitly. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/engine-release-check.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/engine-release-check.yml b/.github/workflows/engine-release-check.yml index 730992f..fd9e967 100644 --- a/.github/workflows/engine-release-check.yml +++ b/.github/workflows/engine-release-check.yml @@ -94,12 +94,17 @@ jobs: outputs: pr: ${{ steps.bump.outputs.pr }} steps: + # Explicitly the default branch. A manual run from some other branch would + # otherwise root the bump there and open the pull request against it. - uses: actions/checkout@v4 + with: + ref: ${{ github.event.repository.default_branch }} - id: bump name: Open a PR moving the pin to this engine env: GH_TOKEN: ${{ github.token }} + DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} ENGINE_VERSION: ${{ github.event.client_payload.tag || github.event.inputs.engine_version }} RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} run: | @@ -140,7 +145,7 @@ jobs: echo "just used." } > pr-body.md - url=$(gh pr create --base "$GITHUB_REF_NAME" --head "$branch" \ + url=$(gh pr create --base "$DEFAULT_BRANCH" --head "$branch" \ --title "Move the engine pin to $ENGINE_VERSION" \ --body-file pr-body.md) echo "pr=$url" >> "$GITHUB_OUTPUT" From d1532acc6dde1898edb93847d299e3be515d9da7 Mon Sep 17 00:00:00 2001 From: Shawn Chen Date: Wed, 12 Aug 2026 19:16:03 +1200 Subject: [PATCH 5/9] Handle a bump branch left over from an earlier attempt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A bump PR closed without merging leaves engine-pin- on the remote. The next run creates the branch fresh from the default branch, so pushing it is a non-fast-forward and is rejected — costing the adoption PR while the verdict issue still reports a pass, which reads as though nothing needed adopting. Two dispatches for the same version race the same way. The push replaces the branch when it already exists. No open PR uses it, which the check above already established, and its only content is one generated line. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/engine-release-check.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/engine-release-check.yml b/.github/workflows/engine-release-check.yml index fd9e967..0aab01f 100644 --- a/.github/workflows/engine-release-check.yml +++ b/.github/workflows/engine-release-check.yml @@ -127,7 +127,17 @@ jobs: git -c user.name="github-actions[bot]" \ -c user.email="41898282+github-actions[bot]@users.noreply.github.com" \ commit -am "Move the engine pin from $current to $ENGINE_VERSION" - git push -u origin "$branch" + # The branch can already exist on the remote: a bump PR closed without + # merging leaves it behind, and a plain push is then rejected as a + # non-fast-forward, silently costing the adoption PR. No open PR uses it + # — that was checked above — and its only content is one generated line, + # so replacing it is safe. + if git ls-remote --exit-code --heads origin "$branch" >/dev/null 2>&1; then + echo "$branch is left over from an earlier attempt, replacing it" + git push --force -u origin "$branch" + else + git push -u origin "$branch" + fi { echo "The release check ran the v2 and v3 suites against \`$ENGINE_VERSION\` on" From 72185e56764598b45826deaec6b4177c81fee247 Mon Sep 17 00:00:00 2001 From: Shawn Chen Date: Wed, 12 Aug 2026 19:21:17 +1200 Subject: [PATCH 6/9] Reject an engine version that is not a plain tag The version arrives from a dispatch payload or a typed input and is interpolated into a sed replacement, a branch name, a URL and a commit message. sed is the sharp edge: an & in a replacement expands to the whole match, so a tag like v9&evil rewrites the pin line to CHDB_ENGINE_PIN=v9CHDB_ENGINE_PIN=v26.5.0evil and the bump PR carries it, while a | ends the substitution early and fails with "bad flag in substitute command". Escaping for sed would fix sed alone. Restricting the value to what a chdb-core tag actually contains covers every place it is used at once, and rejects rather than mangles. Verified that v26.5.0, v26.5.1-rc.1 and v26.7.1.882-stable pass while &, |, backslash, spaces and semicolons are refused. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/engine-release-check.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/workflows/engine-release-check.yml b/.github/workflows/engine-release-check.yml index 0aab01f..27c8ee3 100644 --- a/.github/workflows/engine-release-check.yml +++ b/.github/workflows/engine-release-check.yml @@ -50,6 +50,15 @@ jobs: echo "::error::no engine version in the dispatch payload or the manual input" exit 1 fi + # The version arrives from a dispatch payload or a typed input, then flows + # into a URL, a branch name, a commit message and a sed replacement. Any + # character outside this set belongs to no chdb-core release tag, and an + # & or | reaching sed would quietly rewrite the wrong thing. + case "$ENGINE_VERSION" in + *[!A-Za-z0-9._+-]*) + echo "::error::refusing engine version '$ENGINE_VERSION': letters, digits and . _ + - only" + exit 1 ;; + esac echo "CHDB_ENGINE_VERSION=$ENGINE_VERSION" >> "$GITHUB_ENV" echo "Testing against chdb-core $ENGINE_VERSION" @@ -110,6 +119,14 @@ jobs: run: | set -euo pipefail + # test rejects these too, but this is the step that interpolates the + # version into sed replacements and a branch name. + case "$ENGINE_VERSION" in + *[!A-Za-z0-9._+-]*) + echo "::error::refusing engine version '$ENGINE_VERSION'" + exit 1 ;; + esac + current=$(grep -E '^CHDB_ENGINE_PIN=' update_libchdb.sh | cut -d= -f2) if [ "$current" = "$ENGINE_VERSION" ]; then echo "already pinned to $ENGINE_VERSION, nothing to propose" From 847915278cda22cfc49857333f672d57961e58ef Mon Sep 17 00:00:00 2001 From: Shawn Chen Date: Wed, 12 Aug 2026 19:25:34 +1200 Subject: [PATCH 7/9] Keep the issue open when the bump could not be opened MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The verdict and the close both came from needs.test.result, so a green suite whose propose_bump failed filed as "passes", linked no adoption PR, and closed itself. That reads as "nothing needed adopting" — the one reading that is wrong. It is also the state every repository starts in: without "Allow GitHub Actions to create and approve pull requests" the bump job gets a 403 on the first real run. needs.propose_bump.result now feeds in. A bump that failed or was cancelled keeps the issue open and says which of the two usual causes to look at. A bump that succeeded without opening anything — already pinned, or a PR already open — still closes, because nothing is wrong in that case. Exercised all three outcomes against a stubbed gh: green closes and links the PR, a failed bump stays open with the explanation, a failed suite stays open with the ABI pointer. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/engine-release-check.yml | 32 ++++++++++++++++++---- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/.github/workflows/engine-release-check.yml b/.github/workflows/engine-release-check.yml index 27c8ee3..7e1eedc 100644 --- a/.github/workflows/engine-release-check.yml +++ b/.github/workflows/engine-release-check.yml @@ -194,24 +194,46 @@ jobs: GH_REPO: ${{ github.repository }} RESULT: ${{ needs.test.result }} BUMP_PR: ${{ needs.propose_bump.outputs.pr }} + BUMP_RESULT: ${{ needs.propose_bump.result }} ENGINE_VERSION: ${{ github.event.client_payload.tag || github.event.inputs.engine_version }} RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} run: | set -euo pipefail - if [ "$RESULT" = success ]; then - verdict="passes" - else + # A green suite whose bump could not be opened is not a green run. Closing + # on needs.test.result alone would file it as "nothing to adopt" and leave + # the broken automation with no signal at all. + bump_broke=0 + if [ "$RESULT" != success ]; then verdict="FAILS" + keep=1 + elif [ "$BUMP_RESULT" = failure ] || [ "$BUMP_RESULT" = cancelled ]; then + verdict="passes, bump PR did not open" + keep=1 + bump_broke=1 + else + verdict="passes" + keep=0 fi { - echo "chdb-node $verdict against chdb-core \`$ENGINE_VERSION\`." + if [ "$bump_broke" = 1 ]; then + echo "chdb-node passes against chdb-core \`$ENGINE_VERSION\`, but the bump PR did not open." + else + echo "chdb-node $verdict against chdb-core \`$ENGINE_VERSION\`." + fi echo echo "$RUN_URL" if [ -n "$BUMP_PR" ]; then echo echo "Adopting it: $BUMP_PR" + elif [ "$bump_broke" = 1 ]; then + echo + echo "The engine is fine; the automation is not. The pull request moving the" + echo "pin could not be opened, so this issue stays open. The usual cause is" + echo "this repository having \"Allow GitHub Actions to create and approve pull" + echo "requests\" turned off; the other is the branch push being rejected. The" + echo "pin is unchanged either way, and moving it by hand is one line." fi if [ "$RESULT" != success ]; then echo @@ -229,6 +251,6 @@ jobs: --body-file body.md) echo "$url" - if [ "$RESULT" = success ]; then + if [ "$keep" = 0 ]; then gh issue close "$url" --comment "Green, closing. The run is linked above." fi From bbc93b35605eecb6a770d0b76db9fd8c2687736b Mon Sep 17 00:00:00 2001 From: Shawn Chen Date: Wed, 12 Aug 2026 19:31:01 +1200 Subject: [PATCH 8/9] Base the bump on the commit the suite tested MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit propose_bump checked out the default branch tip at bump time, not the tree the test job ran against. The four-platform matrix takes tens of minutes; a default branch that advances meanwhile puts the new engine pin on binding code nothing tested, while the pull request body says the suite passed. github.sha is fixed for the whole run, so checking that out makes the claim true. Rooting the branch there means it can be behind the default branch, which is honest and what GitHub already shows. It also reintroduces the case the previous commit removed — a manual run from a branch that is not the default one would carry that branch;s other changes into the bump — so the compare API decides: identical or behind means the tested commit is on the default branch, anything else declines to propose. Verified the three statuses against real refs. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/engine-release-check.yml | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/.github/workflows/engine-release-check.yml b/.github/workflows/engine-release-check.yml index 7e1eedc..e0c9473 100644 --- a/.github/workflows/engine-release-check.yml +++ b/.github/workflows/engine-release-check.yml @@ -103,11 +103,14 @@ jobs: outputs: pr: ${{ steps.bump.outputs.pr }} steps: - # Explicitly the default branch. A manual run from some other branch would - # otherwise root the bump there and open the pull request against it. + # The commit the suite actually ran against, not whatever the default branch + # has become since. github.sha is fixed for the whole run, so this is the + # same tree the test job exercised; a default branch that moved during a + # long matrix would otherwise put the new pin on untested code while the + # pull request claims the suite passed. - uses: actions/checkout@v4 with: - ref: ${{ github.event.repository.default_branch }} + ref: ${{ github.sha }} - id: bump name: Open a PR moving the pin to this engine @@ -127,6 +130,17 @@ jobs: exit 1 ;; esac + # A manual run from a branch that is not the default one would carry that + # branch's other changes into the bump. "behind" means the tested commit + # is an ancestor of the default branch; "identical" means it is the tip. + rel=$(gh api "repos/$GITHUB_REPOSITORY/compare/$DEFAULT_BRANCH...$GITHUB_SHA" --jq .status) + case "$rel" in + identical|behind) ;; + *) + echo "tested commit $GITHUB_SHA is $rel relative to $DEFAULT_BRANCH; not proposing a bump" + exit 0 ;; + esac + current=$(grep -E '^CHDB_ENGINE_PIN=' update_libchdb.sh | cut -d= -f2) if [ "$current" = "$ENGINE_VERSION" ]; then echo "already pinned to $ENGINE_VERSION, nothing to propose" @@ -166,6 +180,8 @@ jobs: echo echo "$RUN_URL" echo + echo "Based on $GITHUB_SHA, the commit that run tested." + echo echo "No checks will appear here. GitHub does not start workflow runs for" echo "commits a workflow pushed with \`GITHUB_TOKEN\`, and running CI on this" echo "branch would exercise the same suites against the same engine the check" From 9cf99888259a2fa23c201832995b8693b9bf0de2 Mon Sep 17 00:00:00 2001 From: Shawn Chen Date: Wed, 12 Aug 2026 19:53:29 +1200 Subject: [PATCH 9/9] Only propose the bump when the tested commit is still the tip MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Accepting a "behind" compare status rooted the bump at the tested commit but still opened it against the default branch, so merging adopted the engine together with whatever landed while the matrix ran — commits no run exercised against that engine. Nothing would catch it either: the bump carries no CI by design, so the pull request would be merged on the strength of a body describing a run that never saw that code. The check now requires "identical". When the default branch has moved it declines and reports why, and the verdict issue stays open saying the engine is fine, the pin is unchanged, and the check wants a rerun. Given how rarely these repositories take a commit during a release, declining costs a rerun; the alternative costs a claim that is not true. Exercised all four report outcomes against a stubbed gh: green closes and links the PR; a failed bump job, an unproposed bump and a failed suite each stay open with their own explanation. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/engine-release-check.yml | 30 +++++++++++++++------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/.github/workflows/engine-release-check.yml b/.github/workflows/engine-release-check.yml index e0c9473..dbe6ddb 100644 --- a/.github/workflows/engine-release-check.yml +++ b/.github/workflows/engine-release-check.yml @@ -102,6 +102,7 @@ jobs: pull-requests: write outputs: pr: ${{ steps.bump.outputs.pr }} + unproposed: ${{ steps.bump.outputs.unproposed }} steps: # The commit the suite actually ran against, not whatever the default branch # has become since. github.sha is fixed for the whole run, so this is the @@ -130,16 +131,17 @@ jobs: exit 1 ;; esac - # A manual run from a branch that is not the default one would carry that - # branch's other changes into the bump. "behind" means the tested commit - # is an ancestor of the default branch; "identical" means it is the tip. + # Only when the tested commit is still the tip of the default branch. + # Anything else means merging the bump would adopt commits no run + # exercised against this engine, and the bump carries no CI to catch it. + # Declining and saying why beats a pull request claiming more than the + # run established. rel=$(gh api "repos/$GITHUB_REPOSITORY/compare/$DEFAULT_BRANCH...$GITHUB_SHA" --jq .status) - case "$rel" in - identical|behind) ;; - *) - echo "tested commit $GITHUB_SHA is $rel relative to $DEFAULT_BRANCH; not proposing a bump" - exit 0 ;; - esac + if [ "$rel" != identical ]; then + echo "unproposed=The tested commit $GITHUB_SHA is $rel relative to $DEFAULT_BRANCH, so nothing was proposed" >> "$GITHUB_OUTPUT" + echo "declining to propose a bump: $rel" + exit 0 + fi current=$(grep -E '^CHDB_ENGINE_PIN=' update_libchdb.sh | cut -d= -f2) if [ "$current" = "$ENGINE_VERSION" ]; then @@ -211,6 +213,7 @@ jobs: RESULT: ${{ needs.test.result }} BUMP_PR: ${{ needs.propose_bump.outputs.pr }} BUMP_RESULT: ${{ needs.propose_bump.result }} + BUMP_UNPROPOSED: ${{ needs.propose_bump.outputs.unproposed }} ENGINE_VERSION: ${{ github.event.client_payload.tag || github.event.inputs.engine_version }} RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} run: | @@ -227,6 +230,9 @@ jobs: verdict="passes, bump PR did not open" keep=1 bump_broke=1 + elif [ -n "$BUMP_UNPROPOSED" ]; then + verdict="passes, no bump proposed" + keep=1 else verdict="passes" keep=0 @@ -235,6 +241,8 @@ jobs: { if [ "$bump_broke" = 1 ]; then echo "chdb-node passes against chdb-core \`$ENGINE_VERSION\`, but the bump PR did not open." + elif [ -n "$BUMP_UNPROPOSED" ]; then + echo "chdb-node passes against chdb-core \`$ENGINE_VERSION\`, but no bump was proposed." else echo "chdb-node $verdict against chdb-core \`$ENGINE_VERSION\`." fi @@ -243,6 +251,10 @@ jobs: if [ -n "$BUMP_PR" ]; then echo echo "Adopting it: $BUMP_PR" + elif [ -n "$BUMP_UNPROPOSED" ]; then + echo + echo "$BUMP_UNPROPOSED. The engine is fine and the pin is unchanged; rerun" + echo "the check once the default branch stops moving, or move the pin by hand." elif [ "$bump_broke" = 1 ]; then echo echo "The engine is fine; the automation is not. The pull request moving the"