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
70 changes: 53 additions & 17 deletions editor/build.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,60 @@
use std::env;
use std::process::Command;

const GRAPHITE_RELEASE_SERIES: &str = "Alpha 4";

fn main() {
// Execute a Git command for its stdout. Early exit if it fails for any of the possible reasons.
let try_git_command = |args: &[&str]| -> Option<String> {
let git_output = Command::new("git").args(args).output().ok()?;
let maybe_empty = String::from_utf8(git_output.stdout).ok()?;
let command_result = (!maybe_empty.is_empty()).then_some(maybe_empty)?;
Some(command_result)
};
// Execute a Git command for its output. Return "unknown" if it fails for any of the possible reasons.
let git_command = |args| -> String { try_git_command(args).unwrap_or_else(|| String::from("unknown")) };

// Rather than printing to any terminal, these commands set environment variables in the Cargo toolchain.
// They are accessed with the `env!("...")` macro in the codebase.
println!("cargo:rustc-env=GRAPHITE_GIT_COMMIT_DATE={}", git_command(&["log", "-1", "--format=%cd"]));
println!("cargo:rustc-env=GRAPHITE_GIT_COMMIT_HASH={}", git_command(&["rev-parse", "HEAD"]));
let branch = std::env::var("GITHUB_HEAD_REF").unwrap_or_default();
let branch = if branch.is_empty() { git_command(&["name-rev", "--name-only", "HEAD"]) } else { branch };
println!("cargo:rustc-env=GRAPHITE_GIT_COMMIT_BRANCH={branch}");
// Instruct Cargo to rerun this build script if any of these environment variables change.
println!("cargo:rerun-if-env-changed=GRAPHITE_GIT_COMMIT_DATE");
println!("cargo:rerun-if-env-changed=GRAPHITE_GIT_COMMIT_HASH");
println!("cargo:rerun-if-env-changed=GRAPHITE_GIT_COMMIT_BRANCH");
println!("cargo:rerun-if-env-changed=GITHUB_HEAD_REF");

// Instruct Cargo to rerun this build script if the Git HEAD or refs change.
println!("cargo:rerun-if-changed=.git/HEAD");
println!("cargo:rerun-if-changed=.git/refs/heads");

// Try to get the commit information from the environment (e.g. set by CI), otherwise fall back to Git commands.
let commit_date = env_or_else("GRAPHITE_GIT_COMMIT_DATE", || git_or_unknown(&["log", "-1", "--format=%cI"]));
let commit_hash = env_or_else("GRAPHITE_GIT_COMMIT_HASH", || git_or_unknown(&["rev-parse", "HEAD"]));
let commit_branch = env_or_else("GRAPHITE_GIT_COMMIT_BRANCH", || {
let gh = env::var("GITHUB_HEAD_REF").unwrap_or_default();
if !gh.trim().is_empty() {
gh.trim().to_string()
} else {
git_or_unknown(&["rev-parse", "--abbrev-ref", "HEAD"])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why --abbrev-ref?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returns a commit hash otherwise. But I could also use name-rev like you did before.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does it return if not a commit hash?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Branch name. (Rev short name if you want to use git wording)

Copy link
Member

@Keavon Keavon Sep 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should aim to always have a commit hash so it's possible to actually look up which commit a build link belongs to. (This is also something we don't do on https://editor.graphite.rs but should do.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commit hash is collected in the statement above. There rev-parse without --abbrev-ref.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of this second one?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// Collect commit hash
        let commit_hash = env_or_else("GRAPHITE_GIT_COMMIT_HASH", || git_or_unknown(&["rev-parse", "HEAD"]));
// Collect Branch name
         let commit_branch = env_or_else("GRAPHITE_GIT_COMMIT_BRANCH", || { 
                 let gh = env::var("GITHUB_HEAD_REF").unwrap_or_default();

// Code you comment on is used to collect the branch name when it is not set by GitHub locally for now example

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I wasn't looking closely enough. Disregard my last two comments. Anyway, I think we're good to merge.

}
});

// Instruct Cargo to set environment variables for compile time.
// They are accessed with the `env!("GRAPHITE_*")` macro in the codebase.
println!("cargo:rustc-env=GRAPHITE_GIT_COMMIT_DATE={commit_date}");
println!("cargo:rustc-env=GRAPHITE_GIT_COMMIT_HASH={commit_hash}");
println!("cargo:rustc-env=GRAPHITE_GIT_COMMIT_BRANCH={commit_branch}");
println!("cargo:rustc-env=GRAPHITE_RELEASE_SERIES={GRAPHITE_RELEASE_SERIES}");
}

/// Get an environment variable, or if it is not set or empty, use the provided fallback function. Returns a string with trimmed whitespace.
fn env_or_else(key: &str, fallback: impl FnOnce() -> String) -> String {
match env::var(key) {
Ok(v) if !v.trim().is_empty() => v.trim().to_string(),
_ => fallback().trim().to_string(),
}
}

/// Execute a Git command to obtain its output. Return "unknown" if it fails for any of the possible reasons.
fn git_or_unknown(args: &[&str]) -> String {
git(args).unwrap_or_else(|| "unknown".to_string())
}

/// Run a git command and capture trimmed stdout.
/// Returns None if git is missing, exits with error, or stdout is empty/non-UTF8.
fn git(args: &[&str]) -> Option<String> {
let output = Command::new("git").args(args).output().ok()?;
if !output.status.success() {
return None;
}
let s = String::from_utf8(output.stdout).ok()?;
let t = s.trim();
if t.is_empty() { None } else { Some(t.to_string()) }
}
2 changes: 1 addition & 1 deletion editor/src/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pub fn commit_info_localized(localized_commit_date: &str) -> String {
{}",
GRAPHITE_RELEASE_SERIES,
GRAPHITE_GIT_COMMIT_BRANCH,
&GRAPHITE_GIT_COMMIT_HASH[..8],
GRAPHITE_GIT_COMMIT_HASH.get(..8).unwrap_or(GRAPHITE_GIT_COMMIT_HASH),
localized_commit_date
)
}
Loading