Skip to content

[STAL-2007] Handle branch from Gitlab pipelines #350

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

Merged
merged 1 commit into from
May 7, 2024
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
2 changes: 1 addition & 1 deletion crates/bins/src/bin/datadog-static-analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ fn main() -> Result<()> {

// check if we do a diff-aware scan
let diff_aware_parameters: Option<DiffAwareData> = if diff_aware_requested {
match configuration.generate_diff_aware_request_data() {
match configuration.generate_diff_aware_request_data(configuration.use_debug) {
Ok(params) => {
if configuration.use_debug {
println!("Diff-aware request with repository url {}, sha {}, branch {}, config hash {}", params.repository_url, params.sha, params.branch, params.config_hash);
Expand Down
3 changes: 3 additions & 0 deletions crates/cli/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ pub static SARIF_PROPERTY_DATADOG_FINGERPRINT: &str = "DATADOG_FINGERPRINT";
pub static SARIF_PROPERTY_SHA: &str = "SHA";

pub static DEFAULT_MAX_FILE_SIZE_KB: u64 = 200;
// See https://docs.gitlab.com/ee/ci/variables/predefined_variables.html
pub static GITLAB_ENVIRONMENT_VARIABLE_COMMIT_BRANCH: &str = "CI_COMMIT_BRANCH";
pub static GIT_HEAD: &str = "HEAD";
47 changes: 47 additions & 0 deletions crates/cli/src/git_utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use crate::constants::{GITLAB_ENVIRONMENT_VARIABLE_COMMIT_BRANCH, GIT_HEAD};
use git2::Repository;
use std::env;

/// Try to get the branch running. We first try to get the branch from the repository. When
/// it fails, we attempt to get the branch from the CI provider when the analyzer
/// runs in a CI provider.
///
/// Some CI providers (like Gitlab) runs their CI on a detached HEAD (see
/// [this thread for example](https://forum.gitlab.com/t/why-i-cant-get-the-branch-name/72462).
///
/// When we do not find the branch, we attempt to find it from the CI provider using variables.
pub fn get_branch(repository: &Repository, use_debug: bool) -> Option<String> {
// First, let's try to get it from the repository.
let head_try = repository.head();
if let Ok(head) = head_try {
let branch_from_shorthand = head.shorthand();

if let Some(branch) = branch_from_shorthand {
if branch == GIT_HEAD && use_debug {
eprintln!("branch is HEAD, not using it for diff-aware");
}

if branch != GIT_HEAD {
if use_debug {
eprintln!("Getting branch {} from Git repo", branch)
}

return Some(branch.to_string());
}
}
}

// Let's try to get it from Gitlab.
let branch_from_gitlab_pipeline_try = env::var(GITLAB_ENVIRONMENT_VARIABLE_COMMIT_BRANCH);
if let Ok(branch_from_gitlab_pipeline) = branch_from_gitlab_pipeline_try {
if use_debug {
eprintln!(
"getting branch {} from Gitlab pipelines",
branch_from_gitlab_pipeline
);
}
return Some(branch_from_gitlab_pipeline);
}

None
}
1 change: 1 addition & 0 deletions crates/cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pub mod constants;
pub mod csv;
pub mod datadog_utils;
pub mod file_utils;
mod git_utils;
pub mod model;
pub mod rule_utils;
pub mod sarif;
Expand Down
30 changes: 13 additions & 17 deletions crates/cli/src/model/cli_configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use anyhow::anyhow;
use git2::Repository;
use sha2::{Digest, Sha256};

use crate::git_utils::get_branch;
use kernel::config_file::ArgumentProvider;
use kernel::model::common::OutputFormat;
use kernel::model::config_file::PathConfig;
Expand Down Expand Up @@ -71,7 +72,10 @@ impl CliConfiguration {
/// the repository from the directory, get the repository information to get
/// diff-aware data. If we are not in a repository or cannot get the data
/// we need, we return an error.
pub fn generate_diff_aware_request_data(&self) -> anyhow::Result<DiffAwareRequestArguments> {
pub fn generate_diff_aware_request_data(
&self,
use_debug: bool,
) -> anyhow::Result<DiffAwareRequestArguments> {
let config_hash = self.generate_diff_aware_digest();

let repository_opt = Repository::init(&self.source_directory);
Expand All @@ -93,22 +97,14 @@ impl CliConfiguration {
// let's get the latest commit
let head = repository.head()?;
let oid = head.target();
let head_name = head.shorthand();
match (oid, head_name) {
(Some(o), Some(h)) => {
if h == "HEAD" {
return Err(anyhow!(
"branch is HEAD, cannot generate diff-aware scanning"
));
}

Ok(DiffAwareRequestArguments {
repository_url,
config_hash,
sha: o.to_string(),
branch: h.to_string(),
})
}
let branch_option = get_branch(&repository, use_debug);
match (oid, branch_option) {
(Some(o), Some(b)) => Ok(DiffAwareRequestArguments {
repository_url,
config_hash,
sha: o.to_string(),
branch: b,
}),
_ => {
if self.use_debug {
println!(
Expand Down