diff --git a/.github/workflows/gnd-binary-build.yml b/.github/workflows/gnd-binary-build.yml index ca31d660263..a5fe6842647 100644 --- a/.github/workflows/gnd-binary-build.yml +++ b/.github/workflows/gnd-binary-build.yml @@ -46,49 +46,17 @@ jobs: if: startsWith(matrix.runner, 'ubuntu') run: | sudo apt-get update - sudo apt-get install -y libpq-dev protobuf-compiler musl-tools libssl-dev + sudo apt-get install -y protobuf-compiler musl-tools - name: Install dependencies (macOS) if: startsWith(matrix.runner, 'macos') run: | - brew install postgresql protobuf + brew install protobuf - name: Install protobuf (Windows) if: startsWith(matrix.runner, 'windows') run: choco install protoc - - name: Cache vcpkg - uses: actions/cache@v4 - if: startsWith(matrix.runner, 'windows') - id: vcpkg-cache - with: - path: | - ${{ github.workspace }}/vcpkg - C:/vcpkg/installed - C:/vcpkg/packages - key: ${{ runner.os }}-vcpkg-${{ hashFiles('**/Cargo.lock') }} - restore-keys: | - ${{ runner.os }}-vcpkg- - - - name: Install vcpkg and dependencies (Windows) - if: startsWith(matrix.runner, 'windows') && steps.vcpkg-cache.outputs.cache-hit != 'true' - run: | - # Install vcpkg - git clone https://github.com/microsoft/vcpkg.git - cd vcpkg - .\bootstrap-vcpkg.bat - - # Install libpq using vcpkg - .\vcpkg.exe install libpq:x64-windows - shell: pwsh - - - name: Set Windows environment variables - if: startsWith(matrix.runner, 'windows') - run: | - echo "VCPKG_ROOT=${{ github.workspace }}/vcpkg" | Out-File -FilePath $env:GITHUB_ENV -Append - echo "LIBPQ_DIR=${{ github.workspace }}/vcpkg/installed/x64-windows" | Out-File -FilePath $env:GITHUB_ENV -Append - echo "RUSTFLAGS=-L ${{ github.workspace }}/vcpkg/installed/x64-windows/lib" | Out-File -FilePath $env:GITHUB_ENV -Append - shell: pwsh - name: Build gnd binary (Unix/Mac) if: ${{ !startsWith(matrix.runner, 'windows') }} @@ -97,9 +65,6 @@ jobs: - name: Build gnd binary (Windows) if: startsWith(matrix.runner, 'windows') run: cargo build --bin gnd --release --target ${{ matrix.target }} - env: - LIBPQ_DIR: ${{ format('{0}/vcpkg/installed/x64-windows', github.workspace) }} - VCPKGRS_DYNAMIC: 1 - name: Sign macOS binary if: startsWith(matrix.runner, 'macos') diff --git a/Cargo.lock b/Cargo.lock index ce8de699bbb..88bd11361ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1906,6 +1906,27 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "gnd" +version = "0.36.0" +dependencies = [ + "anyhow", + "clap", + "env_logger", + "git-testament", + "globset", + "graph", + "graph-core", + "graph-node", + "lazy_static", + "notify", + "openssl-sys", + "pgtemp", + "pq-sys", + "serde", + "tokio", +] + [[package]] name = "graph" version = "0.36.0" @@ -2119,7 +2140,6 @@ dependencies = [ "json-structural-diff", "lazy_static", "notify", - "pgtemp", "prometheus", "serde", "shellexpand", @@ -4006,12 +4026,24 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "pq-src" +version = "0.3.9+libpq-17.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24ee82a51d19317d15e43b82e496db215ad5bf09a245786e7ac75cb859e5ba46" +dependencies = [ + "cc", + "openssl-sys", +] + [[package]] name = "pq-sys" -version = "0.6.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a24ff9e4cf6945c988f0db7005d87747bf72864965c3529d259ad155ac41d584" +checksum = "dfd6cf44cca8f9624bc19df234fc4112873432f5fda1caff174527846d026fa9" dependencies = [ + "libc", + "pq-src", "vcpkg", ] @@ -6904,7 +6936,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3bab093bdd303a1240bb99b8aba8ea8a69ee19d34c9e2ef9594e708a4878820" dependencies = [ - "windows-link 0.1.1", + "windows-link 0.1.3", "windows-result", "windows-strings", ] @@ -6915,7 +6947,7 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ - "windows-link 0.1.1", + "windows-link 0.1.3", ] [[package]] @@ -6924,7 +6956,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ - "windows-link 0.1.1", + "windows-link 0.1.3", ] [[package]] @@ -7000,7 +7032,7 @@ version = "0.53.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" dependencies = [ - "windows-link", + "windows-link 0.1.3", "windows_aarch64_gnullvm 0.53.0", "windows_aarch64_msvc 0.53.0", "windows_i686_gnu 0.53.0", diff --git a/Cargo.toml b/Cargo.toml index 7ba859ced56..2620237e28e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ members = [ "chain/ethereum", "chain/near", "chain/substreams", + "gnd", "graphql", "node", "runtime/derive", diff --git a/gnd/Cargo.toml b/gnd/Cargo.toml new file mode 100644 index 00000000000..80966f9bfa4 --- /dev/null +++ b/gnd/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "gnd" +version.workspace = true +edition.workspace = true + +[[bin]] +name = "gnd" +path = "src/main.rs" + +[dependencies] +# Core graph dependencies +graph = { path = "../graph" } +graph-core = { path = "../core" } +graph-node = { path = "../node" } + +# Direct dependencies from current dev.rs +anyhow = { workspace = true } +clap = { workspace = true } +env_logger = "0.11.8" +git-testament = "0.2" +lazy_static = "1.5.0" +tokio = { workspace = true } +serde = { workspace = true } + +# File watching +notify = "8.2.0" +globset = "0.4.16" +pq-sys = { version = "0.7.2", features = ["bundled"] } +openssl-sys = { version = "0.9.100", features = ["vendored"] } + +[target.'cfg(unix)'.dependencies] +pgtemp = { git = "https://github.com/graphprotocol/pgtemp", branch = "initdb-args" } \ No newline at end of file diff --git a/node/src/dev/mod.rs b/gnd/src/lib.rs similarity index 50% rename from node/src/dev/mod.rs rename to gnd/src/lib.rs index 20d269524b3..887d28c69de 100644 --- a/node/src/dev/mod.rs +++ b/gnd/src/lib.rs @@ -1,2 +1 @@ -pub mod helpers; pub mod watcher; diff --git a/node/src/bin/dev.rs b/gnd/src/main.rs similarity index 96% rename from node/src/bin/dev.rs rename to gnd/src/main.rs index cad3dc166f1..8837560fde2 100644 --- a/node/src/bin/dev.rs +++ b/gnd/src/main.rs @@ -12,19 +12,16 @@ use graph::{ tokio::{self, sync::mpsc}, }; use graph_core::polling_monitor::ipfs_service; -use graph_node::{ - dev::watcher, - dev::watcher::{parse_manifest_args, watch_subgraphs}, - launcher, - opt::Opt, -}; +use graph_node::{launcher, opt::Opt}; use lazy_static::lazy_static; +use gnd::watcher::{deploy_all_subgraphs, parse_manifest_args, watch_subgraphs}; + #[cfg(unix)] use pgtemp::{PgTempDB, PgTempDBBuilder}; // Add an alias for the temporary Postgres DB handle. On non unix -// targets we don’t have pgtemp, but we still need the type to satisfy the +// targets we don't have pgtemp, but we still need the type to satisfy the // function signatures. #[cfg(unix)] type TempPgDB = PgTempDB; @@ -39,7 +36,7 @@ lazy_static! { #[derive(Clone, Debug, Parser)] #[clap( name = "gnd", - about = "Graph Node Dev", + about = "Graph Node Dev", author = "Graph Protocol, Inc.", version = RENDERED_TESTAMENT.as_str() )] @@ -259,8 +256,7 @@ async fn main() -> Result<()> { }); if let Err(e) = - watcher::deploy_all_subgraphs(&logger, &manifests_paths, &source_subgraph_aliases, &tx) - .await + deploy_all_subgraphs(&logger, &manifests_paths, &source_subgraph_aliases, &tx).await { error!(logger, "Error deploying subgraphs"; "error" => e.to_string()); std::process::exit(1); diff --git a/node/src/dev/watcher.rs b/gnd/src/watcher.rs similarity index 89% rename from node/src/dev/watcher.rs rename to gnd/src/watcher.rs index a5e5caa6145..743b45f0391 100644 --- a/node/src/dev/watcher.rs +++ b/gnd/src/watcher.rs @@ -9,11 +9,43 @@ use std::path::{Path, PathBuf}; use std::sync::mpsc; use std::time::Duration; -use super::helpers::{parse_alias, parse_manifest_arg}; - const WATCH_DELAY: Duration = Duration::from_secs(5); const DEFAULT_BUILD_DIR: &str = "build"; +/// Parse an alias string into a tuple of (alias_name, manifest, Option) +pub fn parse_alias(alias: &str) -> anyhow::Result<(String, String, Option)> { + let mut split = alias.split(':'); + let alias_name = split.next(); + let alias_value = split.next(); + + if alias_name.is_none() || alias_value.is_none() || split.next().is_some() { + return Err(anyhow::anyhow!( + "Invalid alias format: expected 'alias=[BUILD_DIR:]manifest', got '{}'", + alias + )); + } + + let alias_name = alias_name.unwrap().to_owned(); + let (manifest, build_dir) = parse_manifest_arg(alias_value.unwrap()) + .with_context(|| format!("While parsing alias '{}'", alias))?; + + Ok((alias_name, manifest, build_dir)) +} + +/// Parse a manifest string into a tuple of (manifest, Option) +pub fn parse_manifest_arg(value: &str) -> anyhow::Result<(String, Option)> { + match value.split_once(':') { + Some((manifest, build_dir)) if !manifest.is_empty() => { + Ok((manifest.to_owned(), Some(build_dir.to_owned()))) + } + Some(_) => Err(anyhow::anyhow!( + "Invalid manifest arg: missing manifest in '{}'", + value + )), + None => Ok((value.to_owned(), None)), + } +} + // Parses manifest arguments and returns a vector of paths to the manifest files pub fn parse_manifest_args( manifests: Vec, diff --git a/node/Cargo.toml b/node/Cargo.toml index faeeae5f396..5b7f051efe1 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -12,10 +12,6 @@ path = "src/main.rs" name = "graphman" path = "src/bin/manager.rs" -[[bin]] -name = "gnd" -path = "src/bin/dev.rs" - [dependencies] anyhow = { workspace = true } env_logger = "0.11.8" @@ -45,6 +41,3 @@ prometheus = { version = "0.14.0", features = ["push"] } json-structural-diff = { version = "0.2", features = ["colorize"] } globset = "0.4.16" notify = "8.2.0" - -[target.'cfg(unix)'.dependencies] -pgtemp = { git = "https://github.com/graphprotocol/pgtemp", branch = "initdb-args" } diff --git a/node/src/dev/helpers.rs b/node/src/helpers.rs similarity index 72% rename from node/src/dev/helpers.rs rename to node/src/helpers.rs index 19af9d23382..c8b7ccd2a24 100644 --- a/node/src/dev/helpers.rs +++ b/node/src/helpers.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use anyhow::{Context, Result}; +use anyhow::Result; use graph::prelude::{ BlockPtr, DeploymentHash, NodeId, SubgraphRegistrarError, SubgraphStore as SubgraphStoreTrait, }; @@ -12,11 +12,6 @@ use graph::{ }; use graph_store_postgres::SubgraphStore; -pub struct DevModeContext { - pub watch: bool, - pub updates_rx: Receiver<(DeploymentHash, SubgraphName)>, -} - /// Cleanup a subgraph /// This is used to remove a subgraph before redeploying it when using the watch flag fn cleanup_dev_subgraph( @@ -62,7 +57,7 @@ async fn deploy_subgraph( }) } -pub async fn drop_and_recreate_subgraph( +async fn drop_and_recreate_subgraph( logger: &Logger, subgraph_store: Arc, subgraph_registrar: Arc, @@ -124,37 +119,3 @@ pub async fn watch_subgraph_updates( error!(logger, "Subgraph watcher terminated unexpectedly"; "action" => "exiting"); std::process::exit(1); } - -/// Parse an alias string into a tuple of (alias_name, manifest, Option) -pub fn parse_alias(alias: &str) -> anyhow::Result<(String, String, Option)> { - let mut split = alias.split(':'); - let alias_name = split.next(); - let alias_value = split.next(); - - if alias_name.is_none() || alias_value.is_none() || split.next().is_some() { - return Err(anyhow::anyhow!( - "Invalid alias format: expected 'alias=[BUILD_DIR:]manifest', got '{}'", - alias - )); - } - - let alias_name = alias_name.unwrap().to_owned(); - let (manifest, build_dir) = parse_manifest_arg(alias_value.unwrap()) - .with_context(|| format!("While parsing alias '{}'", alias))?; - - Ok((alias_name, manifest, build_dir)) -} - -/// Parse a manifest string into a tuple of (manifest, Option) -pub fn parse_manifest_arg(value: &str) -> anyhow::Result<(String, Option)> { - match value.split_once(':') { - Some((manifest, build_dir)) if !manifest.is_empty() => { - Ok((manifest.to_owned(), Some(build_dir.to_owned()))) - } - Some(_) => Err(anyhow::anyhow!( - "Invalid manifest arg: missing manifest in '{}'", - value - )), - None => Ok((value.to_owned(), None)), - } -} diff --git a/node/src/launcher.rs b/node/src/launcher.rs index 4441131a52e..5642c5f6f5e 100644 --- a/node/src/launcher.rs +++ b/node/src/launcher.rs @@ -6,7 +6,7 @@ use graph::futures03::compat::Future01CompatExt; use graph::futures03::future::TryFutureExt; use crate::config::Config; -use crate::dev::helpers::watch_subgraph_updates; +use crate::helpers::watch_subgraph_updates; use crate::network_setup::Networks; use crate::opt::Opt; use crate::store_builder::StoreBuilder; diff --git a/node/src/lib.rs b/node/src/lib.rs index 7b3d4347ee8..a0fe189f1f7 100644 --- a/node/src/lib.rs +++ b/node/src/lib.rs @@ -7,7 +7,7 @@ extern crate diesel; pub mod chain; pub mod config; -pub mod dev; +mod helpers; pub mod launcher; pub mod manager; pub mod network_setup;