Commit 10c3058f authored by Benoit Martin's avatar Benoit Martin Committed by Pierre Smeyers
Browse files

feat(sonar): autodetect Merge Request from current branch

parent 5f03e710
Loading
Loading
Loading
Loading
+12 −11
Original line number Diff line number Diff line
@@ -81,27 +81,28 @@ It is bound to the `test` stage, and uses the following variables:
| :lock: `SONAR_AUTH_TOKEN`| SonarQube authentication [token](https://docs.sonarqube.org/latest/user-guide/user-token/) (depends on your authentication method) | _none_ |
| :lock: `SONAR_LOGIN`     | SonarQube login (depends on your authentication method)                | _none_ |
| :lock: `SONAR_PASSWORD`  | SonarQube password (depends on your authentication method)             | _none_ |
| `SONAR_BASE_ARGS`        | SonarQube [analysis arguments](https://docs.sonarqube.org/latest/analysis/analysis-parameters/) | `sonar:sonar -Dsonar.host.url=${SONAR_URL} -Dsonar.links.homepage=${CI_PROJECT_URL} -Dsonar.links.ci=${CI_PROJECT_URL}/-/pipelines -Dsonar.links.issue=${CI_PROJECT_URL}/-/issues -Dsonar.branch.name=${CI_COMMIT_REF_NAME}` |
| `SONAR_BASE_ARGS`        | SonarQube [analysis arguments](https://docs.sonarqube.org/latest/analysis/analysis-parameters/) | `sonar:sonar -Dsonar.host.url=${SONAR_URL} -Dsonar.links.homepage=${CI_PROJECT_URL} -Dsonar.links.ci=${CI_PROJECT_URL}/-/pipelines -Dsonar.links.issue=${CI_PROJECT_URL}/-/issues` |
| :lock: `SONAR_GITLAB_TOKEN` | GitLab [access token](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html) with `api` scope. When set, activates the [Sonar GitLab plugin](https://github.com/gabrie-allaigre/sonar-gitlab-plugin/#plugins-properties) integration. | _none_ |
| `SONAR_BRANCH_ANALYSIS_DISABLED` | Set to disable automatic [Pull Request Analysis](https://docs.sonarqube.org/latest/analysis/pull-request/) and [Branch Analysis](https://docs.sonarqube.org/latest/branches/overview/)  | _none_ (enabled) |
| `SONAR_GITLAB_ARGS`      | Extra arguments to use with [Sonar GitLab plugin](https://github.com/gabrie-allaigre/sonar-gitlab-plugin/#plugins-properties) | `-Dsonar.gitlab.url=${CI_SERVER_URL} -Dsonar.gitlab.user_token=${SONAR_GITLAB_TOKEN} -Dsonar.gitlab.project_id=${CI_PROJECT_ID} -Dsonar.gitlab.commit_sha=${CI_COMMIT_SHA} -Dsonar.gitlab.ref_name=${CI_COMMIT_REF_NAME}` |
| `SONAR_AUTO_ON_DEV_DISABLED` | When set, SonarQube analysis becomes **manual** on development branches (automatic otherwise) | _none_ |
| `SONAR_QUALITY_GATE_ENABLED` | Enables blocking check of SonarQube [Quality Gate](https://docs.sonarqube.org/latest/user-guide/quality-gates/) | _none_ (disabled) |

#### About branch analysis
#### Automatic Branch Analysis & Pull Request Analysis

As you can see, default SonarQube analysis arguments uses the [Branch Analysis](https://docs.sonarqube.org/latest/branches/overview/)
feature (`sonar.branch.name` argument).
By default, this template tries to auto-detect and use [Pull Request Analysis](https://docs.sonarqube.org/latest/analysis/pull-request/) or [Branch Analysis](https://docs.sonarqube.org/latest/branches/overview/) (depending on the context).

This is a great SonarQube feature but it assumes one of the following conditions:
Those is a great SonarQube features but it assumes one of the following conditions:

* you are using a [Developer Edition](https://www.sonarqube.org/developer-edition/) version,
* or you are using Community Edition with an opensource plugin emulating the Branch Analysis feature:
    * etiher [sonar-branch-community](https://github.com/msanez/sonar-branch-community),
    * or [sonarqube-community-branch-plugin](https://github.com/mc1arke/sonarqube-community-branch-plugin),
    * ...
* or you are using Community Edition with an opensource plugin emulating those features, such as [sonarqube-community-branch-plugin](https://github.com/mc1arke/sonarqube-community-branch-plugin).

If you're not in those cases, then the SonarQube analysis will fail with default parameters. You'll have to override the
default `SONAR_BASE_ARGS` and disable it by removing the `sonar.branch.name` argument.
If you're not in one of those cases, then you shall disable this feature by setting `SONAR_BRANCH_ANALYSIS_DISABLED`.

If you leave the feature enabled, if `SONAR_AUTH_TOKEN` is provided, the template will try to autodetect (using GitLab APIs) an opened merge request matching the current branch:

* If one is found, a SonarQube [Pull Request Analysis](https://docs.sonarqube.org/latest/analysis/pull-request/) will be made.
* Otherwise, a simple [Branch Analysis](https://docs.sonarqube.org/latest/branches/overview/) is performed on the current branch.

#### About Sonar GitLab plugin

+8 −3
Original line number Diff line number Diff line
@@ -64,14 +64,19 @@
        {
          "name": "SONAR_BASE_ARGS",
          "description": "SonarQube [analysis arguments](https://docs.sonarqube.org/latest/analysis/analysis-parameters/)",
          "default": "sonar:sonar -Dsonar.host.url=${SONAR_URL} -Dsonar.links.homepage=${CI_PROJECT_URL} -Dsonar.links.ci=${CI_PROJECT_URL}/-/pipelines -Dsonar.links.issue=${CI_PROJECT_URL}/-/issues -Dsonar.branch.name=${CI_COMMIT_REF_NAME}",
          "default": "sonar:sonar -Dsonar.host.url=${SONAR_URL} -Dsonar.links.homepage=${CI_PROJECT_URL} -Dsonar.links.ci=${CI_PROJECT_URL}/-/pipelines -Dsonar.links.issue=${CI_PROJECT_URL}/-/issues",
          "advanced": true
        },
		{
          "name": "SONAR_GITLAB_TOKEN",
          "description": "GitLab API access token. When set, activates the [Sonar GitLab plugin](https://github.com/gabrie-allaigre/sonar-gitlab-plugin/#plugins-properties) integration",
          "description": "GitLab API access token. When set, activates the [Sonar GitLab plugin](https://github.com/gabrie-allaigre/sonar-gitlab-plugin/#plugins-properties) integration, and enables SonarQube [Pull Request Analysis](https://docs.sonarqube.org/latest/analysis/pull-request/)",
          "secret": true
        },
        {
          "name": "SONAR_BRANCH_ANALYSIS_DISABLED",
          "description": "Set to disable automatic [Pull Request Analysis](https://docs.sonarqube.org/latest/analysis/pull-request/) and [Branch Analysis](https://docs.sonarqube.org/latest/branches/overview/)",
          "type": "boolean"
        },
        {
          "name": "SONAR_GITLAB_ARGS",
          "description": "Extra arguments to use with [Sonar GitLab plugin](https://github.com/gabrie-allaigre/sonar-gitlab-plugin/#plugins-properties)",
+35 −3
Original line number Diff line number Diff line
@@ -58,7 +58,6 @@ variables:
    -Dsonar.links.homepage=${CI_PROJECT_URL}
    -Dsonar.links.ci=${CI_PROJECT_URL}/-/pipelines
    -Dsonar.links.issue=${CI_PROJECT_URL}/-/issues
    -Dsonar.branch.name=${CI_COMMIT_REF_NAME}

  # Sonar GitLab plugin args
  # see: https://github.com/gabrie-allaigre/sonar-gitlab-plugin/#plugins-properties
@@ -130,6 +129,38 @@ stages:
    fi
  }
  
  function sonar_autodetect_mr() {
    if [[ "$SONAR_BRANCH_ANALYSIS_DISABLED" ]]
    then
      log_info "Branch Analysis and Merge Request Analysis are disabled"
      return
    fi
    if [[ "$CI_MERGE_REQUEST_ID" ]]
    then
      # we are in an MR pipeline: no need to pass arguments as the SonarScanner for Maven will
      log_info "Merge Request pipeline detected: let Maven plugin handle..."
      return
    fi
    if [[ -n "$SONAR_GITLAB_TOKEN" ]]
    then 
      curl -sS --header "PRIVATE-TOKEN: $SONAR_GITLAB_TOKEN" "$CI_API_V4_URL/projects/${CI_PROJECT_ID}/merge_requests?state=opened&source_branch=${CI_COMMIT_REF_NAME}" -o mr.json
      if [ "$(cat mr.json)" != "[]" ]
      then
        mr_title=$(sed -E 's/.*"title":"([^"]*)".*/\1/g' < mr.json)
        mr_target=$(sed -E 's/.*"target_branch":"([^"]*)".*/\1/g' < mr.json)
        mr_id=$(sed -E 's/.*"iid":([0-9]+).*/\1/g' < mr.json)
        log_info "Merge Request \\e[33;1m$mr_title\\e[0m detected associated to this branch: trigger MR analysis..."
        export sonar_mr_args="-Dsonar.pullrequest.key=$mr_id -Dsonar.pullrequest.branch=${CI_COMMIT_REF_NAME} -Dsonar.pullrequest.base=$mr_target"
      else 
        log_info "No Merge Request associated to this branch: trigger branch analysis..."
        export sonar_mr_args="-Dsonar.branch.name=${CI_COMMIT_REF_NAME}"
      fi
    else 
      log_info "\$SONAR_GITLAB_TOKEN unset: trigger branch analysis..."
      export sonar_mr_args="-Dsonar.branch.name=${CI_COMMIT_REF_NAME}"
    fi
  }

  function sonar_quality_gate_check() {
    log_info "--- Waiting for Sonar analysis end..."
    taskId=$(grep ceTaskId target/sonar/report-task.txt | cut -c10-)
@@ -443,8 +474,9 @@ mvn-sonar:
  stage: test
  extends: .mvn-base
  script:
    - if [[ "$SONAR_GITLAB_TOKEN" ]]; then sonar_extra_args=$SONAR_GITLAB_ARGS; fi
    - mvn ${TRACE+-Dsonar.verbose=true} $MAVEN_CLI_OPTS $java_proxy_args ${SONAR_AUTH_TOKEN+-Dsonar.login=$SONAR_AUTH_TOKEN} ${SONAR_LOGIN+-Dsonar.login=$SONAR_LOGIN} ${SONAR_PASSWORD+-Dsonar.password=$SONAR_PASSWORD} $SONAR_BASE_ARGS $sonar_extra_args
    - sonar_autodetect_mr
    - if [[ "$SONAR_GITLAB_TOKEN" ]]; then sonar_extra_args="$SONAR_GITLAB_ARGS"; fi
    - mvn ${TRACE+-Dsonar.verbose=true} $MAVEN_CLI_OPTS $java_proxy_args ${SONAR_AUTH_TOKEN+-Dsonar.login=$SONAR_AUTH_TOKEN} ${SONAR_LOGIN+-Dsonar.login=$SONAR_LOGIN} ${SONAR_PASSWORD+-Dsonar.password=$SONAR_PASSWORD} $SONAR_BASE_ARGS $sonar_extra_args $sonar_mr_args
    - if [[ "$SONAR_QUALITY_GATE_ENABLED" ]]; then sonar_quality_gate_check; fi
  rules:
    # exclude merge requests