Skip to content

merge hotfixes back to dev - #2100

Open
pikonha wants to merge 9 commits into
devfrom
main
Open

merge hotfixes back to dev#2100
pikonha wants to merge 9 commits into
devfrom
main

Conversation

@pikonha

@pikonha pikonha commented Aug 1, 2026

Copy link
Copy Markdown
Member

Note

Medium Risk
Changes CI/deploy blocking behavior and health API contracts; misconfigured EXPECTED_UPSTREAM_SHAS or git resolution could delay or fail deploys, but runtime app logic outside health/deploy is largely unchanged.

Overview
Fixes dashboard/SDK builds racing gateful while DAO APIs, relayer, and address-enrichment still serve an older merged OpenAPI spec on /docs/json.

Upstream commit reporting: Those services expose commit from RAILWAY_GIT_COMMIT_SHA on /health. Gateful forwards each upstream’s kind and commit in its own /health response.

Deploy gate: scripts/wait-for-gateful.mjs now requires gateful’s commit and that spec-contributing upstreams report SHAs in EXPECTED_UPSTREAM_SHAS (resolved in deploy and PR workflows from git history over each service’s Railway watch paths — “that commit or newer”; missing commit counts as stale). Checkouts use full history so that resolution works.

Turbo: @anticapture/client codegen and build are no longer cached, because the live spec URL can’t be hashed and stale generated/dist output could stick across retries.

Reviewed by Cursor Bugbot for commit 059370d. Configure here.

pikonha and others added 9 commits August 1, 2026 11:33
Gateful merges the DAO APIs' OpenAPI specs into /docs/json on every request,
so waiting for gateful's own commit said nothing about the schemas it would
serve. On #2093 gateful reported the new commit at 14:33:54, the dashboard's
codegen read the spec at 14:34:23, and ens-api only came up at 14:34:34 — the
build typechecked against the previous contract and failed on scoresTotal.

The DAO API now reports its running commit on /health, gateful surfaces it as
upstreams.<dao>.commit, and wait-for-gateful waits for every upstream that
reports one. That is enabled only when the push touches the paths Railway
watches to rebuild those APIs, so releases that leave them alone are not
blocked waiting for a rebuild that will never happen.

Also stop caching @anticapture/client#codegen: its real input is the live
gateful spec, which no hash can see, so the raced output was replayed on every
retry of that commit and no re-run could ever fix it.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
…ad compare

Two review findings on the gate.

A DAO API that reports no commit was being skipped, which is exactly the state
of every API during this release's own rollout — the field ships with it. The
gate would have passed the moment gateful updated, reproducing the race. DAO
APIs now have to report the expected commit; gateful labels each upstream with
a `kind` so relayers, address enrichment and authful stay exempt.

A failing `gh api` inside an `if` was indistinguishable from "no API change",
so a rate limit or outage would silently drop the gate on the releases that
need it most. It now runs as its own command, where set -e fails the step.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
A third review finding: with `cancel-in-progress`, a non-API push landing while
an API push is still deploying cancels the earlier waiter, and asking "did THIS
push change the API" answers no — so the gate stood down while the APIs were
still serving the pre-release spec.

The workflow now resolves the last commit that touched the paths Railway
watches for the DAO APIs, and passes that commit plus every commit after it.
A superseding push resolves the same API commit and keeps waiting for it, and
accepting "or newer" also covers Railway stamping a service with the head of a
multi-commit push rather than the commit that changed it.

This drops the REQUIRE_UPSTREAM_COMMIT flag and the compare API call along with
it — git already knows, so there is no request left to fail.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
…he DAO APIs

A fourth review finding, and a factual correction to a comment I wrote: the
relayer and address enrichment also contribute paths and schemas to
/docs/json via mergeUpstreamDocs, so a release changing either of them could
reproduce the same stale-spec race the DAO API gate was closing.

Both now report their commit on /health, and the expected commits are resolved
per upstream kind from that service's own Railway watch paths — a relayer
release waits for the relayer, not for the APIs. Authful stays exempt: its
spec is not merged, so it only has to be reachable.

Requiring a commit cannot deadlock these two either: teaching a service to
report its commit necessarily touches its own watched paths, so the release
that adds the field is also the release that rebuilds it.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This PR's own preview build failed exactly the way production did: codegen ran
at 16:10:45 while the preview relayer, redeployed at 16:07 because this branch
touches apps/relayer, was still coming up. Gateful served a spec whose relay
paths had no matching schemas, so the generated sdk.ts imported types models.ts
never got and the SDK build failed on them. Re-running with no code change
passed, which is the race admitting what it is.

The preview waiter only ever checked gateful's own commit, so it had none of
the protection deploy.yaml just gained. It now resolves the same per-upstream
commit sets from the PR head. Untrusted PRs point at shared dev gateful and
already leave the expected commit unset; the upstream check rides along with
it and stays off for them.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Re-running codegen on a retry was pointless while `@anticapture/client#build`
still hashed the same: `generated/**` is gitignored, so it never entered that
task's input set, and turbo would restore the `dist` compiled from the stale
spec over the freshly generated one. The dashboard build hashes the client
build in turn, so it inherited the same blindness.

Listing `generated/**` explicitly makes the spec visible to both hashes while
keeping the cache useful when the spec really is unchanged.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
78a5329 declared `generated/**` as an input to `@anticapture/client#build`,
which does not work: turbo hashes inputs before the run, and the directory is
gitignored, so on a fresh checkout the glob matches nothing at hash time. The
retry hashed identically to the poisoned run and restored its `dist`.

Reproduced in isolation with turbo 2.8.16 — a cache:false codegen writing a
gitignored dir, a cached build consuming it, the same hash across both runs
and the stale output replayed on top of fresh generated files.

tsup runs with `dts: true`, so the spec fetched at runtime is compiled into
`dist` and no hash can see it — the same reason codegen is uncached. The build
is ~6s, so this is cheap. `@anticapture/dashboard#build` keeps its cache: turbo
only caches successes, and it is the task that fails in this mode.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
fix(ci): gate the production deploy on the API release, not just gateful
@vercel

vercel Bot commented Aug 1, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
anticapture-storybook Ready Ready Preview Aug 1, 2026 4:52pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
anticapture Ignored Ignored Aug 1, 2026 4:52pm

Request Review

@railway-app

railway-app Bot commented Aug 1, 2026

Copy link
Copy Markdown

🚅 Deployed to the anticapture-pr-2100 environment in anticapture-infra

Service Status Web Updated (UTC)
shutter-indexer-offchain ✅ Success (View Logs) Aug 2, 2026 at 9:14 am
uniswap-indexer-offchain ✅ Success (View Logs) Aug 2, 2026 at 9:14 am
ens-indexer-offchain ✅ Success (View Logs) Aug 2, 2026 at 9:14 am
gitcoin-indexer-offchain ✅ Success (View Logs) Aug 2, 2026 at 9:14 am
compound-indexer-offchain ✅ Success (View Logs) Aug 2, 2026 at 9:13 am
prometheus ✅ Success (View Logs) Aug 1, 2026 at 5:54 pm
grafana ✅ Success (View Logs) Web Aug 1, 2026 at 5:53 pm
lil-nouns-indexer ✅ Success (View Logs) Aug 1, 2026 at 4:55 pm
tornado-indexer ✅ Success (View Logs) Aug 1, 2026 at 4:55 pm
docs ✅ Success (View Logs) Web Aug 1, 2026 at 4:55 pm
mcp ✅ Success (View Logs) Web Aug 1, 2026 at 4:55 pm
gateful ✅ Success (View Logs) Web Aug 1, 2026 at 4:55 pm
obol-indexer ✅ Success (View Logs) Aug 1, 2026 at 4:55 pm
tornado-api ✅ Success (View Logs) Aug 1, 2026 at 4:55 pm
uniswap-indexer ✅ Success (View Logs) Aug 1, 2026 at 4:55 pm
aave-indexer ✅ Success (View Logs) Aug 1, 2026 at 4:55 pm
gitcoin-indexer ✅ Success (View Logs) Aug 1, 2026 at 4:55 pm
nouns-api ✅ Success (View Logs) Aug 1, 2026 at 4:55 pm
address-enrichment ✅ Success (View Logs) Web Aug 1, 2026 at 4:55 pm
aave-api ✅ Success (View Logs) Aug 1, 2026 at 4:55 pm
ens-indexer ✅ Success (View Logs) Aug 1, 2026 at 4:55 pm
fluid-api ✅ Success (View Logs) Aug 1, 2026 at 4:55 pm
ens-api ✅ Success (View Logs) Aug 1, 2026 at 4:55 pm
fluid-indexer ✅ Success (View Logs) Aug 1, 2026 at 4:54 pm
compound-api ✅ Success (View Logs) Aug 1, 2026 at 4:54 pm
lil-nouns-api ✅ Success (View Logs) Aug 1, 2026 at 4:54 pm
uniswap-api ✅ Success (View Logs) Aug 1, 2026 at 4:54 pm
nouns-indexer ✅ Success (View Logs) Aug 1, 2026 at 4:54 pm
ens-relayer ✅ Success (View Logs) Aug 1, 2026 at 4:54 pm
gitcoin-api ✅ Success (View Logs) Aug 1, 2026 at 4:54 pm
obol-api ✅ Success (View Logs) Aug 1, 2026 at 4:54 pm
scroll-indexer ✅ Success (View Logs) Aug 1, 2026 at 4:54 pm
compound-indexer ✅ Success (View Logs) Aug 1, 2026 at 4:54 pm
shutter-indexer ✅ Success (View Logs) Aug 1, 2026 at 4:54 pm
shutter-api ✅ Success (View Logs) Aug 1, 2026 at 4:54 pm
erpc ✅ Success (View Logs) Web Aug 1, 2026 at 4:54 pm
otelcol ✅ Success (View Logs) Aug 1, 2026 at 4:54 pm
nodeful ✅ Success (View Logs) Aug 1, 2026 at 4:54 pm
tempo ✅ Success (View Logs) Aug 1, 2026 at 4:54 pm
user-api ✅ Success (View Logs) Web Aug 1, 2026 at 4:54 pm
alertmanager ✅ Success (View Logs) Web Aug 1, 2026 at 4:53 pm
loki ✅ Success (View Logs) Aug 1, 2026 at 4:53 pm
scroll-api ✅ Success (View Logs) Aug 1, 2026 at 4:53 pm
authful ✅ Success (View Logs) Web Aug 1, 2026 at 4:53 pm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant