Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/check-shell.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ jobs:
- run: nix develop --command cargo release --version
- run: nix develop --command flamegraph --help
- run: nix develop --command graph --version
- run: nix develop --command goldsky --version
- run: nix develop --command yq --version
- run: nix develop --command gh --version
- run: nix develop --command default-shell-test
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,6 @@ candidates at all is left exactly as it is today.
- Solidity: solc 0.8.25
- Foundry: via foundry.nix
- Graph CLI: 0.69.2
- Goldsky CLI: 13.3.4

## License

Expand Down
71 changes: 13 additions & 58 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -148,36 +148,6 @@
'';
};

goldsky = pkgs.stdenv.mkDerivation rec {
pname = "goldsky";
version = "13.3.4";
src =
let
release-name = "13.3.4";
system-mapping = {
x86_64-linux = "linux";
x86_64-darwin = "macos";
aarch64-darwin = "macos";
};
system-sha = {
x86_64-linux = "sha256:1wg09vz652hv3hb0w7mx7hjxm00c857h2a8kd2vj11wnik8gh73m";
x86_64-darwin = "sha256:048w06x56lk84h9x8q2jf7mdxx8lyzd9nrkxsmfkj39rns1nr4yk";
aarch64-darwin = "sha256:048w06x56lk84h9x8q2jf7mdxx8lyzd9nrkxsmfkj39rns1nr4yk";
};
in
builtins.fetchurl {
url = "https://cli.goldsky.com/${release-name}/${system-mapping.${system}}/goldsky";
sha256 = system-sha.${system};
};
buildInputs = [ ];
phases = [ "installPhase" ];
installPhase = ''
mkdir -p $out/bin
cp $src $out/bin/goldsky
chmod +x $out/bin/goldsky
'';
};

# rainix-curated prettier bundle: a single nix-built node_modules
# tree containing prettier + the standardized plugins, plus a
# .prettierrc.json picked up via PRETTIER_BUNDLE_DIR. Consumers
Expand Down Expand Up @@ -426,33 +396,20 @@
'';
};

# Tracing stays off for the whole task: ORMI_DEPLOY_KEY is a credential
# and `set -x` would print it. The logic lives in lib/subgraph-deploy.sh.
subgraph-deploy = mkTask {
name = "subgraph-deploy";
body = ''
set -euxo pipefail
set -euo pipefail
source ${./lib/subgraph.sh}
source ${./lib/subgraph-deploy.sh}

# subgraph/abis and subgraph/generated are committed, so the deploy
# builds the subgraph directly from them with just the graph +
# goldsky toolchain — the same committed-artifact path as
# subgraph-test, slim enough for the subgraph shell.
(cd ./subgraph && ${pkgs.nodejs_22}/bin/npm ci)

commit="$(${pkgs.git}/bin/git rev-parse --short HEAD)"
for network in $(subgraph_networks ./subgraph/networks.json); do
address=$(subgraph_network_address ./subgraph/networks.json "$network")
version=$(subgraph_deploy_version "$address" "$commit")
name_and_version="''${GOLDSKY_SUBGRAPH_NAME}-$network/$version"

if ${goldsky}/bin/goldsky --token ''${GOLDSKY_TOKEN} subgraph list "$name_and_version" 2>/dev/null | grep -q "$name_and_version"; then
echo "Subgraph $name_and_version already deployed, skipping."
else
echo "Building subgraph for $network..."
(cd ./subgraph && ${the-graph}/bin/graph build --network "$network")
echo "Deploying subgraph $name_and_version..."
(cd ./subgraph && ${goldsky}/bin/goldsky --token ''${GOLDSKY_TOKEN} subgraph deploy "$name_and_version")
fi
done
subgraph_deploy \
${the-graph}/bin/graph \
${pkgs.nodejs_22}/bin/npm \
${pkgs.git}/bin/git \
${rainix-static}/bin/rainix-static
'';
additionalBuildInputs = node-build-inputs;
};
Expand Down Expand Up @@ -486,6 +443,7 @@
bats test/bats/task/skip-simulation.test.bats
bats test/bats/task/subgraph-build.test.bats
bats test/bats/task/subgraph-deploy-version.test.bats
bats test/bats/task/subgraph-deploy.test.bats
bats test/bats/task/sol-single-contract.test.bats
bats test/bats/task/no-custom-natspec.test.bats
bats test/bats/workflow/rainix-sol-static.test.bats
Expand Down Expand Up @@ -783,18 +741,16 @@
'';
};

# Slim shell for subgraph repos: node + the-graph + goldsky +
# subgraph-tasks. No rust, no foundry, no sqlite/yq/age. Lets
# consumers avoid the heavy default closure when CI is just
# subgraph-test.
# Slim shell for subgraph repos: node + the-graph + subgraph-tasks. No
# rust, no foundry, no sqlite/yq/age. Lets consumers avoid the heavy
# default closure when CI is just subgraph-test.
subgraph-shell = pkgs.mkShell {
buildInputs =
node-build-inputs
++ subgraph-tasks
++ common-shell-inputs
++ [
the-graph
goldsky
];
shellHook = ''
${pre-commit.shellHook}
Expand All @@ -812,7 +768,6 @@
++ common-shell-inputs
++ [
the-graph
goldsky
pkgs.sqlite
pkgs.yq-go
pkgs.age
Expand Down
103 changes: 103 additions & 0 deletions lib/subgraph-deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#!/usr/bin/env bash

# Orchestration for the `subgraph-deploy` task. Every decision that reads data
# (is this version live? is the name safe in a URL?) is made by
# `rainix-static ormi-probe`; this file only wires steps together.
# Requires lib/subgraph.sh to be sourced first.

# Fail (naming the variable, never its value) unless every named env var is set
# and non-empty.
# Usage: subgraph_require_env <VAR>...
subgraph_require_env() {
local var
for var in "$@"; do
if [ -z "${!var:-}" ]; then
echo "$var is required" >&2
return 1
fi
done
}

# Deploy every network in subgraph/networks.json to Ormi as
# <SUBGRAPH_NAME>-<network> at version label <address>-<commit>, skipping a
# version Ormi already hosts. The deployment name and label keep the Goldsky-era
# shape so an Ormi tag can move between versions.
#
# One network failing does not stop the others: a probe that cannot get a
# trustworthy answer (including a deployed version that is failed or still
# syncing) or a failed deploy is recorded, the loop moves on, and the task
# fails at the end naming every network that did not complete. A network whose
# probe failed is never deployed.
#
# The tools are arguments, not PATH lookups, so the task pins them to store
# paths and tests can substitute stubs.
# Usage: subgraph_deploy <graph> <npm> <git> <rainix-static>
#
# Secret handling, since ORMI_DEPLOY_KEY is a credential:
# - Tracing is switched off first. `set -x` (or `bash -x`) would print the key
# the moment it is expanded, including in the presence check below.
# - The key is moved out of the environment into a local before anything runs,
# so git, jq, npm, the probe and graph-cli never inherit it.
# - Only the hardcoded Ormi deploy endpoint ever receives the key. The
# configurable ORMI_QUERY_BASE is used for the read-only probe alone.
# - Not closed: `graph deploy` takes the key as an argument (no env or stdin
# form), and it compiles the subgraph itself, so the subgraph's
# AssemblyScript toolchain runs with the key visible in the process table.
# Install scripts from `npm ci` also run on this runner, and one that leaves
# a background process behind could read it. A subgraph repo's dependencies
# are therefore trusted with this credential.
subgraph_deploy() {
set +x
local graph="$1" npm="$2" git="$3" static="$4"
local ormi_node="https://subgraph.api.ormilabs.com/deploy"
local ormi_ipfs="https://subgraph.api.ormilabs.com/ipfs"

subgraph_require_env ORMI_DEPLOY_KEY SUBGRAPH_NAME ORMI_QUERY_BASE || return 1
Comment thread
Siddharth2207 marked this conversation as resolved.
local deploy_key="$ORMI_DEPLOY_KEY"
unset ORMI_DEPLOY_KEY

# subgraph/abis and subgraph/generated are committed, so the deploy compiles
# the subgraph directly from them.
(cd ./subgraph && "$npm" ci)

local commit network address version name rc
local failed=""
commit="$("$git" rev-parse --short HEAD)"
for network in $(subgraph_networks ./subgraph/networks.json); do
Comment thread
Siddharth2207 marked this conversation as resolved.
Comment thread
Siddharth2207 marked this conversation as resolved.
address="$(subgraph_network_address ./subgraph/networks.json "$network")"
version="$(subgraph_deploy_version "$address" "$commit")"
name="${SUBGRAPH_NAME}-${network}"

# 0 = already deployed, 10 = confirmed missing. Anything else (the probe
# could not get a trustworthy answer) must NOT fall through to a deploy.
rc=0
"$static" ormi-probe --base "$ORMI_QUERY_BASE" --name "$name" --version "$version" || rc=$?
case "$rc" in
0)
echo "Subgraph $name/$version already deployed, skipping."
;;
10)
# graph deploy compiles the manifest itself, so it needs the network.
echo "Deploying subgraph $name/$version..."
if ! (cd ./subgraph && "$graph" deploy "$name" \
Comment thread
Siddharth2207 marked this conversation as resolved.
--network "$network" \
--node "$ormi_node" \
--ipfs "$ormi_ipfs" \
--deploy-key "$deploy_key" \
--version-label "$version"); then
echo "Deploy of $name/$version failed; continuing with the other networks." >&2
failed="$failed $name"
fi
;;
*)
echo "Could not determine whether $name/$version is deployed (probe exit $rc); not deploying it, continuing with the other networks." >&2
failed="$failed $name"
;;
esac
done

if [ -n "$failed" ]; then
echo "Did not complete:$failed" >&2
return 1
fi
}
18 changes: 17 additions & 1 deletion rainix-static/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@
// removed — a deploy repo's generated released-suites lib imports it, so
// removing it makes the tree uncompilable (rainlanguage/rainix#341). Runs
// where git is on PATH.
// ormi-probe --base <ORMI_QUERY_BASE> --name <name> --version <version>
// subgraph-deploy's skip decision: is <name>/<version> already live on
// Ormi? Exit 0 = deployed, 10 = confirmed missing, 1 = anything else
// (transport/HTTP failure after retries, unrecognised body, wrong query
// base, malformed argument) — so a failed probe can never read as "not
// deployed" and trigger a deploy. Needs no secret. Semantics:
// ormi_probe.rs module doc. Runs where curl is on PATH.

mod agent_context_cap;
mod ci_gate;
Expand All @@ -111,6 +118,7 @@ mod context_bytes;
mod frozen_snapshots;
mod mutation_ledger;
mod no_submodules;
mod ormi_probe;
mod prompt_cap;
mod release_guard;
mod rpc_preflight;
Expand Down Expand Up @@ -267,6 +275,14 @@ fn main() {
let foundry = flag(&args, "--foundry").unwrap_or_else(|| "foundry.toml".to_string());
release_guard::run(&version, &root, &foundry);
}
"ormi-probe" => {
let base = flag(&args, "--base")
.unwrap_or_else(|| fail("ormi-probe: --base <query base url> required"));
let name = flag(&args, "--name").unwrap_or_else(|| fail("ormi-probe: --name required"));
let version =
flag(&args, "--version").unwrap_or_else(|| fail("ormi-probe: --version required"));
ormi_probe::run(&base, &name, &version);
}
"rpc-preflight" => {
let root = flag(&args, "--root").unwrap_or_else(|| ".".to_string());
// There is no stdout fallback on purpose: the selected URL may be
Expand Down Expand Up @@ -307,7 +323,7 @@ fn main() {
"rainix-static: unknown subcommand {other:?} \
(available: no-submodules, agent-context-cap, prompt-cap, \
comment-loc-cap, snapshots-append-only, mutation-ledger, ci-gate, soldeer-gate, \
rpc-preflight, release-guard)"
rpc-preflight, release-guard, ormi-probe)"
);
std::process::exit(2);
}
Expand Down
Loading
Loading