Repository navigation
feat(deployments): generate the subgraph manifest from the deployment record - #252
Merged
truthixify merged 1 commit intoOct 17, 2026
Conversation
… record evm/subgraph/subgraph.yaml still carried 0x...dead placeholder addresses for WraithNames, WraithSender and WraithWithdrawer, and both checks let them through: the manifest consumer skipped placeholders for contracts missing from the manifest, and validate-config.js only reads the instant configs. subgraph.yaml becomes subgraph.template.yaml, without network, addresses or start blocks. `npm run subgraph -- --network <slug>` in scripts/deployment-manifest (`npm run manifest` in evm/subgraph) fills them in from deployments/evm/<slug>.json and writes subgraph.yaml, which is git-ignored. It writes nothing and names every offending contract if a data source's contract is not recorded, has no start block or start block 0, or has the placeholder address. `--check` fails unless an existing subgraph.yaml is exactly what the generator writes now for its network; `deploy` and `deploy-local` run it before graph deploy. codegen, build and test read the template (matchstick.yaml sets manifestPath), so CI needs no deployment. The manifest check validates the template instead of subgraph.yaml: every data source must name an EVM contract and must not set network, address or startBlock. horizen-testnet records only the Announcer and Registry, so generation for it fails, naming the other three, until they are recorded.
|
@izzetemredemir Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
truthixify
approved these changes
Oct 17, 2026
truthixify
left a comment
Contributor
There was a problem hiding this comment.
Deployment manifest subgraph generation is structured, fail-closed on missing records, and passes 43 focused tests plus typecheck. Approved.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #233
Summary
evm/subgraph/subgraph.yamlstill had0x000000000000000000000000000000000000deadas the address of WraithNames, WraithSender and WraithWithdrawer (lines 57, 81 and 109 on develop), and both checks accepted it: the manifest consumer skipped placeholders for contracts that are not in the manifest (consumers.ts:72), andvalidate-config.jsonly reads<network>/instant-config.json. On develop,npm run checkpasses with all three placeholders in place.This PR replaces the hand-maintained manifest with a template and a generator in
scripts/deployment-manifest:evm/subgraph/subgraph.yamlis renamed tosubgraph.template.yamland losesnetwork,source.addressandsource.startBlockon every data source (and the three TODO comments). It gains a header comment saying how to generate the manifest; nothing else changes.npm run subgraph -- --network <slug>(inscripts/deployment-manifest), ornpm run manifest -- --network <slug>(inevm/subgraph), readsdeployments/evm/<slug>.jsonwith the same parsing and validationbuildandcheckuse, maps each data source to its catalogue contract bysource.abi, and writesevm/subgraph/subgraph.yamlwithnetwork,source.addressandsource.startBlockfilled in. The generated file is git-ignored.npm run deployandnpm run deploy-localinevm/subgraphnow runnpm run manifest -- --checkbeforegraph deploy.Fails closed
The generator writes nothing and exits 1 if any of these hold, and lists every problem of every contract in one run:
checkapplies;deployment.height), or start block 0 (the placeholder valuevalidate-config.jsalready rejects);0x…dead;network,addressorstartBlockitself, a data source'ssource.abiis not one of the five EVM contracts incatalogue.ts, or the template has atemplates:section (dynamic data sources would also need anetwork, which the generator does not set yet, so it refuses instead of emitting a manifest without one).There is no fallback to a placeholder.
--checkfails unlesssubgraph.yamlexists and is byte-for-byte what the generator writes now for the network the file names. Sonpm run deploystops if the manifest was never generated, was edited by hand, or was generated from a record or template that has changed since. In a fresh checkout there is nosubgraph.yamlat all, so a baregraph deployalso fails; once a manifest has been generated, a baregraph deployskips the check, and the subgraph README says to use the npm scripts.horizen-testnet until #231
deployments/evm/horizen-testnet.jsonrecords only ERC5564Announcer and ERC6538Registry, so today:Once #231 records the three contracts (
npm run record -- evm ...), the same command writes a complete manifest with no other change. The Goldsky instant-subgraph path (horizen-testnet/instant-config.json, two contracts) is unchanged and still checked byvalidate-config.jsand the instant-config consumer.Design
Own template instead of graph-cli's
networks.json+--network. I read graph-cli 0.96.0 (dist/command-helpers/network.js).graph build/deploy --networkrewritessubgraph.yamlin place (re-serialised, comments dropped) and only checks that each data source name has an entry innetworks.json; an entry withoutaddressorstartBlockis accepted and copied as is. We would still need a generator to writenetworks.jsonfrom the record and validate it, and the committedsubgraph.yamlwould change on every deploy. The deployment-manifest package already owns the records, their validation and the consumer pattern, and already depends onyaml, so the template is rendered there with theyamlDocument API. The output keeps the template's layout and comments and is prettier-clean.The generated manifest is not committed. A checked-in
subgraph.yamlfor horizen-testnet cannot be generated until #231, so it would have to keep the placeholders this issue is about. The template is the only committed manifest, andcheck(CI) now validates the template instead: every data source names an EVM contract and none setsnetwork,addressorstartBlock. The oldsubgraph.yamlconsumer is removed.The template is not named
subgraph.yaml. graph-cli defaults tosubgraph.yaml, so only a generated, validated manifest ever has that name.codegenandbuildpass the template path explicitly, and a newevm/subgraph/matchstick.yamlsetsmanifestPath: ./subgraph.template.yamlforgraph test(Matchstick 0.6.0 readsmanifestPathinsrc/config.rs). Matchstick uses the manifest for the schema location, templates and handlers, not for addresses, so the tests do not need a network.Changes
scripts/deployment-manifest/src/subgraph.ts(new):templateErrors,renderSubgraph(template + record, all checks above),generateSubgraph(network)(reads the files),generatedNetwork(for--check).src/cli.ts: newsubgraph --network <slug>/subgraph --checkcommand and usage text.package.json:npm run subgraph.src/manifest.ts: the per-file part ofloadRecordsmoves intoreadRecord(chain, file), soloadRecordsand the generator share it. Behaviour ofloadRecordsis unchanged.src/consumers.ts: thesubgraph.yamlconsumer is replaced by asubgraph.template.yamlconsumer.evm/subgraph:subgraph.yamlrenamed tosubgraph.template.yaml;.gitignoreignores the generated/subgraph.yaml;package.jsongetsmanifest,codegen/buildpoint at the template,deploy/deploy-localrunmanifest -- --checkfirst;matchstick.yamladded.evm/scripts/deploy.ts: the closing hint now prints the generate command (relative toevm/, where the script runs) instead of "Update evm/subgraph/subgraph.yaml to match"; the network slug is computed once..prettierignore: ignores the generatedsubgraph.yaml, like the other generated subgraph paths.src/manifest.tsreadRecordalso reports a record that is valid JSON but not an object (for examplenull) instead of throwing.deployments/README.md(consumer table, a "Subgraph manifest" section, commands table),evm/subgraph/README.md(a "graph-cli manifest" section, structure, horizen-testnet status),evm/README.md(subgraph and deployment sections).Tests
scripts/deployment-manifest/test/check.e2e.test.ts, run through the CLI against a temporary copy of the repository, like the existing tests:subgraph > refuses the checked-in horizen-testnet record, naming the three contracts it lacks: exit 1, names WraithNames, WraithSender and WraithWithdrawer, does not mention the Announcer or Registry, writes no file.subgraph > fills network, address and start block from a record with every contract: the horizen-testnet record plus the three missing contracts (made-up addresses and blocks, only inside the temporary copy). Checks each data source'snetwork,source.addressandsource.startBlockagainst the record, and that with those three keys removed every data source and the top-level keys equal the template.subgraph > fails when a contract has no start blockand... has start block 0.subgraph > fails when a contract has the placeholder address.subgraph > fails for a network without a deployment record.subgraph > --check passes only while the generated manifest matches the template and record: fails before generation, passes after, fails after a hand edit, and fails once the record loses a contract.check > fails when the subgraph template address driftsand... contract driftsreplace the twosubgraph.yamldrift cases: a0x…deadaddress written into the template, and asource.abithat is not a catalogue contract.subgraph > --check refuses a manifest whose data sources name more than one network.subgraph > lists every problem of a contract, not only the first(start block 0 and the placeholder address together).subgraph > reports a record that fails validation and writes nothingand... that is not a JSON object.subgraph > refuses a template with dynamic data source templates.subgraph > refuses a network that is not a slug,... neither --network nor --check,... both --network and --check.Negative check: in a temporary worktree of this branch with
scripts/deployment-manifest/srcandpackage.jsonreset to develop (tests and template from this branch), 18 of the 43 tests fail and the other 25 pass.Commands
All on macOS, Node 22.23.3. Dependencies installed with
npm ci --ignore-scripts.scripts/deployment-manifest(what the Deployment Manifest workflow runs):npm run typecheck: pass.npm test: 43 passed. Develop has 28; the twosubgraph.yamldrift cases are replaced by the two template cases, and 15 tests are new.npm run check:✓ manifest valid; 3 deployments; 8 consumers agree. On develop the same command also passes, with the three placeholders insubgraph.yaml.evm(the EVM job; it runs becauseevm/changed):npx prettier --check --ignore-path ../.prettierignore .: pass.npm run validate-subgraph: pass (unchanged, instant configs only).evm/subgraph:npm run codegenandnpm run buildfrom the template: pass.generated/is identical to develop's, andbuild/differs only inbuild/subgraph.yaml, which no longer hasnetwork,addressandstartBlock.evm/subgraph: a manifest generated from the five-contract fixture, built withgraph build: pass; compared with develop's build, only the three placeholder addresses and start blocks differ.npm run deploy -- <name> --node <url>with nothing generated, andnpm run deploy-localwith a manifest generated from the fixture but checked against the real horizen-testnet record: both exit 1 atmanifest -- --check, beforegraph deploy.npm testinevm/subgraph(Matchstick downloads and runs its own binary, which I did not do here). Matchstick 0.6.0 readsmanifestPathfrommatchstick.yaml(src/config.rs) and uses the manifest only for the schema path,templatesand handler names, none of which change. The EVM job runs it on this PR.hardhat compile/hardhat test, the Foundry invariant tests and gas snapshot, and Slither. This PR changes no Solidity, test or Foundry file;deploy.tsonly changes a log line.Open questions
validate-config.js. The schema allows 0; say if you want it accepted.npm run subgraph -- --network <slug>for every EVM record, so a record that misses a contract fails CI instead of at deploy time. I left it out because it would fail on develop today.networkon data sources only and refuses a template withtemplates:. There are none today; if dynamic data sources are added, the generator should set their network too.