<?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>Forem: JetBrains Qodana</title>
    <description>The latest articles on Forem by JetBrains Qodana (@qodana).</description>
    <link>https://forem.com/qodana</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%2Forganization%2Fprofile_image%2F5135%2Fa405b1df-c861-4165-a841-9285452e2b96.png</url>
      <title>Forem: JetBrains Qodana</title>
      <link>https://forem.com/qodana</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/qodana"/>
    <language>en</language>
    <item>
      <title>Qodana Is Out Of Preview With First-Class JetBrains IDE Integration</title>
      <dc:creator>Valerie Kuzmina</dc:creator>
      <pubDate>Fri, 21 Jul 2023 08:33:58 +0000</pubDate>
      <link>https://forem.com/qodana/qodana-is-out-of-preview-with-first-class-jetbrains-ide-integration-1fn3</link>
      <guid>https://forem.com/qodana/qodana-is-out-of-preview-with-first-class-jetbrains-ide-integration-1fn3</guid>
      <description>&lt;p&gt;JetBrains has always strived to deliver tools that make developers’ work enjoyable, creative, and thought-provoking. JetBrains IDEs are designed to understand code and provide valuable suggestions for improving it. Having these tips available in the editor is incredibly helpful. But modern CI-centric workflows require a reliable quality gate in your build pipeline. With that in mind, we created Qodana. &lt;/p&gt;

&lt;p&gt;Qodana is the only code quality platform on the market that uses inspections native to JetBrains IDEs and expands the smartness of your JetBrains IDE to the CI server. &lt;/p&gt;

&lt;p&gt;We built this powerful static analysis engine to enable development teams to automate code reviews, build quality gates, and enforce code quality guidelines enterprise-wide – all within their JetBrains ecosystem. The platform can be integrated into any CI/CD pipeline and can analyze code written in 60+ languages, including Java, JavaScript, TypeScript, PHP, Kotlin, Python, Go, and C#.&lt;/p&gt;

&lt;p&gt;Today, Qodana announces a huge milestone: It’s no longer in preview and is available commercially with some major improvements. Get in now to enjoy a 50% discount on your first year.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.jetbrains.com/qodana/" rel="noopener noreferrer"&gt;Try Qodana for free&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s new in Qodana 2023.2
&lt;/h2&gt;

&lt;p&gt;Many of you have been wondering where the name “Qodana” came from. Let us explain.&lt;/p&gt;

&lt;p&gt;“Qodana” stands for “code analyzer”.&lt;/p&gt;

&lt;p&gt;Back in 2021, after weeks of fruitless brainstorming on the product’s name, we turned to one of our polyglot colleagues for guidance. Ten minutes later, she suggested “Qodana” and right away we knew that was it.&lt;/p&gt;

&lt;p&gt;Since launching Qodana in EAP in 2021, we’ve been overjoyed by the response. To date, Qodana analyzes commits to over 9K unique projects on a monthly basis – 80% of these projects are commercial.&lt;/p&gt;

&lt;p&gt;Our early adopters have taught us a lot about what they need, and we’ve used that knowledge to make some major improvements to the static code analysis engine of Qodana. &lt;/p&gt;

&lt;h2&gt;
  
  
  1. Server-side analysis by Qodana is now fully integrated with JetBrains IDEs 2023.2
&lt;/h2&gt;

&lt;p&gt;Static analysis tools are known to be complicated to configure. With the Qodana 2023.2 release, we’ve eliminated this pain by fully integrating our code quality platform with almost all JetBrains IDEs: IntelliJ IDEA, WebStorm, PhpStorm, PyCharm, Rider, and GoLand. Please note that this functionality won’t be available until the release of the 2023.2 versions of our IDEs. &lt;/p&gt;

&lt;p&gt;This integration will bring two important benefits. &lt;/p&gt;

&lt;p&gt;The first benefit is the ease of configuration. You can try the local analysis with just a few clicks, view the list of problems across your entire project, and then configure Qodana in your preferred CI/CD system to establish the quality gate and run server-side checks. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ads7alix9jen3u8qwcx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ads7alix9jen3u8qwcx.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The second benefit is an improved code quality workflow. Once Qodana is configured in the continuous integration server, you’ll be able to see the results of the server-side analysis without leaving the IDE – right out of the box. Alternatively, you can navigate directly to Qodana Cloud to see the issue overview in a straightforward sunburst diagram.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Code coverage support
&lt;/h2&gt;

&lt;p&gt;Qodana now supports processing code coverage for Java, Kotlin, PHP, JavaScript and TypeScript. While running automated tests, Qodana will display how much of the code has been executed by relying on the output from the known unit testing frameworks. This way, users will be able to 1) review the degree of code coverage, 2) spot parts of the code that need more testing, 3) assess the quality of the tests themselves.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz9wtvzzaqetsxmx9hw5l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz9wtvzzaqetsxmx9hw5l.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Vulnerability checker based on the Checkmarx data
&lt;/h2&gt;

&lt;p&gt;Now Qodana is bundled with the vulnerability checker, powered by IntelliJ IDEA. This inspection is designed to spot vulnerable external packages used in the project. The data about vulnerabilities is provided by the software security company Checkmarx.&lt;/p&gt;

&lt;p&gt;The vulnerability checker goes beyond just providing security information. It also offers valuable remediation insights. Developers can take immediate action to address vulnerabilities by quickly migrating to a safe and stable version of the package without known vulnerability issues. &lt;/p&gt;

&lt;h2&gt;
  
  
  4. Quick-fixes (experimental)
&lt;/h2&gt;

&lt;p&gt;All Qodana linters (except for .NET) will provide users with the power of quick-fixes to boost their coding efficiency. Qodana is now able to apply quick-fixes to issues that can be resolved automatically and create a new pull request with the applied changes (currently available only for GitHub Actions). Then, the user will be able to review these changes before committing. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcu0ljngzyhk8i7yf0oyr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcu0ljngzyhk8i7yf0oyr.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the complete list of changes, refer to &lt;a href="https://www.jetbrains.com/help/qodana/new-in-2023-2.html" rel="noopener noreferrer"&gt;What’s new in Qodana 2023.2&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Qodana features beyond the 2023.2 release
&lt;/h2&gt;

&lt;p&gt;In case you haven’t tried Qodana yet, here’s a brief overview of features that are currently available in the product – beyond the newly released ones. &lt;/p&gt;

&lt;h2&gt;
  
  
  2500+ code inspections – exclusive Qodana inspections included
&lt;/h2&gt;

&lt;p&gt;Qodana can spot performance issues, unused declarations, vulnerable dependencies, potential security issues, confusing code constructs, naming and style conventions, and much more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interactive inspection reports and dashboards
&lt;/h2&gt;

&lt;p&gt;Discover issues and trends in your code and better understand the quality of your project with our fancy sunburst diagram. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F57019ik6rs49m3f5ooxr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F57019ik6rs49m3f5ooxr.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Cloud-based overview of reports
&lt;/h2&gt;

&lt;p&gt;You can accumulate all of your Qodana reports in a single place – Qodana Cloud – and explore project trends with interactive dashboards.&lt;/p&gt;

&lt;h2&gt;
  
  
  The baseline for getting your technical debt under control
&lt;/h2&gt;

&lt;p&gt;A snapshot of the codebase, or baseline, is taken during specific Qodana runs. You can compare your current code with its baseline state and see new, unchanged, and resolved problems. &lt;/p&gt;

&lt;p&gt;For example, you can use the baseline to put less critical issues on the back burner and focus on fixing bugs that are either new or highly critical.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc7486gsczsgem0ur7ez9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc7486gsczsgem0ur7ez9.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Third-party license audit
&lt;/h2&gt;

&lt;p&gt;Scan dependencies in your code repository to find their licenses and see if they’re compatible with your project license.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inspection constructor
&lt;/h2&gt;

&lt;p&gt;Looking to scan for a specific problem that Qodana doesn’t cover yet? You can integrate it with third-party inspection tools or create your own plugins.&lt;/p&gt;

&lt;p&gt;A video is worth a thousand words, so please feel free to check out the &lt;a href="https://youtu.be/WrhnUnzMUCg" rel="noopener noreferrer"&gt;Qodana overview video&lt;/a&gt; by our Developer Advocate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Qodana pricing that makes managers say “Wow”
&lt;/h2&gt;

&lt;p&gt;What decision-makers especially like about Qodana is that we charge per active contributor, regardless of the number of lines in the project. This makes Qodana an especially cost-efficient offer. &lt;/p&gt;

&lt;p&gt;Qodana is available in three plans, including a free plan with limited language support, and paid plans starting from $6 per active contributor per month. Paid plans require minimum of 3 active contributors. &lt;/p&gt;

&lt;p&gt;The most advanced Qodana plan, which offers more security inspections and the license audit, comes with a one-year 50% discount! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhmzeb1677vqdubruqqjt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhmzeb1677vqdubruqqjt.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to get started with Qodana?
&lt;/h2&gt;

&lt;p&gt;Simply head to our &lt;a href="https://www.jetbrains.com/qodana/" rel="noopener noreferrer"&gt;website&lt;/a&gt; and claim your free trial! You’ll be asked to create an account in Qodana Cloud and connect the specified linter to your project and preferred CI/CD system. It’s that easy!&lt;/p&gt;

&lt;p&gt;Our mission is to help developers deliver code they can be proud of. We hope you enjoy Qodana and all the intelligence it packs into a straightforward sunburst diagram. If you have any questions, feel free to submit a ticket to the &lt;a href="https://youtrack.jetbrains.com/issues?q=%23QD&amp;amp;_ga=2.133486798.1910624791.1689585216-3373284.1664957792&amp;amp;_gac=1.79264486.1689239733.CjwKCAjwwb6lBhBJEiwAbuVUSkFX63d9ZOiUdVTPW3HLgsotpIsY-whA2LG7bFNB3rZWxVM7_YFlDBoCM-kQAvD_BwE&amp;amp;_gl=1*rt5956*_ga*MzM3MzI4NC4xNjY0OTU3Nzky*_ga_9J976DJZ68*MTY4OTkyNzQzOS4xNzQuMS4xNjg5OTI3Nzk0LjIzLjAuMA.." rel="noopener noreferrer"&gt;issue tracker&lt;/a&gt; or leave a comment below.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>coding</category>
      <category>codequality</category>
      <category>cicd</category>
    </item>
    <item>
      <title>Secure Your PHP Code With Taint Analysis by Qodana</title>
      <dc:creator>Valerie Kuzmina</dc:creator>
      <pubDate>Fri, 10 Mar 2023 14:16:23 +0000</pubDate>
      <link>https://forem.com/qodana/secure-your-php-code-with-taint-analysis-by-qodana-1mj8</link>
      <guid>https://forem.com/qodana/secure-your-php-code-with-taint-analysis-by-qodana-1mj8</guid>
      <description>&lt;p&gt;It only takes one user to exploit a vulnerability in your project and breach your system. To defend programs against malicious inputs from external users (known as “taints”), development teams add taint checking to their static analysis routines. &lt;/p&gt;

&lt;p&gt;In this year’s first release, the &lt;a href="https://www.jetbrains.com/qodana/"&gt;Qodana&lt;/a&gt; team has delivered taint analysis for PHP in the EAP. The feature is available only in Qodana for PHP 2023.1 (jetbrains/qodana-php:2023.1-eap). Qodana for PHP was the first linter we released, so we decided to let PHP developers be the first to test our new security functionality, too. We plan on adding more languages in the future, after we’ve collected enough feedback.&lt;/p&gt;

&lt;p&gt;Read on to learn more about what taint analysis is and how it works in Qodana. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9I62NLIH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/clwaxqlnq3rcml4ydr0r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9I62NLIH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/clwaxqlnq3rcml4ydr0r.png" alt="Image description" width="880" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.jetbrains.com/qodana"&gt;GET STARTED WITH QODANA&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is taint analysis?
&lt;/h2&gt;

&lt;p&gt;A taint is any value that can pose a security risk when modified by an external user. If you have a taint in your code and unverified external data can be distributed across your program, hackers can execute these code fragments to cause SQL injection, arithmetic overflow, cross-site scripting, path traversal, and more. Usually they exploit these vulnerabilities to destroy the system, hijack credentials and other data, and change the system’s behavior.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zFYxtItn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gg88k8j31t85sz7igi3w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zFYxtItn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gg88k8j31t85sz7igi3w.png" alt="Image description" width="880" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Example of a taint. Arbitrary data from the GET parameter is displayed on the screen. For example, malicious users can exploit this vulnerability to tamper with your program’s layout.  &lt;/p&gt;

&lt;p&gt;As an extra layer of defense against malicious inputs, development teams execute taint analysis when they run a security audit on the program’s attack surface. &lt;/p&gt;

&lt;p&gt;Taint analysis is the process of assessing the flow of untrusted user input throughout the body of a function or method. Its core goal is to determine if unanticipated input can affect program execution in malicious ways. &lt;/p&gt;

&lt;p&gt;Taint sources are locations where a program gets access to potentially tainted data. Key points in a program that are susceptible to allowing tainted input are called taint sinks. This data can be propagated to the sinks via function calls or assignments.&lt;/p&gt;

&lt;p&gt;If you run taint analysis manually, you should spot all of the places where you accept data from external users and follow each piece of data through the system – the tainted data can be used in dozens of nodes. Then, to prevent taint propagation, you should take one of the two approaches described below:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sanitize the data&lt;/strong&gt;, i.e. transform data to a safe state. In the example below, we removed tags to resolve the taint. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Xw_xWDHr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r9qmighs2wsuae25wwtm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xw_xWDHr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r9qmighs2wsuae25wwtm.png" alt="Image description" width="880" height="137"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Validate the data&lt;/strong&gt;, i.e. check that the added data conforms to a required pattern. In the example below, we enable validation for the &lt;code&gt;$email&lt;/code&gt; variable. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ilQhMOz3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2gdmzu7kqtfctnhqbad3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ilQhMOz3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2gdmzu7kqtfctnhqbad3.png" alt="Image description" width="880" height="201"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In other words, the taint analysis inspection traces user-tainted data from its source to your sinks, and raises the alarm when you work with that data without sanitizing or validating it. &lt;/p&gt;

&lt;h2&gt;
  
  
  How taint analysis works in Qodana
&lt;/h2&gt;

&lt;p&gt;Taint analysis is performed by Qodana for PHP starting from version 2023.1 EAP. This functionality includes an inspection that scans the code and highlights the taint and potential vulnerability, the ability to open the problem in PhpStorm to address it on the spot, and a dataflow graph visualizing the taint flow. &lt;/p&gt;

&lt;h2&gt;
  
  
  Example #1. SQL injection
&lt;/h2&gt;

&lt;p&gt;Let’s take a look at an example of SQL injection and how Qodana detects it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gEYov37G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rbcggyhe1jyvgeulkgpd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gEYov37G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rbcggyhe1jyvgeulkgpd.png" alt="Image description" width="880" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, Qodana shows us the following taints in the system_admin() function:&lt;/p&gt;

&lt;p&gt;Markers 1-2: Data from user form input is retrieved from the $_POST global array with no sanitization or validation and is assigned to the variable $edit. This is a taint.&lt;/p&gt;

&lt;p&gt;Marker 3: The tainted variable $edit is passed to the system_save_settings function as an argument without any proper sanitization.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9DwtBJKq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/17dnyolv25xtwdbsv80t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9DwtBJKq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/17dnyolv25xtwdbsv80t.png" alt="Image description" width="880" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Marker 4: Data from the $edit variable is now located in the $edit parameter.&lt;/p&gt;

&lt;p&gt;Marker 5: The $edit variable is passed to foreach with the $filename key and $status value. Both variables contain the tainted data from the $edit variable concatenated with the string. The $filename key is concatenated with a tainted SQL string, and then it will propagate tainted data into an argument passed to the db_query.&lt;/p&gt;

&lt;p&gt;Marker 6: The $ filename key contains the tainted data from the $edit variable concatenated with the string.&lt;/p&gt;

&lt;p&gt;Marker 7: The $ filename key is concatenated with a tainted SQL string.&lt;/p&gt;

&lt;p&gt;Marker 8: Tainted SQL string will propagate tainted data into an argument passed to the &lt;code&gt;db_query&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Let’s now look at the db_query:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oQEh80nb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4qlrofkpext33wvlwr2n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oQEh80nb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4qlrofkpext33wvlwr2n.png" alt="Image description" width="880" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Marker 9: The tainted string will be located in the $query parameter.&lt;/p&gt;

&lt;p&gt;Marker 10: This parameter is going to be an argument of the _db_query function.&lt;/p&gt;

&lt;p&gt;Let’s move on to the _db_query function:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AkcIjbY0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f84czipidydows32uiko.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AkcIjbY0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f84czipidydows32uiko.png" alt="Image description" width="880" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Marker 11: Tainted data located in the first parameter $ query of the _db_query function.&lt;/p&gt;

&lt;p&gt;Marker 12: Data of the parameter is passed to the mysql_query function, which is a sink.&lt;/p&gt;

&lt;p&gt;The whole data flow above illustrates how data moves from $_POST[“edit”] to the mysql_query($query) without any sanitization or validation. This allows the attacker to manipulate the SQL query which was concatenated with a key of $_POST[“edit”] and trigger SQL injection. &lt;/p&gt;

&lt;p&gt;Qodana will spot these risks in your codebase along with all nodes where tainted data is used, so you can sanitize all tainted data in a timely manner. &lt;/p&gt;

&lt;h2&gt;
  
  
  Example #2. XSS problem
&lt;/h2&gt;

&lt;p&gt;In the Qodana UI, you can see a graph that visualizes the entire taint flow. Here’s how Qodana will visualize the XSS vulnerability, which contains 2 sources that would be merged on marker 5.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uMRBB9XS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x2f95eh48iol52hymx1v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uMRBB9XS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x2f95eh48iol52hymx1v.png" alt="Image description" width="880" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--W5d1k1AB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1t5bg2a5zci2yefzixwr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--W5d1k1AB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1t5bg2a5zci2yefzixwr.png" alt="Image description" width="880" height="537"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source 1&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Markers 1-2: Data from the searchUpdate.pos file will be read and tainted data will be assigned to the $start variable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source 2&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Markers 3-4: Data from files whose path is located in $posFile will be read and tainted data will be assigned to the $start variable.&lt;/p&gt;

&lt;p&gt;Marker 5: A merged tainted state from all conditional branches in the $start variable will be passed as an argument to the doUpdateSearchIndex method.&lt;/p&gt;

&lt;p&gt;Let’s look inside the doUpdateSearchIndex() method:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NJrLqazA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/592t4vvyrz3gijzk4xu9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NJrLqazA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/592t4vvyrz3gijzk4xu9.png" alt="Image description" width="880" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Markers 6-8: The $ start parameter will contain tainted data on this dataflow slice and then it will be passed within a concatenated string as an argument to the &lt;code&gt;output&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;Let’s look inside the output method:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3EwxMS0O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ojno451lsmsjaw66f51.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3EwxMS0O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ojno451lsmsjaw66f51.png" alt="Image description" width="880" height="575"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Marker 9: Tainted data contained inside the transmitted string will be located in the $out parameter.&lt;/p&gt;

&lt;p&gt;Marker 10: Data from the $out parameter will be transferred to the &lt;code&gt;print&lt;/code&gt; function without any sanitization. This function is a sink and causes XSS vulnerability, which can be exploited.&lt;/p&gt;

&lt;p&gt;To exploit the vulnerability, an attacker can, for example, upload a shell script instead of the expected files in markers 1 and 2, and will be able to put any information onto the web page as a result of an unsanitized print function.&lt;/p&gt;

&lt;p&gt;Qodana will alert you to this vulnerability and give it a high priority so that you can resolve it as soon as possible and prevent the hack.  &lt;/p&gt;

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

&lt;p&gt;Taint analysis helps eliminate exploitable attack surfaces, so it’s an effective method to reduce risk to your software. To learn about taint analysis and Qodana in detail, explore Qodana documentation.&lt;/p&gt;

&lt;p&gt;Happy developing and keep your code healthy!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.jetbrains.com/qodana"&gt;GET STARTED WITH QODANA&lt;/a&gt;&lt;/p&gt;

</description>
      <category>codereview</category>
      <category>php</category>
      <category>security</category>
      <category>codequality</category>
    </item>
    <item>
      <title>Qodana and IntelliJ IDEA: How a Code Quality Platform Streamlined the Localization of an IDE</title>
      <dc:creator>Valerie Kuzmina</dc:creator>
      <pubDate>Mon, 23 Jan 2023 10:33:23 +0000</pubDate>
      <link>https://forem.com/qodana/qodana-and-intellij-idea-how-a-code-quality-platform-streamlined-the-localization-of-an-ide-2l2e</link>
      <guid>https://forem.com/qodana/qodana-and-intellij-idea-how-a-code-quality-platform-streamlined-the-localization-of-an-ide-2l2e</guid>
      <description>&lt;p&gt;Have you ever wondered how to make sure that your determination to live a healthier life, not sweat the small stuff, and work smarter, not harder continues past Valentine’s Day? Psychologists say that breaking big goals into small steps is the best way to stick to your New Year’s resolutions.&lt;/p&gt;

&lt;p&gt;This advice applies to programmers’ resolutions too. If you plan a large project that involves code refactoring, you may want to see the full picture of the required changes and plan accordingly. This is exactly what the IntelliJ team did when they needed to localize the IDE’s entire UI into Chinese, Japanese, and Korean.&lt;/p&gt;

&lt;p&gt;Using Qodana, the code quality platform from JetBrains, as a single source of truth for their localization process, the IntelliJ team managed to finish the project much faster than expected. This positive outcome was a result of wise planning, accountability, and oversight. Here’s how they did it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk2iwn8m25y4wwa1tar7t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk2iwn8m25y4wwa1tar7t.png" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.jetbrains.com/qodana" rel="noopener noreferrer"&gt;TRY QODANA FOR FREE&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The challenge: isolate 13,000 hard-coded strings and monitor progress effectively
&lt;/h3&gt;

&lt;p&gt;To streamline the localization of their UI into 3 different languages, the IntelliJ team needed to strip out all localizable items from the source code and put them into separate properties files to be handed over for translation.&lt;/p&gt;

&lt;p&gt;With over 13,000 strings, it was easy for some localizable ones to be overlooked, meaning that they remained in the code. When localizing the UI, hard-coded strings can be the most difficult parts to deal with. They are hard to find because they do not show up until the software has been localized. As a result, if a user installed the Japanese language pack, for example, some parts of the UI would still be in English.&lt;/p&gt;

&lt;p&gt;The team was therefore left with much tedious and repetitive work. As a result the head of the localization project was looking for a solution that would allow them to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Automate a huge chunk of the work by continuously inspecting the code base for hard-coded string literals.&lt;/li&gt;
&lt;li&gt;Assign issues to the developers who would be responsible for fixing them.&lt;/li&gt;
&lt;li&gt;Oversee the extraction of localizable strings.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The solution: automated code inspection for hard-coded string literals
&lt;/h3&gt;

&lt;p&gt;The localization project lead chose Qodana to streamline the code inspection process, resulting in a project with the following steps:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;#1. Connect Qodana to TeamCity&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The IntelliJ team connected Qodana to their &lt;a href="https://www.jetbrains.com/help/qodana/teamcity.html" rel="noopener noreferrer"&gt;TeamCity pipeline&lt;/a&gt; and enabled the &lt;a href="https://www.jetbrains.com/help/idea/hard-coded-string-literals.html" rel="noopener noreferrer"&gt;&lt;em&gt;Internationalization&lt;/em&gt; code inspection&lt;/a&gt; to highlight hard-coded string literals that were not extracted into properties files as required.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fabttc14cz7znn30zt33b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fabttc14cz7znn30zt33b.png" width="800" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;#2. Configure the inspection profile&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the inspection profile, the team &lt;a href="https://www.jetbrains.com/help/qodana/qodana-yaml.html#Set+up+a+profile" rel="noopener noreferrer"&gt;configured the scope of the inspection&lt;/a&gt; to make sure that the platform skipped parts like legacy code, literals without alphabetic characters, and strings consisting of only whitespace.&lt;/p&gt;

&lt;p&gt;The team also made sure that TeamCity would produce a test report for each line inspected by Qodana and fail it if the string wasn’t extracted.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;#3. Decide on the frequency of scans&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once fully configured, Qodana was set to inspect the code every 4 hours. It was especially important that the scan was running independently on the server, as opposed to on someone’s local machine. This ultimately saved the team valuable time.&lt;/p&gt;

&lt;p&gt;The first Qodana run resulted in 10,000 failed tests in TeamCity.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2F5xWCo4xt5mc1D8v5e_hbZ25hqF7-dI3Lwv4NytD00ddmXqd3unw39POav523WjOCCRiLCDKQq6cOS4RfcGgSFFqQ-X_0XCPA1yxVvRD5y6Dj9Qlu6UFUxhySnPZZqx-XtfJwanN7ginGIT4Tv-fuOWBXo0lBCFFTY4wq0UPBbcFkElIQ6n3klU0O4qM-5A" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2F5xWCo4xt5mc1D8v5e_hbZ25hqF7-dI3Lwv4NytD00ddmXqd3unw39POav523WjOCCRiLCDKQq6cOS4RfcGgSFFqQ-X_0XCPA1yxVvRD5y6Dj9Qlu6UFUxhySnPZZqx-XtfJwanN7ginGIT4Tv-fuOWBXo0lBCFFTY4wq0UPBbcFkElIQ6n3klU0O4qM-5A" width="1600" height="823"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Overview of the failed tests.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FS-xGTPMyOu-zL-Ghz5Ndo8kQXVLSPvYXUYpyBIwNsfwtpRNLv2vlaN0FX-BiShb422gjiNYc0wFU3wPZcSceog4Ke7Ati8m-Jmx6_RWCbW7YAbtcEwg2dc2cem_mHfATcAo2DbLfQOz93meA9YFDmshdQKjQakys_vEHRpBLAUyHmufBBgqbJK7dkHPXnQ" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FS-xGTPMyOu-zL-Ghz5Ndo8kQXVLSPvYXUYpyBIwNsfwtpRNLv2vlaN0FX-BiShb422gjiNYc0wFU3wPZcSceog4Ke7Ati8m-Jmx6_RWCbW7YAbtcEwg2dc2cem_mHfATcAo2DbLfQOz93meA9YFDmshdQKjQakys_vEHRpBLAUyHmufBBgqbJK7dkHPXnQ" width="1600" height="752"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Qodana flags the hard-coded string literal remaining in the code as an error in the internationalized environment.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;#4. Assign tasks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For each of the test failures, the project lead assigned a developer to investigate and extract the hard-coded string to the properties file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FRx5p2vnkFYKL3FEF4IttKzGgE_tnAPbLX9CmFaP20U1wXgN57ramrBJvRrkxQiGIagRx5ETZl7ztDO05l6No7HK4i8hr_crkAdohkw-I_QXSmMLi-wwLdQXelFG2b2lfQu-d2nnI0OmdYUyDxBjfhRoEi-zulqVEoDcc1YvPgCUPtNmm5U7mCUNMYrtOjQ" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FRx5p2vnkFYKL3FEF4IttKzGgE_tnAPbLX9CmFaP20U1wXgN57ramrBJvRrkxQiGIagRx5ETZl7ztDO05l6No7HK4i8hr_crkAdohkw-I_QXSmMLi-wwLdQXelFG2b2lfQu-d2nnI0OmdYUyDxBjfhRoEi-zulqVEoDcc1YvPgCUPtNmm5U7mCUNMYrtOjQ" width="1600" height="619"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;How the assigned test is displayed in TeamCity.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;#5. Monitor the results&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After each Qodana inspection, TeamCity compared the previous results to the current report. If the developer responsible for an issue extracted the string, TeamCity marked the test as fixed. This allowed the project lead to monitor the progress without having to manually mark tests as fixed.&lt;/p&gt;

&lt;p&gt;Additionally, the team was able to monitor progress in the Qodana Cloud dashboard, which updated information on the remaining code issues in real time and compared results between different Qodana runs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff6wx2odp7i9bz2zfae94.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff6wx2odp7i9bz2zfae94.gif" width="760" height="408"&gt;&lt;/a&gt;&lt;br&gt;
_The Qodana Cloud dashboard example. _&lt;/p&gt;

&lt;p&gt;Qodana also allowed adding selected issues to the baseline, otherwise known as the technical debt section. This way, the entire team could see the same list of issues and monitor progress right in the platform. Below is an example of how this works.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb9vuz5tmmxmj1hwtywxk.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb9vuz5tmmxmj1hwtywxk.gif" width="720" height="392"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The Qodana baseline feature.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The key outcomes
&lt;/h3&gt;

&lt;p&gt;In only a few months, the number of &lt;strong&gt;failed tests dropped from 10,000 to zero&lt;/strong&gt; , an average of about &lt;strong&gt;175 fixed tests per day&lt;/strong&gt;. The team successfully removed all hard-coded string literals from the source code and the whole UI was localized seamlessly, with no unexpected elements in English.&lt;/p&gt;

&lt;p&gt;With Qodana, the IntelliJ team required fewer manual steps in the localization process, thereby reducing the number of human errors and increasing confidence in the localized builds. Additionally, with checks running every 4 hours, they were able to detect issues sooner and prevent small problems from turning into big ones later on.&lt;/p&gt;

&lt;p&gt;Finally, Qodana became the single source of truth for the team lead, making it easy to ensure that developers fixed the problems they were assigned.&lt;/p&gt;

&lt;p&gt;Thanks to these results, the IntelliJ team will keep using Qodana as a code quality and resource planning platform when they deliver new functionalities or improve IntelliJ IDEA’s performance. More on that in our upcoming posts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.jetbrains.com/qodana" rel="noopener noreferrer"&gt;GET STARTED WITH QODANA&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happy developing and keep your code clean!&lt;/p&gt;

</description>
      <category>bestpractices</category>
      <category>codereview</category>
      <category>collaboration</category>
      <category>idea</category>
    </item>
    <item>
      <title>Announcing the Preview for Qodana Cloud, a One-Stop-Shop for All Your Code Quality Insights!</title>
      <dc:creator>Viktor Tiulpin </dc:creator>
      <pubDate>Thu, 08 Dec 2022 13:20:36 +0000</pubDate>
      <link>https://forem.com/qodana/announcing-the-preview-for-qodana-cloud-a-one-stop-shop-for-all-your-code-quality-insights-8a3</link>
      <guid>https://forem.com/qodana/announcing-the-preview-for-qodana-cloud-a-one-stop-shop-for-all-your-code-quality-insights-8a3</guid>
      <description>&lt;p&gt;A public preview is now open for Qodana Cloud – a centralized cloud-based solution that collects and displays data from different Qodana linters under one roof. You can use Qodana Cloud to manage your code quality checks in a variety of contexts, ranging from one-person projects to large development teams.&lt;/p&gt;

&lt;p&gt;Qodana Cloud is still in development, and to iron out some wrinkles we are calling for the support of the community. If you want to become an early adopter of our new features, read on to learn how to get started with Qodana Cloud.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F63un3dwud5p0szs84zh8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F63un3dwud5p0szs84zh8.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://qodana.cloud/" rel="noopener noreferrer"&gt;TRY QODANA CLOUD&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How Qodana Cloud can complement your projects
&lt;/h2&gt;

&lt;p&gt;Do you want to run static analysis in multiple projects or repositories? Is your codebase distributed across several servers and virtual private networks? Do your teams work independently, and are they not always on the same page when it comes to code quality? In any of these scenarios, if you wanted to ensure that your code is clean and secure, you previously would need to switch between different linters or Qodana instances to see the results for different projects. &lt;/p&gt;

&lt;p&gt;The need to switch between linters can make the code review process convoluted and inefficient, and we’ve developed Qodana Cloud to address precisely this problem. Qodana Cloud collects all the data from different Qodana linters in a single place and allows you to drill down into particular issues with interactive dashboards. &lt;/p&gt;

&lt;p&gt;Here is how you can benefit from Qodana Cloud:&lt;/p&gt;

&lt;h3&gt;
  
  
  Get deeper insights into your projects’ trends
&lt;/h3&gt;

&lt;p&gt;With the ability to aggregate reports from different sources in one view, you can discover trends and patterns in your code across all projects and get a better understanding of how your project or the whole team is performing. This way, developers will no longer code in silos, instead seeing the same list of issues. This also makes it easier for managers to track progress for the whole organization.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fezbwaahqgfwy4jvhtqek.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fezbwaahqgfwy4jvhtqek.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can create separate organizations, teams, and projects in Qodana Cloud and assign a single team to several projects for convenient navigation. In addition, you achieve more transparency thanks to widgets updating in real time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5mheypfc266t2c7bp4a1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5mheypfc266t2c7bp4a1.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In each project, you can also see a history of previous results and compare the results of quality checks between commits. You can examine the absolute number of problems detected or compare the number of problems against a baseline – a snapshot of the codebase problems taken during a specific Qodana run.&lt;/p&gt;

&lt;h3&gt;
  
  
  Open problems detected by Qodana in your favorite IDE
&lt;/h3&gt;

&lt;p&gt;If you are already a Qodana user, you might know that you can open issues spotted by Qodana right in your IDE. And now this feature works for Qodana Cloud, too! This means you can fix server-side errors in the editor the same way you work with other suggestions given by the IDE. &lt;/p&gt;

&lt;p&gt;Here’s how it works:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnyudert69axmvh7kj0m4.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnyudert69axmvh7kj0m4.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What’s especially important about Qodana being bundled with JetBrains IDEs is that you run resource-intensive checks outside of your development environment without hurting your IDE’s performance. In the example above, Qodana spotted a chance that a variable could be null and cause a runtime exception. This is a severe issue, but users tend to switch off such inspections for the sake of saving resources.&lt;/p&gt;

&lt;p&gt;In fact, that’s one of the reasons why we at JetBrains created Qodana, to ensure that you no longer have to choose between code quality and IDE performance! &lt;/p&gt;

&lt;h3&gt;
  
  
  Plan your work better
&lt;/h3&gt;

&lt;p&gt;Split big projects into small steps! Switching to a newer version of a language or framework, or getting rid of a certain utility or pattern, can be a cumbersome task – especially if you are working on a big project involving many developers and QA engineers. &lt;/p&gt;

&lt;p&gt;In Qodana Cloud, you can build a report to evaluate all pieces of code requiring modification and select issues to add to the baseline – otherwise known as the technical debt section. This way, the whole team can see the same list of issues and monitor progress with an interactive Qodana dashboard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqazjb14rhf1pu90wcvu3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqazjb14rhf1pu90wcvu3.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Choose the dark or the light side
&lt;/h3&gt;

&lt;p&gt;In the design world, dark mode is the new black. Who are we to ignore that? To ensure you have a good experience with Qodana Cloud, we’ve provided the option to manually choose the dark or the light theme or have the UI sync automatically with your system preferences.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frc998sqg6qqmc2wzsa6u.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frc998sqg6qqmc2wzsa6u.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s coming next?
&lt;/h2&gt;

&lt;p&gt;In future releases, we will add role-based access control so that you can grant different permissions based on a user’s responsibilities. For example, perhaps your legal team only needs the ability to view reports about licenses used in a product, or your security team needs to see a list of vulnerabilities in the codebase. You will be able to create custom roles for them with permissions that are specific to their tasks. We are also working on implementing more security controls and allowing quick-fixes for certain types of issues.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fphj4pmulhw55cappvo81.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fphj4pmulhw55cappvo81.png"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;A sneak peek of what’s coming next in Qodana Cloud.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/Qodana" rel="noopener noreferrer"&gt;Follow us on Twitter&lt;/a&gt; or subscribe to the blog for updates.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to get started with Qodana Cloud
&lt;/h2&gt;

&lt;p&gt;To get started, go to &lt;a href="https://qodana.cloud/" rel="noopener noreferrer"&gt;qodana.cloud&lt;/a&gt; and log in with your JetBrains Account. Alternatively, as a non-registered user, you can explore demo projects that were already analyzed by Qodana Cloud to see it in action.&lt;/p&gt;

&lt;p&gt;To pull your inspection reports from other Qodana instances into the cloud, Qodana Cloud will generate a token for you to set into your project in your CI tool. For detailed instructions, &lt;a href="https://www.jetbrains.com/help/qodana/cloud-forward-reports.html" rel="noopener noreferrer"&gt;see our documentation&lt;/a&gt;.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Project setup
&lt;/h3&gt;

&lt;p&gt;Setting up a project in Qodana Cloud takes five simple steps: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Trigger the first run&lt;/strong&gt;. First, Qodana analyzes your project using vital checks only. It will identify the number of files and folders containing problems, the languages used, and other important info about your project. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customize your analysis&lt;/strong&gt;. Next, Qodana offers you the option to enable extra inspections that might be critical for your analysis. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Narrow the analysis down&lt;/strong&gt;. You can then exclude certain files and folders from the analysis.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create technical debt.&lt;/strong&gt; Our favorite part is the ability to add detected problems to the baseline, allowing you to get back to them when you have time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apply the inspections throughout the project.&lt;/strong&gt; To apply the selected settings to your project, download &lt;code&gt;qodana.yaml&lt;/code&gt; and &lt;code&gt;qodana.sarif.json&lt;/code&gt;, put them in the root folder, and restart Qodana.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7ht8kriykivzlu2tflve.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7ht8kriykivzlu2tflve.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s all for now! If you have any suggestions for future blog topics or if you want to learn more about how Qodana can help you and your business, post a comment here, tag us on &lt;a href="https://twitter.com/Qodana" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, or contact us at &lt;a href="mailto:qodana-support@jetbrains.com"&gt;qodana-support@jetbrains.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy developing, and keep your code clean!&lt;/p&gt;

</description>
      <category>codereview</category>
      <category>coding</category>
      <category>collaboration</category>
      <category>news</category>
    </item>
    <item>
      <title>Qodana 2022.3 EAP Is Out: Qodana for .NET and Go and 100+ New Inspections</title>
      <dc:creator>Viktor Tiulpin </dc:creator>
      <pubDate>Wed, 02 Nov 2022 11:22:28 +0000</pubDate>
      <link>https://forem.com/qodana/qodana-20223-eap-is-out-qodana-for-net-and-go-and-100-new-inspections-2on5</link>
      <guid>https://forem.com/qodana/qodana-20223-eap-is-out-qodana-for-net-and-go-and-100-new-inspections-2on5</guid>
      <description>&lt;p&gt;We’re delighted to announce the release of Qodana 2022.3 EAP. This version of the platform brings support for NET. and Go, and over 100 new inspections for cleaner code. However, please, note that Qodana 2022.2 images are more stable, as Qodana 2022.3 EAP is still in its infancy.&lt;/p&gt;

&lt;p&gt;Read on to learn more and become an early adopter of some exciting new features!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhxqu3nfp36o2gkzsng31.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhxqu3nfp36o2gkzsng31.png" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.jetbrains.com/qodana" rel="noopener noreferrer"&gt;GET STARTED WITH QODANA&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our brand new linters bring all of the smarts from &lt;a href="https://www.jetbrains.com/rider/" rel="noopener noreferrer"&gt;Rider&lt;/a&gt; and &lt;a href="https://www.jetbrains.com/go/" rel="noopener noreferrer"&gt;GoLand&lt;/a&gt; to enable you to spot anomalous code and potential bugs, eliminate dead code, improve the overall code structure, and introduce coding best practices across all of your .NET and Go projects!&lt;/p&gt;

&lt;h2&gt;
  
  
  Qodana for .NET
&lt;/h2&gt;

&lt;p&gt;Qodana supports almost all .NET inspections provided by Rider. Since there’s a long list of them, check out the &lt;a href="https://www.jetbrains.com/help/rider/Code_Analysis__Code_Inspections.html" rel="noopener noreferrer"&gt;Rider documentation&lt;/a&gt; to learn more about all of the inspections. Meanwhile, a few examples of the .NET inspections that Qodana can run are below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inconsistent lock ordering&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of the main issues when using locks to achieve thread safety is avoiding deadlocks, i.e. when threads simultaneously block each other from continuing execution, so no progress is made. With this new inspection, Qodana will highlight cycles leading to possible deadlocks at runtime.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3xhb3my8t16j5s03bakk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3xhb3my8t16j5s03bakk.png" width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Access to modified captured variable&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Qodana for .NET detects access to the captured variable from an anonymous method when the variable is modified externally.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fakl3narcjasst1w2tv3a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fakl3narcjasst1w2tv3a.png" width="800" height="257"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Avoid using ‘async’ lambda when delegate type returns ‘void’&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This inspection spots the usage of ‘async’ lambda expressions: any exceptions unhandled by the lambda will never affect the caller thread and will not be caught with the catch clause.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqw6r0y69l3i5l9t5vvwo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqw6r0y69l3i5l9t5vvwo.png" width="800" height="294"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Type check and casts can be merged&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The type-testing &lt;code&gt;is&lt;/code&gt; operator in its classical form &lt;code&gt;(Expression is Type)&lt;/code&gt; returns &lt;code&gt;true&lt;/code&gt; only when the runtime type of &lt;code&gt;Expression&lt;/code&gt; is compatible with &lt;code&gt;Type&lt;/code&gt; and the result of &lt;code&gt;Expression&lt;/code&gt; is not &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When we use &lt;code&gt;is&lt;/code&gt; to check the compatibility before casting, like in the example below, we encounter at least two problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We perform the type check twice for no reason, which can affect performance if we do it inside a loop.&lt;/li&gt;
&lt;li&gt;The fact that the program execution will not get into the &lt;code&gt;if&lt;/code&gt; statement if &lt;code&gt;obj&lt;/code&gt; is &lt;code&gt;null&lt;/code&gt; is not immediately clear to those who read this code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Qodana will spot this issue and suggest you fix it right in Rider.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjh4eloha8vrt9qlm4ofp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjh4eloha8vrt9qlm4ofp.png" width="800" height="233"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lambda expression/anonymous method should not have captures of the containing context&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The lambda expression/anonymous method passed to a parameter annotated by the ‘[RequireStaticDelegate]’ attribute must not have captures of the containing context (local variables, local functions, ‘this’ reference) to avoid heap allocations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjkicw13b4lcxwkzrwqkq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjkicw13b4lcxwkzrwqkq.png" width="800" height="305"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To configure the linter for .NET and run analysis, please refer to the &lt;a href="https://www.jetbrains.com/help/qodana/2022.3/qodana-dotnet-docker-readme.html" rel="noopener noreferrer"&gt;Qodana documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Qodana for Go
&lt;/h2&gt;

&lt;p&gt;Qodana 2022.3 is designed to support all inspections provided by GoLand. To see the exhaustive list, please refer to the &lt;a href="https://www.jetbrains.com/help/go/code-inspections-in-go.html" rel="noopener noreferrer"&gt;GoLand documentation&lt;/a&gt;. Below are examples of some of the Go inspections that Qodana now supports.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Placeholder argument ‘d.DeletedCount’ has the wrong type ‘int64’ (%s)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This inspection reports incorrect usages of &lt;code&gt;fmt.Printf&lt;/code&gt;, &lt;code&gt;fmt.Println&lt;/code&gt;, and similar formatting and printing functions.&lt;/p&gt;

&lt;p&gt;In their format strings, formatting functions use formatting verbs, like &lt;code&gt;%s&lt;/code&gt;, &lt;code&gt;%d&lt;/code&gt;, &lt;code&gt;%v&lt;/code&gt;, and others.&lt;/p&gt;

&lt;p&gt;If formatting verbs are used incorrectly, the result of a formatting function will contain an error.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7neb8vgz290a4zvr1dlx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7neb8vgz290a4zvr1dlx.png" width="800" height="255"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unhandled error&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This inspection reports calls to functions and methods that do not handle the call result of the &lt;code&gt;error&lt;/code&gt; type.&lt;/p&gt;

&lt;p&gt;An API of such functions imply that their execution might finish unsuccessfully and they would return an error. Calls that do not handle the error result could be an indication of misuse of the API.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa3pebycejzvznv9uxmxj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa3pebycejzvznv9uxmxj.png" width="800" height="216"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unused dependency&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This inspection reports unused dependencies on your project. It’s good practice to scan for unused dependencies on a regular basis, as it reduces the library size of your project and improves maintainability.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ou8d7b062wc23brvdnx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ou8d7b062wc23brvdnx.png" width="800" height="242"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To see Qodana in action and play around with these new inspections, feel free to jump into our documentation and see how to configure linters for &lt;a href="https://www.jetbrains.com/help/qodana/2022.3/qodana-go-docker-readme.html" rel="noopener noreferrer"&gt;Go&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  New inspections
&lt;/h2&gt;

&lt;p&gt;Besides adding new linters for .NET and Go, Qodana 2022.3 also brings you over 100 new inspections for the existing linters. Let’s take a look at the most prominent examples of inspections for Java, Kotlin, and Python.&lt;/p&gt;

&lt;h3&gt;
  
  
  Java and Kotlin inspections
&lt;/h3&gt;

&lt;p&gt;We’ve added over 40 new inspections to Qodana for JVM Community and Qodana for JVM.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DataFlowIssue&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This inspection reports code constructs that always violate nullability contracts, may throw exceptions, or are redundant, based on data flow analysis.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EscapedSpace&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Java 15 introduced the string escape sequence \s to make trailing whitespace in text-blocks visible. In most other contexts, especially in regular expressions, this escape sequence can easily be confused with the &lt;code&gt;\s&lt;/code&gt; of a regular expression meaning whitespace. In Java string literals it has to be written as &lt;code&gt;"\\s"&lt;/code&gt; instead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MismatchedJavadocCode&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This inspection reports cases in which the Javadoc of a method obviously contradicts the method signature, such as the comment saying “returns true” when the method returns a string.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Destructure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This inspection reports declarations in Kotlin that can be destructured.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UnresolvedRestParam&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now Qodana can detect inconsistent method declarations in REST services (such as &lt;code&gt;@PathParam&lt;/code&gt; parameters that don’t match a placeholder from the &lt;code&gt;@Get&lt;/code&gt;annotation), as these would throw exceptions at runtime. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ReactiveStreamsThrowInOperator&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This new inspection spots &lt;code&gt;throw&lt;/code&gt; statements in Reactor/RxJava operator code instead of returning designated error values, which prevents the errors from being processed further. For example, it ignores them or replaces them with a fallback value.&lt;/p&gt;

&lt;p&gt;Please, note that this version of Qodana also brings all of the new inspections for Android from IntelliJ IDEA 2022.3 and Android Studio – Electric Eel | 2022.1.1.&lt;/p&gt;

&lt;h3&gt;
  
  
  Python inspections
&lt;/h3&gt;

&lt;p&gt;We’ve also added some inspections for the Google App Engine to Qodana for Python that will highlight issues before they cause failures in production environments. For example, now you can spot:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GQL queries that  do not comply with restrictions for queries allowed on the Google App Engine server.&lt;/li&gt;
&lt;li&gt;GQL queries without indexes.&lt;/li&gt;
&lt;li&gt;Usages of Python features that are restricted by the Google App Engine sandbox.&lt;/li&gt;
&lt;li&gt;Сases when threadsafe is not enabled with the CGI handler.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To exclude certain inspections from your analysis, you can customize your default inspection profile or create a brand new one. You may also want to ​​enforce inspections that are important to your coding guidelines. Check out our &lt;a href="https://www.jetbrains.com/help/qodana/qodana-yaml.html#Include+an+inspection+into+the+analysis+scope" rel="noopener noreferrer"&gt;Qodana documentation&lt;/a&gt; for more information.&lt;/p&gt;

&lt;p&gt;That’s everything about Qodana 2022.3 EAP! We hope you enjoy this new release. If you have any suggestions for future blog topics or if you want to learn more about how Qodana can help you and your business, post a comment here, tag us on &lt;a href="https://twitter.com/Qodana" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, or contact us at &lt;em&gt;&lt;a href="mailto:qodana-support@jetbrains.com"&gt;qodana-support@jetbrains.com&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Happy developing and keep your code clean!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Your Qodana team&lt;/em&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>kotlin</category>
      <category>news</category>
      <category>releases</category>
    </item>
    <item>
      <title>Qodana 2022.2 Is Available: 50+ New Inspections and CircleCI Orb</title>
      <dc:creator>Viktor Tiulpin </dc:creator>
      <pubDate>Fri, 05 Aug 2022 15:12:57 +0000</pubDate>
      <link>https://forem.com/qodana/qodana-20222-is-available-50-new-inspections-and-circleci-orb-3i3b</link>
      <guid>https://forem.com/qodana/qodana-20222-is-available-50-new-inspections-and-circleci-orb-3i3b</guid>
      <description>&lt;p&gt;Qodana 2022.2 is now available, bringing new and improved code inspections for Java, Kotlin, Android, PHP, JS, and Python. Additionally, we’ve added &lt;a href="https://circleci.com/developer/orbs/orb/jetbrains/qodana?version=2022.2.1" rel="noopener noreferrer"&gt;CircleCI Orb&lt;/a&gt; to the Qodana integration toolset. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy0xs18yjyrv7vhuofcu1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy0xs18yjyrv7vhuofcu1.png" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.jetbrains.com/qodana" rel="noopener noreferrer"&gt;GET STARTED WITH QODANA&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  More CIs to run Qodana with
&lt;/h2&gt;

&lt;p&gt;Qodana already has plugins for &lt;a href="https://www.jetbrains.com/help/qodana/qodana-azure-pipelines.html" rel="noopener noreferrer"&gt;Azure Pipelines&lt;/a&gt;, &lt;a href="https://www.jetbrains.com/help/qodana/qodana-github-action.html" rel="noopener noreferrer"&gt;GitHub Actions&lt;/a&gt;, and &lt;a href="https://www.jetbrains.com/help/qodana/teamcity.html" rel="noopener noreferrer"&gt;TeamCity&lt;/a&gt;. Starting from 2022.2, we’ve prepared a &lt;a href="https://circleci.com/developer/orbs/orb/jetbrains/qodana" rel="noopener noreferrer"&gt;CircleCI Qodana orb&lt;/a&gt; that allows you to set up code inspections quickly and easily with your CircleCI projects.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2FD-yaEpuhrBZkxU2Kv3C9DNKH4ctdoPi3uPKbcsuxH9I5M5lPw-QrUho3h2mLdEsnJ-Na1P9TaD0ySxDtLP8vUxJyhVmOBSBrs0Q1KVQSWat_c54vEDlqRALOhPcUjChzm0mmESAFGlI4kbvGxh1NGiM" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2FD-yaEpuhrBZkxU2Kv3C9DNKH4ctdoPi3uPKbcsuxH9I5M5lPw-QrUho3h2mLdEsnJ-Na1P9TaD0ySxDtLP8vUxJyhVmOBSBrs0Q1KVQSWat_c54vEDlqRALOhPcUjChzm0mmESAFGlI4kbvGxh1NGiM" width="1600" height="1133"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, it’s easy to set up Qodana in &lt;a href="https://www.jetbrains.com/help/qodana/gitlab.html" rel="noopener noreferrer"&gt;GitLab&lt;/a&gt;, &lt;a href="https://www.jetbrains.com/help/qodana/jenkins.html" rel="noopener noreferrer"&gt;Jenkins&lt;/a&gt;, or &lt;a href="https://www.jetbrains.com/help/qodana/getting-started.html#docker-image-tab" rel="noopener noreferrer"&gt;any other CI that supports running Docker images&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  New inspections
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Regular expressions
&lt;/h3&gt;

&lt;p&gt;Regular expressions are widely known for their complexity, intricate syntax, and sometimes verbosity. To make life easier, we’ve added new inspections in this area. Previously these inspections were available only for Java, but we’ve now made them available for all languages. &lt;/p&gt;

&lt;h4&gt;
  
  
  Simplified regular expressions
&lt;/h4&gt;

&lt;p&gt;A regular expression like &lt;code&gt;[\wa-z\d]&lt;/code&gt; can be simplified to just &lt;code&gt;\w&lt;/code&gt; since &lt;code&gt;\w&lt;/code&gt; already includes &lt;code&gt;a-z&lt;/code&gt; as well as the digits.  It helps improve the code’s overall readability.&lt;/p&gt;

&lt;h4&gt;
  
  
  Suspicious backreferences
&lt;/h4&gt;

&lt;p&gt;A regular expression like &lt;code&gt;\1(abc)&lt;/code&gt; cannot match anything. This is because the &lt;code&gt;\1&lt;/code&gt; refers to the &lt;code&gt;abc&lt;/code&gt; that is not yet defined when evaluating the &lt;code&gt;\1&lt;/code&gt;. This inspection prevents simple typos in regular expressions and speeds up the editing experience. &lt;/p&gt;

&lt;h4&gt;
  
  
  Redundant &lt;code&gt;\d&lt;/code&gt;, &lt;code&gt;[:digit:]&lt;/code&gt;, or &lt;code&gt;\D&lt;/code&gt; class elements
&lt;/h4&gt;

&lt;p&gt;The regular expression &lt;code&gt;[\w+\d]&lt;/code&gt; can be written as &lt;code&gt;[\w+]&lt;/code&gt;, as the &lt;code&gt;\w&lt;/code&gt; already includes the &lt;code&gt;\d&lt;/code&gt;. It helps improve the code’s overall readability.&lt;/p&gt;

&lt;h3&gt;
  
  
  Markdown support
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Incorrectly numbered list items
&lt;/h4&gt;

&lt;p&gt;Ordered list items like &lt;code&gt;1. 2. 4.&lt;/code&gt; are marked as being inconsistently numbered. In the rendered Markdown, the list is still displayed as &lt;code&gt;1. 2. 3.&lt;/code&gt;, but the inconsistency makes editing the source code harder.&lt;/p&gt;

&lt;h3&gt;
  
  
  Java, Kotlin, and Android inspections
&lt;/h3&gt;

&lt;p&gt;We’ve added and reorganized inspections in the categories: Javadoc, DevKit, Markdown, Kotlin language, style, architectural patterns, performance, and JUnit support. Here are a couple of examples from the JUnit set.&lt;/p&gt;

&lt;h4&gt;
  
  
  JUnit: Malformed Declaration
&lt;/h4&gt;

&lt;p&gt;Reports the JUnit test member declarations that are malformed and are likely not to be recognized by the JUnit test framework. Declarations like these could result in unexecuted tests or lifecycle methods.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F19w6j6eyeuex9i6gjif2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F19w6j6eyeuex9i6gjif2.png" width="800" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fesz1k6mkvcqvplgrryck.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fesz1k6mkvcqvplgrryck.png" width="800" height="247"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  JUnit: Unconstructable TestCase
&lt;/h4&gt;

&lt;p&gt;Reports JUnit test cases that can’t be constructed because they have an invalid constructor. Test cases like these will not be picked up by the JUnit test runner and will therefore not execute.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F482qqdm61vskykhz2k9z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F482qqdm61vskykhz2k9z.png" width="800" height="248"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Those examples you can see live on &lt;a href="https://qodana.teamcity.com/buildConfiguration/Hosted_Root_Java_Build/61718?buildTab=Qodana&amp;amp;genericFilters=N4IgLg9hA2IFwG0QGEIBMCmACAkgOwGcAHDAYzAEsI8QBdAGhAIwDcMAnCsAT3iQAkKAcwAWdRqQCGYDEIjteiEABUMBMFgBm7SQFsMAd3kBrAnQC%2BQA&amp;amp;locationFilters=NoXSA&amp;amp;orderedLevels=NoIgLg9hA2IDQgM4FMBuyBOBLMBPeIAxgIZjIDmEG%2BCeADsiALpA&amp;amp;showingBaseline=GYQwNgzgpkA" rel="noopener noreferrer"&gt;our public TeamCity instance&lt;/a&gt;. Please use the Guest login to enter. Other inspections are described in &lt;a href="https://www.jetbrains.com/help/qodana/2022.2/new-in-2022-2.html" rel="noopener noreferrer"&gt;our documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  PHP inspections
&lt;/h3&gt;

&lt;p&gt;We added inspections in Probable bugs, Documentation, Style, Testing, and Laravel categories, for example:&lt;/p&gt;

&lt;h4&gt;
  
  
  Probable bug: Number ranges mismatch
&lt;/h4&gt;

&lt;p&gt;In a function that is declared with &lt;code&gt;returns int&amp;lt;0,10&amp;gt;&lt;/code&gt;, marks return statements that return a number outside this range. Similarly for fields, field constructors and function calls. &lt;/p&gt;

&lt;h4&gt;
  
  
  Documentation: Type tag without variable name
&lt;/h4&gt;

&lt;p&gt;The PHPDoc snippet &lt;code&gt;@param string&lt;/code&gt; is redundant as it doesn’t say &lt;em&gt;what&lt;/em&gt; is a string. It should be either removed or replaced with &lt;code&gt;@param string $argument&lt;/code&gt;, saying that &lt;em&gt;argument&lt;/em&gt; is a string. &lt;/p&gt;

&lt;h4&gt;
  
  
  Blade: Parse error due to unpaired parentheses in string literals
&lt;/h4&gt;

&lt;p&gt;Early detection of unpaired parentheses in string literals that are later parsed by Blade, a template engine.&lt;/p&gt;

&lt;p&gt;To include or exclude certain inspections from your analysis, you can customize your default inspection profile or create a brand new one. You may also want to ​​enforce inspections that are important to your coding guidelines or best practices. Check out our &lt;a href="https://www.jetbrains.com/help/qodana/qodana-yaml.html#Include+an+inspection+into+the+analysis+scope" rel="noopener noreferrer"&gt;Qodana documentation&lt;/a&gt; for more information. &lt;/p&gt;

&lt;p&gt;If you have any suggestions for future blog topics or if you want to learn more about how Qodana can help you and your business, post a comment here, tag us on &lt;a href="https://twitter.com/Qodana" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, or contact us at &lt;em&gt;&lt;a href="mailto:qodana-support@jetbrains.com"&gt;qodana-support@jetbrains.com&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Your Qodana team&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>python</category>
      <category>releases</category>
      <category>circleci</category>
    </item>
    <item>
      <title>Qodana 2022.1 Is Available</title>
      <dc:creator>Anastasia</dc:creator>
      <pubDate>Thu, 12 May 2022 13:06:40 +0000</pubDate>
      <link>https://forem.com/qodana/qodana-20221-is-available-4ich</link>
      <guid>https://forem.com/qodana/qodana-20221-is-available-4ich</guid>
      <description>&lt;p&gt;We are continuously adding new functionality and improving Qodana, our code quality platform. To keep you updated about what’s new, we’re starting a series of regular release blog posts with the major release of Qodana 2022.1.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;License audit&lt;/em&gt; has been an extra linter that had to be configured separately from the main linters. It now comes with Qodana out of the box. We also added a bunch of new and useful inspections for PHP and JVM linters. Read on to learn more!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Fk69G1Tv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh5.googleusercontent.com/XDUC2ReAqWMNoQNTNpRSK_LttAmoeg9yL5AdF_3DOdRjyxAbZ0YIvvJNCQUHgGzZ8flbAKVETOhtkZ3f2TuYMT2jSVtvPynCz-72y39MmlPvHo2vC5gC2syVvxiK1kyWm7roSH46rngJwaz0nw" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Fk69G1Tv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh5.googleusercontent.com/XDUC2ReAqWMNoQNTNpRSK_LttAmoeg9yL5AdF_3DOdRjyxAbZ0YIvvJNCQUHgGzZ8flbAKVETOhtkZ3f2TuYMT2jSVtvPynCz-72y39MmlPvHo2vC5gC2syVvxiK1kyWm7roSH46rngJwaz0nw" alt="" width="880" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.jetbrains.com/qodana"&gt;GET STARTED WITH QODANA&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  License audit
&lt;/h1&gt;

&lt;p&gt;Legal and compliance penalties for invalid or inappropriately used licenses in your code can be extremely costly. With Qodana, you can scan dependencies in your code repository to find their licenses and see whether there are any potential issues.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qu_ulQsT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.jetbrains.com/wp-content/uploads/2022/05/license_auditing_qodana.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qu_ulQsT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.jetbrains.com/wp-content/uploads/2022/05/license_auditing_qodana.png" alt="Qodana License Audit in action" width="880" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With this release, we’ve made it easy to bring license auditing into your project and make it a part of your CI/CD pipeline. The new &lt;em&gt;License audit&lt;/em&gt; feature is available for all linters, including Python, Java, Kotlin, PHP, and JavaScript.&lt;br&gt;&lt;br&gt;
To enable &lt;em&gt;License audit&lt;/em&gt;, add the following lines to the &lt;code&gt;qodana.yaml&lt;/code&gt; file in your project root:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;include:
  - name: CheckDependencyLicenses
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you need to ignore a specific dependency in your project, add the following lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dependencyIgnores:
- name: "dependency/name"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read &lt;a href="https://www.jetbrains.com/help/qodana/license-audit.html"&gt;our documentation&lt;/a&gt; for more information about custom configurations for &lt;em&gt;License audit&lt;/em&gt; and check out &lt;a href="https://dev.to/tiulpin/keep-your-dependency-licenses-in-check-fll-temp-slug-952480"&gt;this blog post&lt;/a&gt; to see how it can streamline working routines for developers, managers, and legal teams.&lt;/p&gt;

&lt;h1&gt;
  
  
  PHP inspections
&lt;/h1&gt;

&lt;p&gt;This version of Qodana brings all of the new inspections from PhpStorm 2022.1 and adds them to your pipeline with our PHP linters. PhpStorm comes bundled with Qodana, so when Qodana notifies you about an issue in your code, you can open it right in your IDE for further investigation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--94x_nLgM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh3.googleusercontent.com/GAkqNfy12zleqr2G1ctXqLpkeDu_TW_qNIhRe_K7NiXYtNxGAJ7lbgyar3_3zjHyGjmSh0ffn8f3zcBrrwsYO8cahSgZxXvXKopqPNVW2gITRuXp7kd0azAxeoc4q4g-ylRxa7M7SVVDR99Q6A" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--94x_nLgM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh3.googleusercontent.com/GAkqNfy12zleqr2G1ctXqLpkeDu_TW_qNIhRe_K7NiXYtNxGAJ7lbgyar3_3zjHyGjmSh0ffn8f3zcBrrwsYO8cahSgZxXvXKopqPNVW2gITRuXp7kd0azAxeoc4q4g-ylRxa7M7SVVDR99Q6A" alt="" width="880" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Duplicate array key&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The behavior of &lt;code&gt;array_merge()&lt;/code&gt; and merging with the &lt;code&gt;+&lt;/code&gt; operator are different from each other in PHP. The latter will not override the value if the key is duplicated. This can lead to confusion and bugs, so Qodana for PHP now highlights such cases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Usage of count($array) as array index&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When appending an item to an array, there is no need to explicitly specify the index. Qodana for PHP can warn you about the redundant &lt;code&gt;count()&lt;/code&gt; call.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Replace pow() call with **&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;PHP has had an &lt;code&gt;**&lt;/code&gt; exponentiation operator available since version 5.6. Qodana for PHP will suggest a quick-fix right in PhpStorm (Alt+Enter) to replace the old &lt;code&gt;pow()&lt;/code&gt; calls with the ** operator.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read-only properties&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Private properties with read-only access inside a class can be declared with the &lt;code&gt;readonly&lt;/code&gt; flag. Qodana for PHP will suggest updating the property declaration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Final class constants&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Starting with PHP 8.1, it is possible to declare constants as final. This is why Qodana for PHP will warn you about constants that are not inherited and suggest adding a &lt;code&gt;final&lt;/code&gt; modifier to them. With the PhpStorm integration, you can quickly jump to the IDE to fix the issue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;rand function arguments in reverse order&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This inspection highlights function calls from the rand family where the max argument can be less than the min. For example, calling &lt;code&gt;rand(10, 1)&lt;/code&gt; is the same as calling &lt;code&gt;rand(1, 10)&lt;/code&gt;, but &lt;code&gt;mt_rand()&lt;/code&gt; is strict about the order of its arguments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Invalid mock target with PHPUnit&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Qodana for PHP will warn you when you try to access a private or final method on a mock object.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Redundant modifier&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This new inspection will report modifiers that are used in regular expression patterns but do not affect the match:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/i&lt;/code&gt;(case insensitivity) in patterns that contain no letters.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/D&lt;/code&gt; (&lt;em&gt;PCRE_DOLLAR_ENDONLY&lt;/em&gt;) in patterns that do not contain a dollar sign or that contain the &lt;code&gt;\m&lt;/code&gt; (PCRE_MULTILINE) modifier.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/s&lt;/code&gt;(dot matches line breaks) in patterns that contain no dots.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Unsupported modifier&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This inspection will report usages of the &lt;code&gt;/e&lt;/code&gt; modifier, which is deprecated in PHP versions 7.0 and later.&lt;/p&gt;

&lt;h1&gt;
  
  
  Java and Kotlin inspections
&lt;/h1&gt;

&lt;p&gt;This release also adds new inspections from IntelliJ IDEA 2022.1 to Qodana for JVM. With our IntelliJ IDEA integration, if any issues are found, the erroneous code can be opened right in the IDE for a quick fix.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Me8s40WG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh4.googleusercontent.com/Gaawael6izJr4fT60bitnNJlRD_d-fMeBUep9opM92THL1utcWW057LLRJNM9YsYgE8sS0QBaLgvUG_JU5gFQ8p_E_MicVl1Y7wTmbbIrKEDuw-e4pbjvX8FPX7D0sglKqq7aWeyEawoWvChvQ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Me8s40WG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh4.googleusercontent.com/Gaawael6izJr4fT60bitnNJlRD_d-fMeBUep9opM92THL1utcWW057LLRJNM9YsYgE8sS0QBaLgvUG_JU5gFQ8p_E_MicVl1Y7wTmbbIrKEDuw-e4pbjvX8FPX7D0sglKqq7aWeyEawoWvChvQ" alt="" width="880" height="317"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s take a look at the most notable inspections.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Suspicious back reference&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Qodana for JVM will find references that will not be resolvable at runtime.This means that the back reference can never match anything. A back reference will not be resolvable when the group is defined after the back reference, or if the group is defined in a different branch of an alternation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;‘InputStream’ and ‘OutputStream’ can be constructed using ‘Files’ methods&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This inspection reports &lt;code&gt;FileInputStream&lt;/code&gt; and &lt;code&gt;FileOutputStream&lt;/code&gt; constructors when they can be replaced with &lt;code&gt;Files.newInputStream()&lt;/code&gt; and &lt;code&gt;Files.newOutputStream()&lt;/code&gt;, respectively. Streams created using &lt;code&gt;Files&lt;/code&gt; methods are usually more efficient than those created by stream constructors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Redundant @ScheduledForRemoval annotation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Qodana for JVM will warn you about the usage of &lt;code&gt;@ApiStatus.ScheduledForRemoval&lt;/code&gt; annotations without the &lt;code&gt;inVersion&lt;/code&gt; attribute, which targets Java 9 or a newer version of Java. It will suggest replacing such usages with the &lt;code&gt;forRemoval&lt;/code&gt; attribute in the &lt;code&gt;@Deprecated&lt;/code&gt; annotation to simplify your code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bulk ‘Files.readAttributes’ calls can be used instead of multiple file attribute calls&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This inspection finds places where multiple java.io.File attribute checks, such as &lt;code&gt;isDirectory&lt;/code&gt;, &lt;code&gt;isFile&lt;/code&gt;, &lt;code&gt;lastModified&lt;/code&gt;, or &lt;code&gt;length&lt;/code&gt;, are used in a row. These calls can be replaced with a bulk &lt;code&gt;Files.readAttributes&lt;/code&gt; call. The bulk method is usually more performant than multiple attribute checks.     &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Loop can be replaced with ‘List.replaceAll()’&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This inspection reports loops that can be collapsed into a single &lt;code&gt;List.replaceAll()&lt;/code&gt; call.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Number of placeholders does not match the number of arguments in logging call&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Qodana for JVM will report &lt;code&gt;SLF4J&lt;/code&gt; or &lt;code&gt;Log4j 2&lt;/code&gt; logging calls, such as &lt;code&gt;logger.info(\"{}: {}\", key)&lt;/code&gt;, where the number of &lt;code&gt;{}&lt;/code&gt; placeholders in the logger message doesn’t match the number of other arguments in the logging call.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Regular expressions can be simplified&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This inspection detects regular expressions that can be simplified.   &lt;/p&gt;

&lt;p&gt;To exclude certain inspections from your analysis, you can customize your default inspection profile or create a brand new one. You may also want to ​​enforce inspections that are important to your coding guidelines or best practices. Check out our &lt;a href="https://www.jetbrains.com/help/qodana/qodana-yaml.html#Include+an+inspection+into+the+analysis+scope"&gt;Qodana documentation&lt;/a&gt; for more information.&lt;/p&gt;

&lt;p&gt;That’s all that is new in Qodana 2022.1! We hope you’ll find our release blog posts useful. If you have any suggestions for future blog topics or if you want to learn more about how Qodana can help you and your business, post a comment here, tag us on &lt;a href="https://twitter.com/Qodana"&gt;Twitter&lt;/a&gt;, or contact us at &lt;em&gt;&lt;a href="mailto:qodana-support@jetbrains.com"&gt;qodana-support@jetbrains.com&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Your Qodana team&lt;/em&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>kotlin</category>
      <category>php</category>
      <category>releases</category>
    </item>
    <item>
      <title>Why Do Testers Need CI/CD?</title>
      <dc:creator>Alexandra Psheborovskaya</dc:creator>
      <pubDate>Thu, 14 Apr 2022 09:04:46 +0000</pubDate>
      <link>https://forem.com/qodana/why-do-testers-need-cicd-2lo8</link>
      <guid>https://forem.com/qodana/why-do-testers-need-cicd-2lo8</guid>
      <description>&lt;p&gt;Competency in the TestOps field is now just as much of a basic requirement for QA engineers as the ability to write automated tests. This is because of the ongoing development of CI/CD and the increasing number of QA engineers who work with pipelines (or the sequence of stages in CI/CD) and implement their own. So why is CI/CD such a great tool for quality control? Let’s find out.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---u2VLduh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh5.googleusercontent.com/OtG44KqsW2bqQvcGbjAXFzjAwUX-H4LnhzqNKFp8Ey-KZQBughAsV8OeVQmqUOaVXa238O9AMbWk4zmn25XzGwca78GKRodkn5sJOc9Al1c_3qan7_CP1r7DHblnvptfZ4Eyfrwl" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---u2VLduh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh5.googleusercontent.com/OtG44KqsW2bqQvcGbjAXFzjAwUX-H4LnhzqNKFp8Ey-KZQBughAsV8OeVQmqUOaVXa238O9AMbWk4zmn25XzGwca78GKRodkn5sJOc9Al1c_3qan7_CP1r7DHblnvptfZ4Eyfrwl" alt="" width="880" height="787"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Running tests automatically
&lt;/h2&gt;

&lt;p&gt;Automated tests haven’t been run locally in what feels like ages. These days, CI/CD pipelines run tests automatically as one of their main functions.&lt;/p&gt;

&lt;p&gt;Pipeline configuration can be assigned to DevOps. But then we will be a long way from making use of CI/CD’s second function: quality control, or more precisely, “quality gates”.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quality control using quality gates
&lt;/h2&gt;

&lt;p&gt;But what are quality gates? Let’s say the product code is like a castle. Every day, developers write new code – which could weaken the foundations of our castle or even poke holes in it, if we are really unlucky. The purpose of a QA engineer is to test each feature and reduce the likelihood of bugs finding their way into product code. Lack of automation in the QA process could cause QA engineers to lose sleep, since there is nobody to watch over all the various metrics – especially at dangerous times, like Friday evenings when everyone wants to leave work and is hurrying to get everything finished. An ill-fated merge at that moment can cause a lot of problems down the road.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This problem can be solved by building in quality checks.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Each check deals with a different important metric. If the code doesn’t pass a check, the gates close and the feature is not allowed to enter. A feature will only be merged into the product when it passes all the checks and potential bugs have been prevented.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ly5iewDp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh3.googleusercontent.com/xvVYg4Iv5QvdnY9m0t1jFHbQQBCCuqkcgHjkogmQihNIy9Bmf5xnk1cDKjJGJke0FpMJcVoyzSjkQyJh2giCPo9GErs68FgXWU2186k16L-xxou5LGhFm4H0mN4QNhqKe_x7KB2D" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ly5iewDp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh3.googleusercontent.com/xvVYg4Iv5QvdnY9m0t1jFHbQQBCCuqkcgHjkogmQihNIy9Bmf5xnk1cDKjJGJke0FpMJcVoyzSjkQyJh2giCPo9GErs68FgXWU2186k16L-xxou5LGhFm4H0mN4QNhqKe_x7KB2D" alt="" width="880" height="832"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What quality checks can be included in CI/CD?
&lt;/h3&gt;

&lt;p&gt;We need to put together a list of checks to ensure that the process is as automated as possible. They can be sequenced in “fail first” order. A feature needs to pass all the checks to get through the pipeline successfully. The initial checks are the ones that make sure the app is capable of working: build, code style check, and static analysis. &lt;/p&gt;

&lt;p&gt;“Build” speaks for itself: if the app cannot be built, the feature does not progress. It is important to incorporate a code style check into your CI/CD pipeline to ensure the code meets unified requirements, as doing so allows you to avoid wasting time on this kind of bug during code reviews.&lt;/p&gt;

&lt;p&gt;Static analysis is an extremely important tool for judging code quality. It can point out a huge number of critical errors that lead to bugs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9q7olEyN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh6.googleusercontent.com/JOj7Yn_ie9RqZWOePgNEhL6Vb-24W6J92TcRTOV4WfTJ_uop5FtG8SHS2zHQ75ZZjy6D1eljT1YpXklbUVIKKL83vVW6MaQOaZyNcGJtXRqZAKX8eXUWvFoMDY3fPLJK8fsXzOh0" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9q7olEyN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh6.googleusercontent.com/JOj7Yn_ie9RqZWOePgNEhL6Vb-24W6J92TcRTOV4WfTJ_uop5FtG8SHS2zHQ75ZZjy6D1eljT1YpXklbUVIKKL83vVW6MaQOaZyNcGJtXRqZAKX8eXUWvFoMDY3fPLJK8fsXzOh0" alt="" width="880" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We then continue with stage-two checks: unit tests with coverage analysis and coverage quality control, as well as integration and systems tests. Next, we review detailed reports of the results to make sure nothing was missed. At this stage we may also perform a range of non-functional tests to check performance, convenience, and security, as well as screenshot tests. &lt;/p&gt;

&lt;p&gt;When developing a pipeline, we need to pay attention to two competing requirements: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The pipeline must guarantee the best possible feature quality in light of your needs.&lt;/li&gt;
&lt;li&gt;Time spent running the pipeline should not slow down your workflow. It should generally take no more than 20 minutes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Examples of tools to incorporate in quality checks
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Code style highlighting&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A code style is a set of rules that should be followed in every line of code in a project, from alignment rules to rules like “never use global variables”.  &lt;/p&gt;

&lt;p&gt;You might be wondering what style has to do with testers. The answer is a lot, actually. A style check provides several benefits for QA experts, not to mention the rest of the team:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A unified style helps developers work with the code and gives them more time to implement new features and fix bugs.&lt;/li&gt;
&lt;li&gt;A unified style allows you to dispense with manual code checks and use a CI/CD tool to run the checks instead. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Large companies usually have their own style guides that can be used as examples. For instance, Airbnb has a &lt;a href="https://github.com/airbnb/javascript"&gt;JavaScript style guide&lt;/a&gt; and Google has &lt;a href="https://google.github.io/styleguide/"&gt;a number of guides&lt;/a&gt;. You can even write your own.&lt;/p&gt;

&lt;p&gt;The choice of tools for code checking depends on the language. You can find a suitable tool on &lt;a href="https://github.com/collections/clean-code-linters"&gt;GitHub&lt;/a&gt; or find out which tools other teams are using. Linters use bodies of rules and highlight code that fails to abide by them. Some examples include &lt;a href="https://github.com/pinterest/ktlint"&gt;ktlint&lt;/a&gt; for Kotlin, &lt;a href="https://github.com/checkstyle/checkstyle"&gt;checkstyle&lt;/a&gt; for Java, &lt;a href="https://github.com/eslint/eslint"&gt;eslint&lt;/a&gt; for JavaScript.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Static code analysis&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Static code analysis is a method of debugging by examining source code without executing a program. There are many different static code analyzers on the market. We’ll take a look now at a platform we’re developing ourselves – &lt;a href="https://www.jetbrains.com/qodana"&gt;Qodana&lt;/a&gt;. The major advantage of this code analyzer is that it includes a number of inspections that are available to us in JetBrains development environments when we’re writing code.&lt;/p&gt;

&lt;p&gt;Many of you probably use an IDE-driven approach, where the IDE helps you write code and points out various bugs such as suboptimal code usage, NullPointerExceptions, duplicates, and so on.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--smDytY-U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh5.googleusercontent.com/l2spCDgt3blzH9VthoB_x9Ggu2LPZeoFb1xXu2qCWtxiJmRyvFlz3kroFxXMt56ZG5xxavyJHvqbrsStGSiuNyN32d-28i2heLtb8sXVYMHcFwBVXHxBXtIlsQ68EgrQyJIQEO-nXXz_Es4_yQQ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--smDytY-U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh5.googleusercontent.com/l2spCDgt3blzH9VthoB_x9Ggu2LPZeoFb1xXu2qCWtxiJmRyvFlz3kroFxXMt56ZG5xxavyJHvqbrsStGSiuNyN32d-28i2heLtb8sXVYMHcFwBVXHxBXtIlsQ68EgrQyJIQEO-nXXz_Es4_yQQ" alt="" width="880" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But unfortunately, you can never be sure all the critical problems found by the IDE were fixed before the commit. One way you can guarantee that all the problems will be addressed is by &lt;strong&gt;incorporating Qodana into your CI/CD pipeline&lt;/strong&gt;. If you can’t fix everything at once, you can select critical problems, add them to the baseline, and gradually work your way through the technical debt. This allows you to avoid slowing down the development process while keeping the problems that have been found under control.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test coverage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Code coverage is a metric that helps you understand how well your code has been covered by your tests (generally unit tests).  &lt;/p&gt;

&lt;p&gt;Here you need to define the minimum coverage percentage that you want to support. The code won’t be able to go live until it has been covered sufficiently by the tests. The minimum percentage is established empirically, but you should remember that even 100% coverage may not completely save your code from bugs. According to &lt;a href="https://www.atlassian.com/continuous-delivery/software-testing/code-coverage"&gt;this article&lt;/a&gt; from Atlassian, 80% is a good figure to aim for.  &lt;/p&gt;

&lt;p&gt;Different coverage analyzers are available for different languages, such as &lt;a href="https://github.com/jacoco/jacoco"&gt;Jacoco&lt;/a&gt; for Java, &lt;a href="https://github.com/istanbuljs"&gt;Istanbul&lt;/a&gt; for JavaScript, or &lt;a href="https://github.com/nedbat/coveragepy"&gt;Coverage.py&lt;/a&gt; for Python. You can build all these analyzers into your CI/CD pipeline and track the metrics with ease.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shaping the release process
&lt;/h2&gt;

&lt;p&gt;In addition to automatically running tests and ensuring particular code quality requirements are satisfied, CI/CD lets testers organize the release process.&lt;/p&gt;

&lt;p&gt;The release process can be complex and can depend on a lot of different manual actions. It is often a completely manual process: the artifact is created by a developer, then passed to the testers for checks, and finally comes to the person who knows how to roll it out for the go-live. Once again, there are a lot of potential choke points here. For instance, one of those people could fall ill or go on vacation. &lt;/p&gt;

&lt;p&gt;An effective release process will look different for each team, but it will generally include the following steps: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Each change in the Git branch triggers a build of the app.&lt;/li&gt;
&lt;li&gt;The build undergoes quality checks and does not become part of the main branch until it passes all the checks successfully.&lt;/li&gt;
&lt;li&gt;A release candidate is taken from the release branch or the main branch: this fixes the version and guarantees that nothing will go live unless it has been tested and has not been changed afterwards. This helps with tracking releases and all the changes they include. In addition, by storing artifacts of the stable version, you make it possible to revert to them quickly in the event of an unsuccessful release.&lt;/li&gt;
&lt;li&gt;The release candidate is tested and undergoes final checks.&lt;/li&gt;
&lt;li&gt;The release candidate goes live. This may be either a manual pipeline launch or an automated launch, if the release candidate passed all the checks at the preceding stage. The choice between an automatic release process and a manual one will depend on how frequent and how important the releases are, as well as the preferences among team members and the convenience of the rollout.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Any CI/CD system allows you to set up this kind of process. The process should be convenient for the whole team, including the testing team.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Given the factors outlined above, we believe following these basic rules will help ensure an easy and efficient release process:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Artifacts must be ready for download and testing, ideally all in one place.&lt;/li&gt;
&lt;li&gt;As many checks and tests as possible must be automated. They should take place without human intervention.&lt;/li&gt;
&lt;li&gt;All complex operations with builds should be as automated as possible.&lt;/li&gt;
&lt;li&gt;All builds that will go live should be recorded and remain available for a certain period after release. This will help if you need to investigate errors in the production version, reproduce bugs, or just track the history.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We would also like to remind you that if quality metrics are not controlled automatically and do not affect anything, they are useless, as there’s no way to guarantee that these metrics will be adhered to. &lt;/p&gt;

&lt;p&gt;Implement pipelines, automate processes, and use static code analysis!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Your Qodana team&lt;/em&gt;&lt;/p&gt;

</description>
      <category>codereview</category>
      <category>news</category>
      <category>ci</category>
      <category>cicd</category>
    </item>
    <item>
      <title>Introducing Qodana for Azure Pipelines</title>
      <dc:creator>Anastasia</dc:creator>
      <pubDate>Thu, 07 Apr 2022 11:26:11 +0000</pubDate>
      <link>https://forem.com/qodana/introducing-qodana-for-azure-pipelines-3l7k</link>
      <guid>https://forem.com/qodana/introducing-qodana-for-azure-pipelines-3l7k</guid>
      <description>&lt;p&gt;With Qodana, you can detect, analyze, and resolve code issues right in the CI/CD system you rely on. Since Qodana was released, we’ve supported &lt;a href="https://www.jetbrains.com/help/qodana/github-actions.html"&gt;GitHub Actions&lt;/a&gt;, &lt;a href="https://www.jetbrains.com/help/qodana/qodana-github-application.html"&gt;GitHub App&lt;/a&gt;, &lt;a href="https://www.jetbrains.com/help/qodana/gitlab.html"&gt;GitLab CI/CD&lt;/a&gt;, &lt;a href="https://www.jetbrains.com/help/qodana/qodana-teamcity-plugin.html"&gt;TeamCity&lt;/a&gt;, and &lt;a href="https://www.jetbrains.com/help/qodana/jenkins.html"&gt;Jenkins&lt;/a&gt;. We continue to expand our integrated environments to make sure we bring code quality into your favorite CI/CD. This time around, we’re introducing a new extension for &lt;a href="https://marketplace.visualstudio.com/items?itemName=JetBrains.qodana"&gt;Azure Pipelines&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SpnTTTQB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.jetbrains.com/wp-content/uploads/2022/04/featured_image.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SpnTTTQB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.jetbrains.com/wp-content/uploads/2022/04/featured_image.png" alt="" width="880" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=JetBrains.qodana"&gt;Try for free&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Qodana linters are now integrated into your Azure DevOps repositories to allow you to make code analysis a part of your build pipeline and ensure the maintainability and reliability of your projects. You can integrate Qodana with Azure Pipelines in just 2 steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install Qodana for Azure Pipelines&lt;/li&gt;
&lt;li&gt;Configure Qodana to analyze your code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now let’s dive into the details.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Qodana for Azure Pipelines
&lt;/h2&gt;

&lt;p&gt;From Visual Studio Marketplace, install the &lt;a href="https://marketplace.visualstudio.com/items?itemName=JetBrains.qodana"&gt;Qodana for Azure Pipelines&lt;/a&gt; extension by clicking the &lt;em&gt;Get it free&lt;/em&gt; button, and &lt;em&gt;Proceed to organization&lt;/em&gt; once the installation has finished.&lt;/p&gt;

&lt;p&gt;If you do not have the required permissions to install an extension from the marketplace, a request will be sent to the account administrator to ask them to approve the installation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure Qodana to analyze your code
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Set up a pipeline that integrates with Qodana
&lt;/h3&gt;

&lt;p&gt;Before analyzing your code, you will first need to set up a new build pipeline that integrates with Qodana. On the Azure DevOps panel, go to &lt;em&gt;Pipelines&lt;/em&gt; and click &lt;em&gt;Create Pipeline&lt;/em&gt;. If any pipelines have already been created, select &lt;em&gt;New pipeline&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WfBZ-t2Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.jetbrains.com/wp-content/uploads/2022/04/screen1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WfBZ-t2Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.jetbrains.com/wp-content/uploads/2022/04/screen1.png" alt="" width="880" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can configure the pipeline with either the YAML editor or the classic editor. When using the classic editor, you can take advantage of the predefined templates. The YAML editor requires you to use a YAML file. Let’s choose the latter for this example.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---QQbkfRW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.jetbrains.com/wp-content/uploads/2022/04/screen2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---QQbkfRW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.jetbrains.com/wp-content/uploads/2022/04/screen2.png" alt="" width="880" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The YAML editor will open with the template YAML file. In order to configure it correctly you will need to configure the &lt;a href="https://github.com/JetBrains/Qodana/blob/2021.3/topics/qodana-azure-pipelines.md"&gt;&lt;em&gt;Qodana Scan&lt;/em&gt;&lt;/a&gt; task by editing your azure-pipelines.yml file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml

trigger:
  - main

pool:
  vmImage: ubuntu-latest

steps:
  - task: Cache@2 # Not required, but Qodana will open projects with cache faster.
    inputs:
      key: '"$(Build.Repository.Name)" | "$(Build.SourceBranchName)" | "$(Build.SourceVersion)"'
      path: '$(Agent.TempDirectory)/qodana/cache'
      restoreKeys: |
        "$(Build.Repository.Name)" | "$(Build.SourceBranchName)"
        "$(Build.Repository.Name)"
  - task: QodanaScan@1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also find the &lt;em&gt;Qodana Scan&lt;/em&gt; task in the list of tasks on the &lt;em&gt;Show assistant&lt;/em&gt; panel.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vpCUyYXl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.jetbrains.com/wp-content/uploads/2022/04/screen3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vpCUyYXl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.jetbrains.com/wp-content/uploads/2022/04/screen3.png" alt="" width="880" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ​​Run your pipeline
&lt;/h3&gt;

&lt;p&gt;When you are done making the changes to the file, click &lt;em&gt;Save and Run&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LkXvvwzZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.jetbrains.com/wp-content/uploads/2022/04/screen4-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LkXvvwzZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.jetbrains.com/wp-content/uploads/2022/04/screen4-1.png" alt="" width="880" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  See the results
&lt;/h3&gt;

&lt;p&gt;To display the Qodana report summary in Azure DevOps, install &lt;a href="https://marketplace.visualstudio.com/items?itemName=sariftools.scans"&gt;Microsoft DevLabs’ SARIF SAST Scans Tab&lt;/a&gt; extension. Once installation is done, go to the &lt;em&gt;Pipelines&lt;/em&gt; tab, select the pipeline being run and analyzed, and look at the &lt;em&gt;Scans&lt;/em&gt; tab for more information about the quality of your code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WTimUMxc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.jetbrains.com/wp-content/uploads/2022/04/screen5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WTimUMxc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.jetbrains.com/wp-content/uploads/2022/04/screen5.png" alt="" width="880" height="485"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the Qodana for Azure Pipelines extension, you will be able to easily integrate Qodana into your Azure DevOps pipeline and start seeing the analytics the first time your code is checked.&lt;/p&gt;

&lt;p&gt;If you have any questions or suggestions about Qodana, post a comment here, tag us on &lt;a href="https://twitter.com/Qodana"&gt;Twitter&lt;/a&gt; or contact us at &lt;a href="mailto:qodana-support@jetbrains.com"&gt;qodana-support@jetbrains.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Your Qodana team&lt;/em&gt;&lt;/p&gt;

</description>
      <category>news</category>
      <category>plugins</category>
      <category>azure</category>
      <category>azuredevops</category>
    </item>
    <item>
      <title>Cut Time on Code Reviews and Project Planning With Static Analysis</title>
      <dc:creator>Kate</dc:creator>
      <pubDate>Thu, 27 Jan 2022 11:00:07 +0000</pubDate>
      <link>https://forem.com/qodana/cut-time-on-code-reviews-and-project-planning-with-static-analysis-2lao</link>
      <guid>https://forem.com/qodana/cut-time-on-code-reviews-and-project-planning-with-static-analysis-2lao</guid>
      <description>&lt;p&gt;When you’re tired of endless code reviews and debugging, you may start wondering if there are ways to automate tedious tasks without it backfiring on you later in development. If this is something you or your team are interested in, you may want to take a closer look at server-side static analysis. How will you benefit from adding yet another step in the project lifecycle, especially in the age of smart IDEs? What kinds of tasks can you delegate to a static analysis tool? Read this blog post to find the answers to these questions and more!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NhSh5iBA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.jetbrains.com/wp-content/uploads/2022/01/DSGN-13163-Static-analysis-with-Qodana-banners_featured.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NhSh5iBA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.jetbrains.com/wp-content/uploads/2022/01/DSGN-13163-Static-analysis-with-Qodana-banners_featured.png" alt="" width="880" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automate code reviews&lt;/li&gt;
&lt;li&gt;Stay confident with external contributions&lt;/li&gt;
&lt;li&gt;Slash time spent on project planning&lt;/li&gt;
&lt;li&gt;Static analysis with Qodana in your project lifecycle&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Automate code reviews
&lt;/h2&gt;

&lt;p&gt;According to the &lt;a href="https://www.activestate.com/resources/white-papers/developer-survey-2019-open-source-runtime-pains/"&gt;Active State Developer Survey 2019&lt;/a&gt;, 61.5% of developers spend four hours or less a day writing code. One of the tasks contributing to the non-coding time is code reviews. The main goal of this process is a direct discovery of quality problems. In many projects, quality means:&lt;/p&gt;

&lt;p&gt;1) flawless business logic implementation;&lt;/p&gt;

&lt;p&gt;2) elements related to the maintainability of the code: design pattern, naming strategies, code style, etc.&lt;/p&gt;

&lt;p&gt;If the process is purely manual, the reviewer should care about both aspects. It can be error-prone and time-consuming. For example, try to spot a deficiency in the code related to the regular expression:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cowWIjTu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.jetbrains.com/wp-content/uploads/2022/01/Screenshot-2022-01-27-at-11.36.18.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cowWIjTu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.jetbrains.com/wp-content/uploads/2022/01/Screenshot-2022-01-27-at-11.36.18.png" alt="" width="880" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It couldn’t be easy for you, but it’s a trivial task for a static analysis tool. It’s just one example. You can automate many checks for unused imports, dead code, duplicates, spelling problems, formatting issues, and many more – any rules of your choice. For example, if you use &lt;a href="https://www.jetbrains.com/help/idea/using-todo.html"&gt;TODO’s&lt;/a&gt; in the comment, you can automatically check that each of them contains a reference to the issue tracker, as some teams in JetBrains do.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ysKVpa1T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh4.googleusercontent.com/KS3xw4y_qhC9KYzPZMpSPfUnQ_9WLXeBEKAWJCmVcB3KdbtTHK98BWh3gYxRsRVfmFAb3NH0rGvHTXdbDl-4FHc2jfY3zZL_lzM-45r-Qy38gjU0QTm1McGV_asmCse4bX3Kl-TD" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ysKVpa1T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh4.googleusercontent.com/KS3xw4y_qhC9KYzPZMpSPfUnQ_9WLXeBEKAWJCmVcB3KdbtTHK98BWh3gYxRsRVfmFAb3NH0rGvHTXdbDl-4FHc2jfY3zZL_lzM-45r-Qy38gjU0QTm1McGV_asmCse4bX3Kl-TD" alt="" width="880" height="271"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Those checks configured in the editor guide developers, but this guidance becomes a mandatory rule with the server-side static analysis. The server-side quality gate will ensure the code meets specific standards before it moves onto the next phase, like manual code review or deployment to production. The author and the reviewer will spend less time in the feedback loop. Also, you will have a track record for proofs and further analysis.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--McLhRxe6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh4.googleusercontent.com/BgPBLYRSTvfufMdAehsc0gkPfYxovFsgBo2jttBtwAFCTh-3TUOw9OoiHcyPhtS30pEeq3vxRINAzDT8cDMMsG2F7cPXpCii-BL2mqrZZHxw-5PqQYxWT-L_9hxPOwABw5tykqll" alt="" width="880" height="449"&gt;
&lt;/h3&gt;

&lt;h2&gt;
  
  
  Stay confident with external contributions
&lt;/h2&gt;

&lt;p&gt;Code reviewing is good practice, even if all team members are equally skilled, accurate, and have a shared understanding of the code quality. Even professional climbers need belays, don’t they? And a belay becomes vital if you don’t know the actual skill level of the contributor. Accepting an external contribution to your project is precisely the case when you need an additional guarantee that the contributor follows your guidelines. It can be a pull request to the open-source project or tasks you delegate to the subcontractor – the automatic code review will perform routine checks so you can focus on business value.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vxpXZqmj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh5.googleusercontent.com/tY_fxqQCXlt0hRLgsS1sDDjFMcIAhW90ujP9YwVo6m7qXKXQgQV5mgAp3pb6FMMo0gCaDCBrVseAGEIWdFyuX1YtobTJYNgqdOAKTW6hSGlonaOQDBUnU-zIjh8YE41S4r2kxnKw" alt="" width="880" height="384"&gt;
&lt;/h3&gt;

&lt;h2&gt;
  
  
  Slash time spent on project planning
&lt;/h2&gt;

&lt;p&gt;With server-side static analysis, you can review the created code and plan your code evolution steps. Imagine you want to switch to a newer version of the language or framework. If you’re lucky, you update your dependencies, and your project is up and running. In a less fortunate scenario, you update your dependency, and the IDE highlights tons of places you need to update. &lt;/p&gt;

&lt;p&gt;For big projects, the number of changes could be so large that you will need several people to succeed. How will you split the work between them? Static analysis platforms can build a report to split the work between people and estimate the outcome. This goes for any refactoring you need for your code. For example, with checks based on &lt;a href="https://www.jetbrains.com/help/idea/structural-search-and-replace.html"&gt;structural searches&lt;/a&gt;, you can evaluate all places that require your attention. Technically, this analysis can be done on the developer’s machine, but there will be no option to share the list of issues and track the progress with others.&lt;/p&gt;

&lt;h2&gt;
  
  
  Static analysis with Qodana in your project lifecycle
&lt;/h2&gt;

&lt;p&gt;Qodana, the code quality platform from JetBrains, empowers you and your team to leverage the benefits of a static analysis tool while integrating with your favorite CI/CD pipelines – TeamCity, GitLab, GitHub, and others. The picture below illustrates a typical software build process employed during the software development life cycle and how Qodana can be integrated with this process.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KfCfSwiV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.jetbrains.com/wp-content/uploads/2022/01/qodana_scheme.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KfCfSwiV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.jetbrains.com/wp-content/uploads/2022/01/qodana_scheme.png" alt="" width="720" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To get started with Qodana, check our &lt;a href="https://dev.to/qodana/better-late-than-never-or-new-years-resolutions-with-qodana-i4h"&gt;previous blog post&lt;/a&gt; for detailed instructions, or download the version of the components that are suitable for your technology stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.jetbrains.com/qodana/jvm/"&gt;Qodana for JVM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.jetbrains.com/help/qodana/qodana-js.html"&gt;Qodana for JS&lt;/a&gt; (EAP)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.jetbrains.com/help/qodana/qodana-php.html"&gt;Qodana for PHP&lt;/a&gt; (EAP)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.jetbrains.com/help/qodana/qodana-python.html"&gt;Qodana for Python&lt;/a&gt; (EAP)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Visit &lt;a href="https://www.jetbrains.com/qodana/"&gt;jetbrains.com/qodana&lt;/a&gt; for more information. We would be grateful for any feedback you might have, and all ideas are welcome! Contact us at &lt;a href="mailto:qodana-support@jetbrains.com"&gt;qodana-support@jetbrains.com&lt;/a&gt; or via our &lt;a href="https://youtrack.jetbrains.com/issues/QD"&gt;issue tracker&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Your Qodana team&lt;/em&gt;&lt;/p&gt;

</description>
      <category>codereview</category>
      <category>news</category>
      <category>qodana</category>
    </item>
    <item>
      <title>Better Late Than Never, or New Year’s Resolutions with Qodana</title>
      <dc:creator>Viktor Tiulpin </dc:creator>
      <pubDate>Tue, 28 Dec 2021 12:00:00 +0000</pubDate>
      <link>https://forem.com/qodana/better-late-than-never-or-new-years-resolutions-with-qodana-i4h</link>
      <guid>https://forem.com/qodana/better-late-than-never-or-new-years-resolutions-with-qodana-i4h</guid>
      <description>&lt;p&gt;Even before we started to work on &lt;a href="https://jetbrains.com/qodana" rel="noopener noreferrer"&gt;Qodana&lt;/a&gt;, we knew from our own experience and user interviews that it’s hard to add static analysis to a project, which leads people to postpone this decision. &lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1475799581434781699-996" src="https://platform.twitter.com/embed/Tweet.html?id=1475799581434781699"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1475799581434781699-996');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1475799581434781699&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;If you join a project with established code quality procedures, you can just follow the rules. If you start a shiny new project, you can pick any set of rules you want. This option has its pitfalls, but at least you know that your code meets your own standards from the beginning.&lt;/p&gt;

&lt;p&gt;In contrast, if you join or work for a project where quality gates are not yet part of the process, being pressured to implement them could be a heartbreaking experience! We’ve felt it ourselves, and heard from many users who opened up in interviews: implementing the appropriate gateways can be a bumpy road.&lt;/p&gt;

&lt;p&gt;Most people we talked to encountered issues with the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Figuring out what kind of rules to apply&lt;/li&gt;
&lt;li&gt;Determining what to do with the existing issues&lt;/li&gt;
&lt;li&gt;Identifying how to make all of this sustainable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our goal with Qodana has always been to provide a pleasant experience for those who decide to have quality gates, and we’ve developed two new features to further this goal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Project setup wizard, which lets you tailor your analysis configuration further based on the initial results.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.jetbrains.com/help/qodana/qodana-baseline.html" rel="noopener noreferrer"&gt;Technical debt (or baseline)&lt;/a&gt;, which lets you mark a given state of the project as initial and track further changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you have been thinking about using quality gates for your project but haven’t known where to start, this post is right for you. You don’t need to wait until the first week of January to adopt your New Year’s resolution: you can get started now, and make your life in the new year easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with a local run and create a baseline
&lt;/h2&gt;

&lt;p&gt;Let’s start with your local machine. If you use a JetBrains IDE and are familiar with code &lt;a href="https://www.jetbrains.com/help/idea/customizing-profiles.html" rel="noopener noreferrer"&gt;inspection profiles&lt;/a&gt;, you can &lt;a href="https://www.jetbrains.com/help/qodana/qodana-yaml.html#Set+up+a+profile" rel="noopener noreferrer"&gt;re-use them in your Qodana run&lt;/a&gt;. If you are unsure of what server-side analysis fits your project best, you can start with Qodana’s default options. We introduced &lt;a href="https://www.jetbrains.com/help/qodana/qodana-yaml.html#three-phase-analysis" rel="noopener noreferrer"&gt;three-phase analysis&lt;/a&gt; precisely for this case.&lt;/p&gt;

&lt;p&gt;Follow these steps to run Qodana on your project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pick the proper &lt;a href="https://www.jetbrains.com/help/qodana/linters.html" rel="noopener noreferrer"&gt;Qodana linter for your project’s technology&lt;/a&gt; stack and pull its image:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker pull jetbrains/qodana-&amp;lt;linter&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Options include &lt;code&gt;qodana-jvm&lt;/code&gt;, &lt;code&gt;qodana-jvm-android&lt;/code&gt;, &lt;code&gt;qodana-php&lt;/code&gt;, and so on.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Perform the first run:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:8080 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; &amp;lt;project-root-directory&amp;gt;/:/data/project/ &lt;span class="se"&gt;\&lt;/span&gt;
  jetbrains/qodana-&amp;lt;linter&amp;gt; &lt;span class="nt"&gt;--show-report&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your project’s working folder likely has all the required dependencies in place, so you don’t need to perform any additional steps for the analysis to succeed. In cases when you’ve just cloned the repository and haven’t previously worked in the editor on this machine, depending on the project technology, either Qodana will do everything on its own or you will need to take one extra step to download project dependencies. For more details about this step, please check out the corresponding section in &lt;a href="https://www.jetbrains.com/help/qodana/linters.html" rel="noopener noreferrer"&gt;our documentation&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After the analysis is complete, you will see an invitation to check the results. Open Qodana UI in your browser using this link: &lt;a href="http://localhost:8080/" rel="noopener noreferrer"&gt;http://localhost:8080&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You will see a page that looks like the example below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fweb4von27wruzk8qjf18.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fweb4von27wruzk8qjf18.png" alt="Qodana UI main screen" width="800" height="576"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;During this first run, Qodana analyzes your project using vital checks only. Non-vital checks and folders containing non-vital code, such as the &lt;em&gt;Tests&lt;/em&gt; folder, are ignored. Qodana also reports any conditions that could affect the truthfulness or completeness of the results. For example, if your project relies on external resources or generated code that is unavailable during the analysis, the final results could be compromised. Qodana notifies you about such suspicious results. We encourage you to follow the guidance during project setup and tune the configuration. After the first run, everything you need will be at hand. You can review every problem in the left-hand panel, and you will see immediately how your adjustments affect the number of issues you need to work on.&lt;/p&gt;

&lt;p&gt;Our favorite step is the third one – putting all the detected problems into a &lt;a href="https://www.jetbrains.com/help/qodana/qodana-baseline.html" rel="noopener noreferrer"&gt;baseline&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F720ynzfk9zm341fcoybb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F720ynzfk9zm341fcoybb.png" alt="Baseline screen" width="800" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why put everything in a &lt;a href="https://bit.ly/what-is-technical-debt" rel="noopener noreferrer"&gt;technical debt&lt;/a&gt; (baseline)? Well, bringing the number of problems in your code down to zero is quite simple, really: first, fix all existing issues; second, ensure no new problems appear over time. The second part may be easier than the first one, and by using the baseline, we set the current project state as the initial one and only track new issues that appear.&lt;/p&gt;

&lt;p&gt;The last step in the project setup is downloading two files: &lt;code&gt;qodana.yaml&lt;/code&gt; and &lt;code&gt;qodana.sarif.json&lt;/code&gt;. Just place them into your project folder, and be sure to copy the suggested Docker command.&lt;/p&gt;

&lt;h2&gt;
  
  
  A local run with the baseline enabled
&lt;/h2&gt;

&lt;p&gt;Now return to your console and run Qodana again using this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:8080 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; &amp;lt;project-root-directory&amp;gt;:/data/project &lt;span class="se"&gt;\&lt;/span&gt;
  jetbrains/qodana-&amp;lt;linter&amp;gt; &lt;span class="nt"&gt;--show-report&lt;/span&gt; &lt;span class="se"&gt;\ &lt;/span&gt;
  &lt;span class="nt"&gt;--baseline&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;baseline.sarif.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please ensure you use the proper Docker image name.&lt;/p&gt;

&lt;p&gt;You will see something similar to the example below. Qodana now treats all of the previously discovered issues as the baseline and does not report them again.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7y4bmm7mzxlx3uftdr9b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7y4bmm7mzxlx3uftdr9b.png" alt="Qodana report with the baseline set" width="800" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Add even more checks
&lt;/h2&gt;

&lt;p&gt;At this point, you are ready for the next step – setting the quality gate in your CI. If you want to get started with that right away, feel free to jump right to the &lt;em&gt;Quality gate&lt;/em&gt; section of this post.&lt;/p&gt;

&lt;p&gt;But if you are feeling adventurous, you can examine the suggestions Qodana prepared for you, and perhaps enable even more checks. Use the &lt;em&gt;Problem examples&lt;/em&gt; dialog to see the checks we suggest, as well as some examples in your codebase that need improvement according to those rules. If you find them appropriate, turn them on, download the updated &lt;code&gt;qodana.yaml&lt;/code&gt; file to the project root folder, and run Qodana locally again to perform the same triage using even more checks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F38xim4xyos6i73gg74q7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F38xim4xyos6i73gg74q7.png" alt="Qodana profile" width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can repeat the previous steps again and again, thereby tailoring your configuration further. &lt;/p&gt;

&lt;p&gt;When you are happy with what you see locally – it’s time to set a quality gate for your CI pipeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quality gate for the CI pipeline
&lt;/h2&gt;

&lt;p&gt;One good thing about Qodana is that you can add it to any CI platform. But since it would be hard to cover all integration-related nuances in a single blog post, we will describe its integration with GitHub Actions. The process of setting up quality gates is very similar in all other CI platforms, too, with the exception of TeamCity. In TeamCity, we would suggest you use our &lt;a href="https://plugins.jetbrains.com/plugin/15498-qodana" rel="noopener noreferrer"&gt;dedicated plugin&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So, if you use GitHub Actions as your main CI platform, follow these steps to set up quality gates:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add &lt;code&gt;qodana.yaml&lt;/code&gt; and &lt;code&gt;qodana.sarif.json&lt;/code&gt; to your VCS. If you find &lt;code&gt;qodana.sarif.json&lt;/code&gt; is too big to be placed in your VCS, you can store it anywhere it is accessible for your GitHub Actions.&lt;/li&gt;
&lt;li&gt;Add the &lt;a href="https://github.com/JetBrains/qodana-action" rel="noopener noreferrer"&gt;Qodana GitHub Action&lt;/a&gt; to your workflow by following the instructions in &lt;a href="https://www.jetbrains.com/help/qodana/qodana-github-action.html" rel="noopener noreferrer"&gt;our documentation&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Set the workflow to run on &lt;em&gt;pull_request&lt;/em&gt; events that target the main branch.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;on:
  pull_request:
    branches:
    - main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Add the &lt;em&gt;fail-threshold&lt;/em&gt; option with a value of &lt;em&gt;0&lt;/em&gt; to the Qodana Action, as well as &lt;a href="https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/managing-a-branch-protection-rule" rel="noopener noreferrer"&gt;branch protection rules&lt;/a&gt; to any branch you want to protect. We suggest starting with the main branch. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7dyifr5fpuatqpjoxddi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7dyifr5fpuatqpjoxddi.png" alt="GitHub Quality Gate" width="800" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For more information about branch protection rules, refer to the &lt;a href="https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/managing-a-branch-protection-rule" rel="noopener noreferrer"&gt;GitHub Documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now you are all set! Your changes will be checked by Qodana so they will meet your standards. You can use this action as a proper quality gate. For example, you can check incoming pull requests and merge only those whose quality is up to your standards. If your most common scenario involves developing in branches, you can add this action to make sure the whole branch is checked before being merged into the main branch. Actually, you can include a Qodana Action in any part of your pipeline and use the produced artifacts and resulting exit code as the basis for further decisions.&lt;/p&gt;

&lt;p&gt;And if, like us, you like making New Year’s resolutions, you can make a plan to work on the issues from the baseline one step at a time in 2022. Qodana UI will help you plan out this work, e.g. you can choose issues to be fixed by category, or folder, or just one-by-one.&lt;/p&gt;

&lt;p&gt;When you reach zero issues in the actual list and the baseline, it will be time to go to the ‘next level’. You can turn to Qodana’s suggestions for inspiration, or study the whole list of checks to add more of them to your profile.&lt;/p&gt;

&lt;p&gt;By the way, Qodana is extensible: you can create your own checks. We will cover this topic in a dedicated blogpost at the beginning of next year.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it now and improve your code
&lt;/h2&gt;

&lt;p&gt;Check &lt;a href="https://www.jetbrains.com/qodana/" rel="noopener noreferrer"&gt;out the website&lt;/a&gt; to download the version of the components that’s suitable for your technology stack. Some of them have already reached stable releases, and some are available under an Early Access Program (EAP).  Don’t wait to set yourself up to meet your code quality goals in the new year. Future you will thank you!&lt;/p&gt;

&lt;h2&gt;
  
  
  Feedback
&lt;/h2&gt;

&lt;p&gt;We would be grateful for any feedback you have, and all ideas are welcome! Contact us at &lt;a href="mailto:qodana-support@jetbrains.com"&gt;qodana-support@jetbrains.com&lt;/a&gt; or via our &lt;a href="https://youtrack.jetbrains.com/issues/QD" rel="noopener noreferrer"&gt;issue tracker&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Your JetBrains Qodana Team&lt;br&gt;&lt;br&gt;
The Drive to Develop&lt;/em&gt;&lt;/p&gt;

</description>
      <category>codequality</category>
      <category>staticanalysis</category>
      <category>codereview</category>
      <category>jetbrains</category>
    </item>
  </channel>
</rss>
