Skip to content

Commit b3958d6

Browse files
authored
Merge pull request #12323 from Turbo87/heroku-crate
Extract `crates_io_heroku` crate with `commit()` fns
2 parents 6242a71 + 91071eb commit b3958d6

File tree

10 files changed

+142
-5
lines changed

10 files changed

+142
-5
lines changed

Cargo.lock

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ crates_io_diesel_helpers = { path = "crates/crates_io_diesel_helpers" }
7474
crates_io_docs_rs = { path = "crates/crates_io_docs_rs" }
7575
crates_io_env_vars = { path = "crates/crates_io_env_vars" }
7676
crates_io_github = { path = "crates/crates_io_github" }
77+
crates_io_heroku = { path = "crates/crates_io_heroku" }
7778
crates_io_index = { path = "crates/crates_io_index" }
7879
crates_io_linecount = { path = "crates/crates_io_linecount" }
7980
crates_io_markdown = { path = "crates/crates_io_markdown" }

crates/crates_io_database_dump/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ workspace = true
1010
[dependencies]
1111
anyhow = "=1.0.100"
1212
chrono = { version = "=0.4.42", default-features = false, features = ["clock", "serde"] }
13+
crates_io_heroku = { path = "../crates_io_heroku" }
1314
flate2 = "=1.1.5"
1415
minijinja = "=2.12.0"
1516
serde = { version = "=1.0.228", features = ["derive"] }

crates/crates_io_database_dump/src/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,10 @@ impl DumpDirectory {
7070
}
7171
let metadata = Metadata {
7272
timestamp: &self.timestamp,
73-
crates_io_commit: std::env::var("HEROKU_SLUG_COMMIT")
74-
.unwrap_or_else(|_| "unknown".to_owned()),
73+
crates_io_commit: crates_io_heroku::commit()
74+
.ok()
75+
.flatten()
76+
.unwrap_or_else(|| "unknown".to_owned()),
7577
};
7678
let path = self.path().join("metadata.json");
7779
debug!(?path, "Writing metadata.json file…");

crates/crates_io_heroku/Cargo.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[package]
2+
name = "crates_io_heroku"
3+
version = "0.0.0"
4+
license = "MIT OR Apache-2.0"
5+
edition = "2024"
6+
7+
[lints]
8+
workspace = true
9+
10+
[dependencies]
11+
anyhow = "=1.0.100"
12+
crates_io_env_vars = { path = "../crates_io_env_vars" }

crates/crates_io_heroku/README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# crates_io_heroku
2+
3+
This package contains utilities for accessing Heroku-specific environment
4+
variables.
5+
6+
When the `runtime-dyno-metadata` Heroku Labs feature is enabled, Heroku
7+
exposes application and environment information through environment variables.
8+
This crate provides convenient functions to access these values.
9+
10+
For more information, see:
11+
<https://devcenter.heroku.com/articles/dyno-metadata>

crates/crates_io_heroku/src/lib.rs

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#![doc = include_str!("../README.md")]
2+
3+
use crates_io_env_vars::var;
4+
5+
/// Returns the Git SHA of the currently deployed commit.
6+
///
7+
/// This function tries `HEROKU_BUILD_COMMIT` first (the current standard),
8+
/// and falls back to `HEROKU_SLUG_COMMIT` (deprecated) if the former is not
9+
/// set. This provides compatibility with both old and new Heroku deployments.
10+
///
11+
/// Both environment variables are set by Heroku when the appropriate Labs
12+
/// features are enabled (`runtime-dyno-build-metadata` for `HEROKU_BUILD_COMMIT`,
13+
/// `runtime-dyno-metadata` for `HEROKU_SLUG_COMMIT`).
14+
///
15+
/// Returns `None` if neither variable is set (e.g., in local development).
16+
///
17+
/// See <https://devcenter.heroku.com/articles/dyno-metadata> for more
18+
/// information.
19+
///
20+
/// # Examples
21+
///
22+
/// ```
23+
/// use crates_io_heroku::commit;
24+
///
25+
/// if let Ok(Some(commit)) = commit() {
26+
/// println!("Running commit: {}", commit);
27+
/// } else {
28+
/// println!("Commit SHA unknown");
29+
/// }
30+
/// ```
31+
pub fn commit() -> anyhow::Result<Option<String>> {
32+
// Try the current standard first
33+
if let Some(commit) = build_commit()? {
34+
return Ok(Some(commit));
35+
}
36+
37+
// Fall back to the deprecated variable for backward compatibility
38+
slug_commit()
39+
}
40+
41+
/// Returns the Git SHA of the currently deployed commit.
42+
///
43+
/// This value comes from the `HEROKU_SLUG_COMMIT` environment variable,
44+
/// which is set by Heroku when the `runtime-dyno-metadata` Labs feature
45+
/// is enabled. If the variable is not set (e.g., in local development
46+
/// or when the feature is disabled), returns `None`.
47+
///
48+
/// Note: `HEROKU_SLUG_COMMIT` is deprecated by Heroku in favor of
49+
/// `HEROKU_BUILD_COMMIT`, but this function continues to use
50+
/// `HEROKU_SLUG_COMMIT` for backward compatibility with existing
51+
/// deployments.
52+
///
53+
/// See <https://devcenter.heroku.com/articles/dyno-metadata> for more
54+
/// information.
55+
///
56+
/// # Examples
57+
///
58+
/// ```
59+
/// use crates_io_heroku::slug_commit;
60+
///
61+
/// if let Ok(Some(commit)) = slug_commit() {
62+
/// println!("Running commit: {}", commit);
63+
/// } else {
64+
/// println!("Commit SHA unknown");
65+
/// }
66+
/// ```
67+
pub fn slug_commit() -> anyhow::Result<Option<String>> {
68+
var("HEROKU_SLUG_COMMIT")
69+
}
70+
71+
/// Returns the Git SHA of the currently deployed commit.
72+
///
73+
/// This value comes from the `HEROKU_BUILD_COMMIT` environment variable,
74+
/// which is set by Heroku when the `runtime-dyno-build-metadata` Labs
75+
/// feature is enabled. If the variable is not set (e.g., in local development
76+
/// or when the feature is disabled), returns `None`.
77+
///
78+
/// This is the recommended function to use, as `HEROKU_BUILD_COMMIT` is
79+
/// the current standard while `HEROKU_SLUG_COMMIT` is deprecated.
80+
///
81+
/// See <https://devcenter.heroku.com/articles/dyno-metadata> for more
82+
/// information.
83+
///
84+
/// # Examples
85+
///
86+
/// ```
87+
/// use crates_io_heroku::build_commit;
88+
///
89+
/// if let Ok(Some(commit)) = build_commit() {
90+
/// println!("Running commit: {}", commit);
91+
/// } else {
92+
/// println!("Commit SHA unknown");
93+
/// }
94+
/// ```
95+
pub fn build_commit() -> anyhow::Result<Option<String>> {
96+
var("HEROKU_BUILD_COMMIT")
97+
}

src/config/sentry.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use anyhow::Context;
22
use crates_io_env_vars::{required_var, var, var_parsed};
3+
use crates_io_heroku::commit;
34
use sentry::IntoDsn;
45
use sentry::types::Dsn;
56

@@ -28,7 +29,7 @@ impl SentryConfig {
2829
Ok(Self {
2930
dsn,
3031
environment,
31-
release: var("HEROKU_SLUG_COMMIT")?,
32+
release: commit()?,
3233
traces_sample_rate: var_parsed("SENTRY_TRACES_SAMPLE_RATE")?.unwrap_or(0.0),
3334
})
3435
}

src/controllers/site_metadata.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::app::AppState;
22
use axum::Json;
33
use axum::response::IntoResponse;
4+
use crates_io_heroku::commit;
45
use serde::Serialize;
56

67
#[derive(Debug, Serialize, utoipa::ToSchema)]
@@ -33,7 +34,7 @@ pub struct MetadataResponse<'a> {
3334
pub async fn get_site_metadata(state: AppState) -> impl IntoResponse {
3435
let read_only = state.config.db.are_all_read_only();
3536

36-
let deployed_sha = dotenvy::var("HEROKU_SLUG_COMMIT");
37+
let deployed_sha = commit().ok().flatten();
3738
let deployed_sha = deployed_sha.as_deref().unwrap_or("unknown");
3839

3940
Json(MetadataResponse {

src/sentry/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ use tracing::warn;
1212
/// be set if a DSN is provided.
1313
///
1414
/// `HEROKU_SLUG_COMMIT`, if present, will be used as the `release` property
15-
/// on all events.
15+
/// on all events. This environment variable is provided by Heroku when the
16+
/// `runtime-dyno-metadata` Labs feature is enabled.
1617
pub fn init() -> Option<ClientInitGuard> {
1718
let config = match SentryConfig::from_environment() {
1819
Ok(config) => config,

0 commit comments

Comments
 (0)