Skip to content

Commit

Permalink
feat: print build info in all services (#753)
Browse files Browse the repository at this point in the history
## Summary
Print build info for all services.

## Background
Astria services emit no build information which means we are potentially
flying blind.

This patch injects various bits of build information using our services'
`build.rs` build scripts and reads them out at compile time. The
injected build information is then printed on stderr immediately after
startup following the convention that informational and debug messages
are not sent to stdout.

The emitted build information is json formatted and looks like so (for
sequencer compiled locally and ran through `jq`. It's not actually
pretty-printed):
```json
{
  "build_timestamp": "2024-02-14T14:13:18.583116000Z",
  "cargo_opt_level": "0",
  "cargo_pkg_name": "astria-sequencer",
  "cargo_target_triple": "aarch64-apple-darwin",
  "git_branch": "superfluffy/version-and-sha-into-services",
  "git_commit_date": "2024-02-14",
  "git_describe": "sequencer-v0.8.0-25-g268bbba",
  "git_sha": "268bbba35155fcf2f218a52afda20557dad8f294",
  "rustc_channel": "stable",
  "rustc_commit_hash": "07dca489ac2d933c78d3c5158e3f43beefeb02ce",
  "rustc_host_triple": "aarch64-apple-darwin"
}
```

## Changes
- Add a new crate `astria-build-info` to emit and inject build
information at compile time
- Update all services to print build info.
- Set the minimum version requirement of `ibc-types` to `0.11.1` because
of conflicts in the version resolution of the `time` dependency (a
mutual dependency of `vergen` and `ibc-types`).

## Testing
Nothing to test as this is fundamentally a thin wrapper around the
functionality provided by the `vergen` crate. All services, composer,
conductor, sequencer, and sequencer-relayer, were executed locally and
observed to emit the expected build info.
  • Loading branch information
SuperFluffy authored Feb 15, 2024
1 parent 96960d8 commit 4d8efb2
Show file tree
Hide file tree
Showing 25 changed files with 292 additions and 5 deletions.
39 changes: 39 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
exclude = ["tools/protobuf-compiler"]

members = [
"crates/astria-build-info",
"crates/astria-celestia-client",
"crates/astria-celestia-mock",
"crates/astria-cli",
Expand All @@ -22,6 +23,7 @@ members = [
# Specify default members so that cargo invocations in github actions will
# not act on lints
default-members = [
"crates/astria-build-info",
"crates/astria-celestia-client",
"crates/astria-celestia-mock",
"crates/astria-cli",
Expand Down Expand Up @@ -60,7 +62,7 @@ hex = "0.4"
hex-literal = "0.4.1"
humantime = "2.1.0"
hyper = "0.14"
ibc-types = "0.11.0"
ibc-types = "0.11.1"
jsonrpsee = { version = "0.20" }
once_cell = "1.17.1"
sha2 = "0.10"
Expand Down
20 changes: 20 additions & 0 deletions crates/astria-build-info/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[package]
name = "astria-build-info"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies.serde]
workspace = true
features = ["derive"]
optional = true

[dependencies.vergen]
version = "8"
features = ["build", "cargo", "rustc", "git", "git2"]
optional = true

[features]
build = ["dep:vergen"]
runtime = ["dep:serde"]
51 changes: 51 additions & 0 deletions crates/astria-build-info/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# `astria-build-info`

Inject build information about services and binaries at compile time.

`astria-build-info` provides the `astria_build_info::emit` utility
and the `astria_build_info::get!` macro to inject build information
into binaries.

`emit` is used to emit environment variables in a binary's build script,
while `get!` picks up the environment variables and constructs a `BuildInfo`
at compile time. `get!` is a macro so that it runs in the compilation context
of the binary and not in the context of the source package.

## Features

`astria-build-info` provides two features (both disabled by default):

+ `build` to enable the `emit` utility.
+ `runtime` to enable `BuildInfo` and the `get!` macro.

## Usage

Set up a service's dependencies like so:

```toml
[dependencies]
astria-build-info = { path = "../astria-build-info", features = ["runtime"] }

[build-dependencies]
astria-build-info = { path = "../astria-build-info", features = ["build"] }
```

And then use `emit` in the binary's build.rs, specifying the git tag which is
used for the service. For example, if the service is tagged with
`shaving-cats-v0.1.2`, then provide `emit("shaving-cats-v")` (supplying
`"shaving-cats"` also works, but it is recommened to use `"shaving-cats-v"` in
case there is another service/tag named `"shaving-cats-and-dogs-v1.2.3"`).

```rust,ignore
fn main() -> Result<(), Box<dyn std::error::Error>> {
astria_build_info::emit("<release-tag-of-service>")?;
Ok(())
}
```

And pick up the emitted variables like so:

```rust,ignore
use astria_build_info::BuildInfo;
const BUILD_INFO: BuildInfo = astria_build_info::get!();
```
97 changes: 97 additions & 0 deletions crates/astria-build-info/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#![doc = include_str!("../README.md")]
#![cfg_attr(docsrs, feature(doc_cfg))]

#[cfg(feature = "runtime")]
pub use runtime::BuildInfo;

#[cfg(feature = "runtime")]
#[cfg_attr(docsrs, doc(cfg(feature = "runtime")))]
mod runtime {
/// Constructs a [`BuildInfo`] at compile time.
#[macro_export]
macro_rules! get {
() => {
BuildInfo {
build_timestamp: env!("VERGEN_BUILD_TIMESTAMP"),
cargo_opt_level: env!("VERGEN_CARGO_OPT_LEVEL"),
cargo_pkg_name: env!("CARGO_PKG_NAME"),
cargo_target_triple: env!("VERGEN_CARGO_TARGET_TRIPLE"),
git_branch: env!("VERGEN_GIT_BRANCH"),
git_commit_date: env!("VERGEN_GIT_COMMIT_DATE"),
git_describe: env!("VERGEN_GIT_DESCRIBE"),
git_sha: env!("VERGEN_GIT_SHA"),
rustc_channel: env!("VERGEN_RUSTC_CHANNEL"),
rustc_commit_hash: env!("VERGEN_RUSTC_COMMIT_HASH"),
rustc_host_triple: env!("VERGEN_RUSTC_HOST_TRIPLE"),
}
};
}

/// The build info of a package constructed at compile time.
///
/// This intended to be constructed at compile time using the
/// [`get`] macro:
///
/// ```ignore
/// # use astria_build_info::BuildInfo;
/// const BUILD_INFO: BuildInfo = astria_build_info::get!();
/// ```
#[derive(Debug, serde::Serialize)]
pub struct BuildInfo {
pub build_timestamp: &'static str,
pub cargo_opt_level: &'static str,
pub cargo_pkg_name: &'static str,
pub cargo_target_triple: &'static str,
pub git_branch: &'static str,
pub git_commit_date: &'static str,
pub git_describe: &'static str,
pub git_sha: &'static str,
pub rustc_channel: &'static str,
pub rustc_commit_hash: &'static str,
pub rustc_host_triple: &'static str,
}
}

#[cfg(feature = "build")]
#[cfg_attr(docsrs, doc(cfg(feature = "build")))]
/// Emits build infos as environment variables.
///
/// The `prefix` argument is used akin to manually calling
/// `git describe --tags --match="<prefix>*"`. It assumes that releases of
/// services (and binaries) are tagged using a format like `<prefix>0.1.2`.
///
/// Note that if two services share a common prefix like `sequencer` and
/// `sequencer-relayer`, `<prefix>` should be supplied as `"sequencer-v"` and
/// `"sequencer-relayer-v"` for tags like `sequencer-v1.2.3` or
/// `sequencer-relayer-v1.2.3`. This is to avoid matching on the wrong prefix
///
/// # Errors
/// Emits the same errors as [`vergen::EmitBuilder::emit`].
///
/// # Usage
///
/// In a crate's `build.rs` write:
///
/// ```no_run
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// astria_build_info::emit("crate-release-tag")?;
/// # Ok(())
/// # }
/// ```
pub fn emit(prefix: &str) -> Result<(), Box<dyn std::error::Error>> {
let git_describe_prefix = Box::leak(format!("{prefix}*").into_boxed_str());
vergen::EmitBuilder::builder()
.build_timestamp()
.cargo_opt_level()
.cargo_target_triple()
.git_branch()
.git_commit_date()
.git_describe(true, true, Some(&*git_describe_prefix))
.git_sha(false)
.rustc_channel()
.rustc_commit_hash()
.rustc_host_triple()
.rustc_semver()
.emit()?;
Ok(())
}
4 changes: 4 additions & 0 deletions crates/astria-composer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ homepage = "https://astria.org"
name = "astria-composer"

[dependencies]
astria-build-info = { path = "../astria-build-info", features = ["runtime"] }
astria-core = { path = "../astria-core" }
config = { package = "astria-config", path = "../astria-config" }
telemetry = { package = "astria-telemetry", path = "../astria-telemetry" }
Expand Down Expand Up @@ -65,3 +66,6 @@ tokio-test = { workspace = true }

tendermint-rpc = { workspace = true }
wiremock = { workspace = true }

[build-dependencies]
astria-build-info = { path = "../astria-build-info", features = ["build"] }
4 changes: 4 additions & 0 deletions crates/astria-composer/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pub fn main() -> Result<(), Box<dyn std::error::Error>> {
astria_build_info::emit("composer-v")?;
Ok(())
}
3 changes: 3 additions & 0 deletions crates/astria-composer/src/build_info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
use astria_build_info::BuildInfo;

pub const BUILD_INFO: BuildInfo = astria_build_info::get!();
2 changes: 2 additions & 0 deletions crates/astria-composer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,12 @@
//! ```
pub(crate) mod api;
mod build_info;
mod composer;
pub mod config;
pub(crate) mod searcher;

pub use build_info::BUILD_INFO;
pub use composer::Composer;
pub use config::Config;
pub use telemetry;
6 changes: 6 additions & 0 deletions crates/astria-composer/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@ use astria_composer::{
telemetry,
Composer,
Config,
BUILD_INFO,
};
use color_eyre::eyre::WrapErr as _;
use tracing::info;

#[tokio::main]
async fn main() -> ExitCode {
eprintln!(
"{}",
serde_json::to_string(&BUILD_INFO)
.expect("build info is serializable because it contains only unicode fields")
);
let cfg: Config = match config::get() {
Ok(cfg) => cfg,
Err(e) => {
Expand Down
4 changes: 4 additions & 0 deletions crates/astria-conductor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ tonic = { workspace = true }
tracing = { workspace = true, features = ["valuable"] }
tryhard = { workspace = true }

astria-build-info = { path = "../astria-build-info", features = ["runtime"] }
astria-core = { path = "../astria-core", features = ["client", "serde"] }
celestia-client = { package = "astria-celestia-client", path = "../astria-celestia-client" }
optimism = { package = "astria-optimism", path = "../astria-optimism" }
Expand All @@ -67,3 +68,6 @@ optimism = { package = "astria-optimism", path = "../astria-optimism", features
config = { package = "astria-config", path = "../astria-config", features = [
"tests",
] }

[build-dependencies]
astria-build-info = { path = "../astria-build-info", features = ["build"] }
4 changes: 4 additions & 0 deletions crates/astria-conductor/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fn main() -> Result<(), Box<dyn std::error::Error>> {
astria_build_info::emit("conductor-v")?;
Ok(())
}
3 changes: 3 additions & 0 deletions crates/astria-conductor/src/build_info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
use astria_build_info::BuildInfo;

pub const BUILD_INFO: BuildInfo = astria_build_info::get!();
2 changes: 2 additions & 0 deletions crates/astria-conductor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
//! execution layer until it's received from the data availability layer. In the second case, the
//! execution layer is notified to mark the block as finalized.
pub(crate) mod block_cache;
mod build_info;
pub(crate) mod celestia;
pub(crate) mod client_provider;
pub mod conductor;
Expand All @@ -19,6 +20,7 @@ pub(crate) mod utils;

use std::fmt::Write;

pub use build_info::BUILD_INFO;
pub use conductor::Conductor;
pub use config::Config;

Expand Down
Loading

0 comments on commit 4d8efb2

Please sign in to comment.