<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Martin Huter</title>
    <description>The latest articles on DEV Community by Martin Huter (@mgh87).</description>
    <link>https://dev.to/mgh87</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F132304%2F6e4be09d-8aab-4292-acb6-0534a7d0d29e.jpeg</url>
      <title>DEV Community: Martin Huter</title>
      <link>https://dev.to/mgh87</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mgh87"/>
    <language>en</language>
    <item>
      <title>Gitlab Integration with Sonarqube: Automate your quality gates</title>
      <dc:creator>Martin Huter</dc:creator>
      <pubDate>Fri, 27 Sep 2019 15:00:27 +0000</pubDate>
      <link>https://dev.to/mgh87/gitlab-integration-with-sonarqube-automate-your-quality-gates-3j1e</link>
      <guid>https://dev.to/mgh87/gitlab-integration-with-sonarqube-automate-your-quality-gates-3j1e</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL/DR:&lt;/strong&gt; A new parameter made this post for a lot of use cases obsolete. You can activate sonar.qualitygate.wait to have a built in waiting mechanism which exits the plugin with a non-zero return code on a failing quality gate. More information at: &lt;a href="https://docs.sonarqube.org/latest/analysis/gitlab-cicd/"&gt;https://docs.sonarqube.org/latest/analysis/gitlab-cicd/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I accidentally killed the first release of this article so here its up again. Any improvement suggestions very welcome.&lt;/p&gt;

&lt;p&gt;This article was originally posted on my companies blog at &lt;a href="https://viesure.io/blog"&gt;viesure.io/blog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Last week I took the task of our sprint to create a build breaker step for Sonar in our GitLab deployment pipeline.&lt;br&gt;
To clarify this term: We wanted each build to break if the quality gate of Sonar fails.&lt;br&gt;
Since this was not straightforward, I wanted to share my result.&lt;br&gt;
I am using the API of the SonarQube server to get the information about the status of the quality gate.&lt;/p&gt;
&lt;h2&gt;
  
  
  Preconditions to use the script
&lt;/h2&gt;

&lt;p&gt;A Sonar API Token that has sufficient rights to access the data of the analysis. If you don't know where to get the token look it up in the &lt;a href="https://docs.sonarqube.org/latest/user-guide/user-token/"&gt;documentation&lt;/a&gt;&lt;br&gt;
A sonar runner needs to be executed before, to get a ceTaskId for the requests. For maven the sonar:sonar runner creates a file at target/sonar/report-task.txt.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#Example content of the report-task.txt&lt;/span&gt;
&lt;span class="nv"&gt;projectKey&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;io.viesure:project
&lt;span class="nv"&gt;serverUrl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://sonar.server.url
&lt;span class="nv"&gt;serverVersion&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;7.7.0.23042
&lt;span class="nv"&gt;branch&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;master
&lt;span class="nv"&gt;dashboardUrl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://sonar.server.url/dashboard?id&lt;span class="o"&gt;=&lt;/span&gt;io.viesure%3Aproject&amp;amp;branch&lt;span class="o"&gt;=&lt;/span&gt;master
&lt;span class="nv"&gt;ceTaskId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;AWy0noy7Aqf9WEmmjKgw
&lt;span class="nv"&gt;ceTaskUrl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://sonar.server.url/api/ce/task?id&lt;span class="o"&gt;=&lt;/span&gt;AWy0noy7Aqf9WEmmjKgw

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  A detailed explanation of the script
&lt;/h2&gt;

&lt;p&gt;In this section, I will explain the parts of the script step by step.&lt;br&gt;
TL;DR at the end is a link to the full script on GitHub.&lt;/p&gt;
&lt;h3&gt;
  
  
  Semi-static parameters
&lt;/h3&gt;

&lt;p&gt;Since we are using Sonar with Maven in a CI/CD pipeline, I hard link the source for the result. Depending on your runner, this might differ. A better practice would also be to also extract the sonar server property to the CI environment variables, to reduce the nonfunctional information within the code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env sh&lt;/span&gt;

&lt;span class="nv"&gt;SONAR_RESULT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;2&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="s2"&gt;"target/sonar/report-task.txt"&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="nv"&gt;SONAR_SERVER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;1&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="s2"&gt;"https://our.sonar.server"&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Sonar API Token
&lt;/h3&gt;

&lt;p&gt;We are checking if the environment has set the sonar API token. If this variable is not available, we terminate the script with a proper error message.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="nv"&gt;$SONAR_API_TOKEN&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Sonar API Token not set."&lt;/span&gt;
  &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Extract ceTaskId from Sonar result and validate access rights
&lt;/h3&gt;

&lt;p&gt;First, we are checking if the sonar result file exists.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nv"&gt;$SONAR_RESULT&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Sonar result does not exist"&lt;/span&gt;
  &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Afterwards, we use sed to extract the task id for further processing. The task id is a unique hash that refers to a sonar runner result that is processed by the server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;CE_TASK_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'s/ceTaskId=\(.*\)/\1/p'&lt;/span&gt; &amp;lt; &lt;span class="nv"&gt;$SONAR_RESULT&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="nv"&gt;$CE_TASK_ID&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"ceTaskId is not set from sonar build."&lt;/span&gt;
  &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we are checking if our API Token has proper access rights to get information about the processing state of the found task id.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;HTTP_STATUS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s1"&gt;'%{http_code}'&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="nv"&gt;$SONAR_API_TOKEN&lt;/span&gt;: &lt;span class="nv"&gt;$SONAR_SERVER&lt;/span&gt;/api/ce/task&lt;span class="se"&gt;\?&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="se"&gt;\=&lt;/span&gt;&lt;span class="nv"&gt;$CE_TASK_ID&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;  &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HTTP_STATUS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-ne&lt;/span&gt; 200 &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Sonar API Token has no access rights."&lt;/span&gt;
  &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Find analysisId for a taskId
&lt;/h3&gt;

&lt;p&gt;After processing a project with a sonar runner the SonarQube server processes the result to generate an analysis report. The task.analysisId from the response JSON is available after the process has finished. For this reason, I created a simple time loop to evaluate the analysisId from the response. &lt;a href="https://stedolan.github.io/jq/"&gt;Jq&lt;/a&gt; returns null if the property that is filtered is not part of the JSON.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;ANALYSIS_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-XGET&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="nv"&gt;$SONAR_API_TOKEN&lt;/span&gt;: &lt;span class="nv"&gt;$SONAR_SERVER&lt;/span&gt;/api/ce/task&lt;span class="se"&gt;\?&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="se"&gt;\=&lt;/span&gt;&lt;span class="nv"&gt;$CE_TASK_ID&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; .task.analysisId&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;I&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
&lt;span class="nv"&gt;TIMEOUT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$ANALYSIS_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"null"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;do
  if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$TIMEOUT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; 30 &lt;span class="o"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Timeout of "&lt;/span&gt; + &lt;span class="nv"&gt;$TIMEOUT&lt;/span&gt; + &lt;span class="s2"&gt;" seconds exceeded for getting ANALYSIS_ID"&lt;/span&gt;
    &lt;span class="nb"&gt;exit &lt;/span&gt;1
  &lt;span class="k"&gt;fi
  &lt;/span&gt;&lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="nv"&gt;$I&lt;/span&gt;
  &lt;span class="nv"&gt;TIMEOUT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;TIMEOUT+I&lt;span class="k"&gt;))&lt;/span&gt;
  &lt;span class="nv"&gt;I&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;I+1&lt;span class="k"&gt;))&lt;/span&gt;
  &lt;span class="nv"&gt;ANALYSIS_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-XGET&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="nv"&gt;$SONAR_API_TOKEN&lt;/span&gt;: &lt;span class="nv"&gt;$SONAR_SERVER&lt;/span&gt;/api/ce/task&lt;span class="se"&gt;\?&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="se"&gt;\=&lt;/span&gt;&lt;span class="nv"&gt;$CE_TASK_ID&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; .task.analysisId&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Get the quality gate information
&lt;/h3&gt;

&lt;p&gt;The quality gate API endpoint returns a JSON that contains all parts of the quality analysis from Sonar. The projectStatus.status is representing the state of the quality gate and was our desired health metric. If you want to have a different setup, adapt the jq processing to your needs and find your breaking parameter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;STATUS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-XGET&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="nv"&gt;$SONAR_API_TOKEN&lt;/span&gt;: &lt;span class="nv"&gt;$SONAR_SERVER&lt;/span&gt;/api/qualitygates/project_status?analysisId&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$ANALYSIS_ID&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; .projectStatus.status&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$STATUS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ERROR"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Qualitygate failed."&lt;/span&gt;
  &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi

&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Sonar Qualitygate is OK."&lt;/span&gt;
&lt;span class="nb"&gt;exit &lt;/span&gt;0

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Executing the script in the pipeline
&lt;/h2&gt;

&lt;p&gt;First, execute the script after the sonar execution.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env sh&lt;/span&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;MAVEN_OPTS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"-Dmaven.repo.local=maven.repository -Dsonar.branch.name=&lt;/span&gt;&lt;span class="nv"&gt;$CI_COMMIT_REF_NAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

./mvnw sonar:sonar
&lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;SCRIPT_DIR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/sonar_break_build.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then define a job that executes sonar and the breaker.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;sonar&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sonar&lt;/span&gt;
    &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;java11&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mvn-build&lt;/span&gt;
    &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;${SCRIPT_DIR}/mvn_sonarqube.sh&lt;/span&gt;
    &lt;span class="na"&gt;only&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;branches&lt;/span&gt;
    &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;maven.repository/&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;More detailed information about the script can is available at our blog post about &lt;a href="https://viesure.io/optimizing-our-build-times-with-gitlab-on-aws/"&gt;optimizing our build times with gitlab on aws&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Our goal is to deliver a good maintainable code as fast as possible.&lt;br&gt;
To achieve this fast feedback is crucial and breaking our build, on the first commit that introduces new security issues, bugs and code smells, is game-changing for this goal.&lt;/p&gt;

&lt;p&gt;Some colleagues might be annoyed at first, that their code is instantly analyzed or they have to fix stuff that does not pass the quality gate right away. On the upside code that does not fit the quality standard won't ever be merged to develop or master.&lt;br&gt;
Also, you now need to interact with Sonar more often, but this can also be an advantage to shape your ruleset to the degree that everybody can live with it on a daily basis.&lt;br&gt;
Another question on fine-tuning that came up was if we should break the build on Sonar or mark it as unstable to minimize the disruption of the pipeline, but still get the feedback from Sonar.&lt;/p&gt;

&lt;p&gt;I hope you enjoyed the read.&lt;br&gt;
Additional, I would love some feedback on the shell script to make it as robust as possible, since its part of a deploy pipeline.&lt;br&gt;
What's your opinion of breaking your pipeline with Sonar?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/viesure/blog-sonar-build-breaker"&gt;viesure/blog-sonar-build-breaker&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Tests versus Documentation</title>
      <dc:creator>Martin Huter</dc:creator>
      <pubDate>Sat, 16 Mar 2019 18:56:43 +0000</pubDate>
      <link>https://dev.to/mgh87/tests-versus-documentation-2gi4</link>
      <guid>https://dev.to/mgh87/tests-versus-documentation-2gi4</guid>
      <description>&lt;p&gt;Have you ever been in the situation that you have been thrown under the bus and needed to fix a bug in an unknown code base with a real tight deadline? Or joined a new team/project which has tons of legacy code where you do not know where to start?&lt;/p&gt;

&lt;p&gt;Well let's create some hypothetical project in our mind and we call it &lt;strong&gt;&lt;em&gt;Schroedinger's repository&lt;/em&gt;&lt;/strong&gt;. It has the described properties that its code base is rather large and you are not familiar with it. You remember that cat from school that was either dead or alive. Well in our example we won't murder innocent cats, but this project can have two representations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You have a well-documented API and lots of comment flavor that is guiding you through the code, but tests are barely existent.&lt;/li&gt;
&lt;li&gt;There is a good level of test coverage, tests are well structured in unit, integration, etc. tests. The downside here is that the API is lacking proper descriptions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In my experience, if I need to fix a bug inside a code base I prefer proper automated tests, to see if I would break something. On the other hand, when my task is to enhance an API or create another layer upon something, proper documentation is preferably in my view.&lt;/p&gt;

&lt;p&gt;Now I am asking you out there, if you would have to get in touch with our legacy &lt;strong&gt;&lt;em&gt;Schroedinger's repository&lt;/em&gt;&lt;/strong&gt; which state would you prefer, and what's your reasoning?&lt;/p&gt;

&lt;p&gt;Another thing I want to point out:&lt;br&gt;
We are all producing legacy code. The question is what should our legacy look like?&lt;/p&gt;

</description>
      <category>legacy</category>
      <category>mindgame</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Contributing to OSS</title>
      <dc:creator>Martin Huter</dc:creator>
      <pubDate>Wed, 06 Feb 2019 20:04:23 +0000</pubDate>
      <link>https://dev.to/mgh87/contributing-to-oss-44an</link>
      <guid>https://dev.to/mgh87/contributing-to-oss-44an</guid>
      <description>&lt;p&gt;Hey guys out there! If you are like me you are using most of your time coding some bits of OSS. Have you ever thought about contributing to some of those nice frameworks, services and all this other cool stuff? Well I did, but I got to tell you I did not really achieve a lot.&lt;/p&gt;

&lt;p&gt;I did some smaller pull requests on GitHub or tried to help to solve a issue with the investigation process. But that's it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Whats your approach to contribute to OSS
&lt;/h3&gt;

&lt;p&gt;I would like to know the stories of you guys and girls out there how you tackle this subject, or if you even tackle it? Have you any trick to select a good project that's worth your time?&lt;/p&gt;

&lt;h3&gt;
  
  
  How to improve my way to make a larger impact to the OSS world
&lt;/h3&gt;

&lt;p&gt;Sooo, in future I want to sacrifice a hour every week to work on OSS, and try to report at dev.to about my progress, to have additional motivation to procrastinate this process anymore. This is about 0.5% of my time that should be doable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Annex
&lt;/h3&gt;

&lt;p&gt;First I wanted to thank &lt;a class="comment-mentioned-user" href="https://dev.to/marek"&gt;@marek&lt;/a&gt;
 for his article about writing more, which motivated to put myself out there.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/marek" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XZUI-52x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--GP1jcA5A--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/123184/7eefdb7c-1047-4617-8608-f33db3dc5ba7.jpg" alt="marek image"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/marek/three-arguments-for-why-you-should-write-more-1no6" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Three Arguments for Why You Should Write More&lt;/h2&gt;
      &lt;h3&gt;Marek Zaluski ・ Jan 28 '19 ・ 4 min read&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#writing&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#career&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#discuss&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;Second I want to thank dev.to that there editor is in markdown, since I use this language on daily bases to write documentation, it was really easy to adjust.&lt;/p&gt;

&lt;p&gt;Image origin: &lt;a href="https://pixabay.com/"&gt;https://pixabay.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>opensource</category>
      <category>writing</category>
    </item>
  </channel>
</rss>
