-
-
Notifications
You must be signed in to change notification settings - Fork 119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Embed the git commit in fj-app's version number #868
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
2f5e622
Embed the git commit in fj-app's version number
Michael-F-Bryan b8072f0
Add "unreleased" to fj-app versions that aren't official releases
Michael-F-Bryan fa72e73
Re-run the build script whenever the commit changes
Michael-F-Bryan e03363a
Handle detached HEADs
Michael-F-Bryan 0386542
Make sure we only accept FJ_OFFICIAL_RELEASE=1
Michael-F-Bryan 104ef4a
Build scripts are used automatically if "build.rs" is present
Michael-F-Bryan d80dbd5
Explicitly run "git describe" in the crate directory
Michael-F-Bryan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
use std::{ | ||
path::PathBuf, | ||
process::{Command, Output, Stdio}, | ||
}; | ||
|
||
fn main() { | ||
println!("cargo:rustc-env=FJ_VERSION_STRING={}", version_string()); | ||
} | ||
|
||
fn version_string() -> String { | ||
let pkg_version = std::env::var("CARGO_PKG_VERSION").unwrap(); | ||
let commit = git_description(); | ||
|
||
let official_release = | ||
std::env::var("FJ_OFFICIAL_RELEASE").as_deref() == Ok("1"); | ||
println!("cargo:rerun-if-env-changed=FJ_OFFICIAL_RELEASE"); | ||
|
||
match (commit, official_release) { | ||
(Some(commit), true) => format!("{pkg_version} ({commit})"), | ||
(Some(commit), false) => { | ||
format!("{pkg_version} ({commit}, unreleased)") | ||
} | ||
(None, true) => pkg_version, | ||
(None, false) => format!("{pkg_version} (unreleased)"), | ||
} | ||
} | ||
|
||
/// Try to get the current git commit. | ||
/// | ||
/// This may fail if `git` isn't installed (unlikely) or if the `.git/` folder | ||
/// isn't accessible (more likely than you think). This typically happens when | ||
/// we're building just the `fj-app` crate in a Docker container or when | ||
/// someone is installing from crates.io via `cargo install`. | ||
fn git_description() -> Option<String> { | ||
let crate_dir = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap()); | ||
|
||
let mut cmd = Command::new("git"); | ||
cmd.args(["describe", "--always", "--dirty=-modified"]) | ||
.stdout(Stdio::piped()) | ||
.stderr(Stdio::piped()) | ||
.current_dir(&crate_dir); | ||
|
||
let Output { | ||
status, | ||
stdout, | ||
stderr, | ||
} = cmd.output().ok()?; | ||
|
||
let stdout = String::from_utf8_lossy(&stdout); | ||
|
||
if !status.success() { | ||
// Not sure if anyone will ever see this, but it could be helpful for | ||
// troubleshooting. | ||
eprintln!("Command failed: {cmd:?}"); | ||
let stderr = String::from_utf8_lossy(&stderr); | ||
eprintln!("---- Stdout ----"); | ||
eprintln!("{stdout}"); | ||
eprintln!("---- Stderr ----"); | ||
eprintln!("{stderr}"); | ||
return None; | ||
} | ||
|
||
// Make sure we re-run whenever the current commit changes | ||
let project_root = crate_dir.ancestors().nth(2).unwrap(); | ||
let head_file = project_root.join(".git").join("HEAD"); | ||
println!("cargo:rerun-if-changed={}", head_file.display()); | ||
|
||
if let Ok(contents) = std::fs::read_to_string(&head_file) { | ||
// Most of the time the HEAD file will be `ref: refs/heads/$branch`, but | ||
// when it's a detached head we'll only get the commit hash and can skip | ||
// the rerun-if-changed logic. | ||
|
||
if let Some((_, branch)) = contents.split_once(' ') { | ||
let commit_hash_file = | ||
project_root.join(".git").join(branch.trim()); | ||
println!("cargo:rerun-if-changed={}", commit_hash_file.display()); | ||
} | ||
} | ||
|
||
Some(stdout.trim().to_string()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this is incorrect. The CD workflow is run (and builds binaries for) every push to
main
. If a release is detected, those binaries are re-used for the actual release.Note the
Operator | Deduce
step, which detects whether we're dealing with a release, or a regular push tomain
, and theif: ${{ steps.release.outputs.release-detected == 'true' }}
bits that use that step's output.Not sure how good your grasp on GitHub Actions is. We might need @hendrikmaus to help figure this out.
If this turns into a problem, we could consider removing the per-push-to-
main
build, and only build binaries for the release. I'm not sure how useful those per-push binaries are anymore, with weekly releases. Thoughts?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh, I just had a deeper look into how the release job works, and it seems like every push to
main
generates its own compiled binaries, but they only get promoted to a proper release if the "release operator" says so.That makes things more complicated because
fj-app
won't know at compile time whether it is a proper release (therelease
job depends onbinaries
, butBinaries | Compile
would need to knowsteps.release.outputs.release-detected
- which is a dependency cycle).