-
Notifications
You must be signed in to change notification settings - Fork 3
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
(Feat): Support passing a bazel BuildEventProtocol path #197
(Feat): Support passing a bazel BuildEventProtocol path #197
Conversation
required_unless_present = "bazel_bep_path", | ||
conflicts_with = "bazel_bep_path", |
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.
This allows it to be mutually exclusive with the --junit-paths
as well as --xc-result-path
when applicable
required_unless_present = "junit_paths", | ||
help = "Path to bazel build event protocol JSON file." | ||
)] | ||
bazel_bep_path: Option<String>, |
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.
If we decide we want to support the binary format too at some point, we can just name that bazel_bep_binary_path
. JSON seems the sanest default here
cli/src/main.rs
Outdated
|
||
log::info!("running command: {:?}", command); | ||
let run_result = run_test_command( | ||
&repo, | ||
&org_url_slug, | ||
command.first().unwrap(), | ||
command.iter().skip(1).collect(), | ||
junit_paths, | ||
&junit_spec, |
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.
We can't early parse here like we do in other cases, since we haven't run the test yet 🙃
cli/src/main.rs
Outdated
let mut parser = BazelBepParser::new(bazel_bep_path.clone()); | ||
parser.parse()?; | ||
parser.xml_files() |
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.
Not sure if there's a more idiomatic way to do this in rust. Maybe chaining?
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.
Nah, this is pretty good. It gets annoying when having to do mapping with Result
s
cli/src/upload.rs
Outdated
@@ -258,6 +273,7 @@ pub async fn run_upload( | |||
|
|||
log::info!("Total files pack and upload: {}", file_counter.get_count()); | |||
if file_counter.get_count() == 0 { | |||
// DONOTLAND FIX LOG MESSAGE HERE |
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.
Will be auditing this to make sure the message still makes sense/works
context/src/bazel_bep/parser.rs
Outdated
let xml_files = test_result.test_action_output.into_iter().fold( | ||
Vec::new(), | ||
|mut xml_files, action_output| { | ||
if action_output.name.ends_with(".xml") { |
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.
test.xml
by default afaik, but my understanding is that this may vary for different runners
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.
My pre-review - all looks good to me at a first passthroug. Since we're ok with this feature being hacky, I'm ok with believing the external types you're using to be correct / up-to-date enough
pub struct TestResult { | ||
pub cached: bool, | ||
pub xml_files: Vec<String>, | ||
} |
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 was under the impression that one test result = one file - is that not the case? Or just being proactive here?
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.
From what I've seen it's just one xml file. But there are multiple files (test.log), and conceivably if you were using bazel to wrap some other invocation, you could get multiple junits, so being proactive
context/src/bazel_bep/parser.rs
Outdated
log::info!( | ||
"Parsed {} ({} cached) test results from BEP file", | ||
self.test_results.len(), | ||
self.test_results.iter().filter(|r| r.cached).count() |
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.
Open to input on precomputing this, storing other info, etc. I wanted to strike a balance of only storing info that we found valuable here, while also reporting useful information for debug purposes...
context/test_fixtures/bep_example
Outdated
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.
These are sanitized BEP files from our repro of the original issue. I have:
- Stripped env vars
- Simplified paths
- Removed extra log output
- Cleaned up CLI options
and tried a few different situations to simulate truncation, invalid files, etc.
f6f2969
to
32bc6ef
Compare
32bc6ef
to
f72c26a
Compare
# Fork from 0.2.2 that adds serde serialize/deserialize via pbjson | ||
bazel-bep = { git = "https://github.com/TylerJang27/bazel-bep.git", rev = "e51c546960067b9fe98ae35ae00bc53302973a9e" } |
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'd recommend for us to just vendor the crate in the workspace. There's only ~100 lines of code there
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.
Good point, will do as a follow-up
cli/src/main.rs
Outdated
let mut parser = BazelBepParser::new(bazel_bep_path.clone()); | ||
parser.parse()?; | ||
parser.xml_files() |
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.
Nah, this is pretty good. It gets annoying when having to do mapping with Result
s
f72c26a
to
08eed55
Compare
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.
These changes didn't end up helping with CI like I'd hoped, but it may prove helpful locally. If need be we can remove later
if [ "$(uname -m)" == "aarch64" ]; then | ||
curl -L https://github.com/protocolbuffers/protobuf/releases/download/v29.1/protoc-29.1-linux-aarch_64.zip -o protoc.zip | ||
unzip protoc.zip | ||
export PROTOC=$(pwd)/bin/protoc | ||
else | ||
curl -L https://github.com/protocolbuffers/protobuf/releases/download/v29.1/protoc-29.1-linux-x86_64.zip -o protoc.zip | ||
unzip protoc.zip | ||
export PROTOC=$(pwd)/bin/protoc |
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.
The package registries were giving me issues. This ended up being a more reliable way to install and pin within the VMs
- name: Install protoc | ||
shell: bash | ||
run: | | ||
if [ -f /opt/homebrew/bin/brew ]; then | ||
/opt/homebrew/bin/brew install protobuf | ||
elif [ -f /usr/bin/apt ]; then | ||
sudo /usr/bin/apt update | ||
sudo /usr/bin/apt install -y protobuf-compiler | ||
fi | ||
|
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.
The arduino setup action was relentless with rate limiting (not sure why they don't allow bypassing the API call), and I didn't want to pass our whole GH token rn https://github.com/marketplace/actions/setup-protoc
let output_paths = match junit_spec { | ||
JunitSpec::Paths(paths) => paths, | ||
JunitSpec::BazelBep(bep_path) => { | ||
let mut parser = BazelBepParser::new(bep_path.clone()); |
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.
Now that junit_spec
is passed by value, we don't need to clone here
pub fn print_parsed_results(&self) { | ||
if !self.errors.is_empty() { | ||
log::warn!("Errors parsing BEP file: {:?}", &self.errors); | ||
} | ||
|
||
let (test_count, cached_count) = self.test_results.iter().fold( | ||
(0, 0), | ||
|(mut test_count, mut cached_count), test_result| { | ||
test_count += test_result.xml_files.len(); | ||
if test_result.cached { | ||
cached_count += test_result.xml_files.len(); | ||
} | ||
(test_count, cached_count) | ||
}, | ||
); | ||
log::info!( | ||
"Parsed {} ({} cached) test results from BEP file", | ||
test_count, | ||
cached_count | ||
); | ||
} |
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.
Optional: I would leave the log::info
for the CLI crate. This method could just return the number of tests and number of cached tests to be used however the caller pleases
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.
Ah, fair point. Will handle in follow-up
Support testing, validating, and uploading from a bazel BuildEventProtocol JSON file
I've added unit and integration tests, and also validated this manually with a local bazel run and a successful upload.
As a follow-up I'll be vendoring the proto crate in this repo