<?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: Xianpeng Shen</title>
    <description>The latest articles on Forem by Xianpeng Shen (@shenxianpeng).</description>
    <link>https://forem.com/shenxianpeng</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F289026%2Fd0b1d1d2-19d2-4754-a8c6-f6f0c0911a34.jpg</url>
      <title>Forem: Xianpeng Shen</title>
      <link>https://forem.com/shenxianpeng</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/shenxianpeng"/>
    <language>en</language>
    <item>
      <title>Thank you for sharing the Conventional Branch.</title>
      <dc:creator>Xianpeng Shen</dc:creator>
      <pubDate>Tue, 16 Sep 2025 13:05:31 +0000</pubDate>
      <link>https://forem.com/shenxianpeng/thank-you-for-sharing-the-conventional-branch-2pfm</link>
      <guid>https://forem.com/shenxianpeng/thank-you-for-sharing-the-conventional-branch-2pfm</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/louis7/from-conventional-commits-to-conventional-branch-4flp" class="crayons-story__hidden-navigation-link"&gt;From Conventional Commits to Conventional Branch&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/louis7" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F929271%2Fd8eb2758-2c0a-4cc2-aec3-c3ed531cae08.png" alt="louis7 profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/louis7" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Louis Liu
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Louis Liu
                
              
              &lt;div id="story-author-preview-content-2342796" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/louis7" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F929271%2Fd8eb2758-2c0a-4cc2-aec3-c3ed531cae08.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Louis Liu&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/louis7/from-conventional-commits-to-conventional-branch-4flp" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Mar 26 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/louis7/from-conventional-commits-to-conventional-branch-4flp" id="article-link-2342796"&gt;
          From Conventional Commits to Conventional Branch
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/programming"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;programming&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/git"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;git&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/github"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;github&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/louis7/from-conventional-commits-to-conventional-branch-4flp" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/raised-hands-74b2099fd66a39f2d7eed9305ee0f4553df0eb7b4f11b01b6b1b499973048fe5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;3&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/louis7/from-conventional-commits-to-conventional-branch-4flp#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            3 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>programming</category>
      <category>git</category>
      <category>github</category>
    </item>
    <item>
      <title>New Jenkins Plugin: Let AI Explain Your Build Failures</title>
      <dc:creator>Xianpeng Shen</dc:creator>
      <pubDate>Fri, 01 Aug 2025 18:00:49 +0000</pubDate>
      <link>https://forem.com/shenxianpeng/new-jenkins-plugin-let-ai-explain-your-build-failures-26lo</link>
      <guid>https://forem.com/shenxianpeng/new-jenkins-plugin-let-ai-explain-your-build-failures-26lo</guid>
      <description>&lt;p&gt;Recently, I released my &lt;strong&gt;first-ever Jenkins plugin&lt;/strong&gt; – and &lt;a href="https://plugins.jenkins.io/explain-error/" rel="noopener noreferrer"&gt;it's now officially available in the Jenkins Center!&lt;/a&gt; 🎉&lt;/p&gt;

&lt;p&gt;This plugin makes it possible to &lt;strong&gt;analyze build errors with AI directly inside Jenkins&lt;/strong&gt;, so you no longer need to copy and paste logs into ChatGPT or other tools. Instead, you'll see an &lt;strong&gt;"Explain Error" button right in the console output&lt;/strong&gt;, and you can also use the &lt;code&gt;explainError()&lt;/code&gt; step in your pipeline to trigger AI analysis automatically when a build fails.&lt;/p&gt;

&lt;p&gt;This is my first contribution to the Jenkins plugin ecosystem. I used to think most things could be handled by pipeline scripts, and there wasn’t much need for custom plugins. But as AI becomes increasingly mainstream, I noticed something surprising: &lt;strong&gt;Jenkins still didn’t have a plugin for AI-based error explanation&lt;/strong&gt;. So, I decided to build one myself.&lt;/p&gt;

&lt;p&gt;With the help of AI and some late-night coding sessions, along with several rounds of thorough code review from the Jenkins Hosting team, the plugin finally went live last weekend. 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing the Plugin
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Explain Error Plugin&lt;/strong&gt; is an OpenAI-powered Jenkins plugin that can automatically analyze logs from failed builds and generate easy-to-understand explanations. It works with both Pipeline and Freestyle job types.&lt;/p&gt;

&lt;p&gt;GitHub repo: &lt;a href="https://github.com/jenkinsci/explain-error-plugin" rel="noopener noreferrer"&gt;https://github.com/jenkinsci/explain-error-plugin&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;👉 &lt;a href="https://youtu.be/rPI9PMeDQ2o?si=YMeprtSz9VmqglCL" rel="noopener noreferrer"&gt;Watch the hands-on demo on YouTube&lt;/a&gt; — setup, run, and see how AI explains your Jenkins job failures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;✅ One-click console error explanation&lt;/td&gt;
&lt;td&gt;Adds an “Explain Error” button to the build log view&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅ Pipeline support&lt;/td&gt;
&lt;td&gt;Use &lt;code&gt;explainError()&lt;/code&gt; in your pipeline scripts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅ Custom model support&lt;/td&gt;
&lt;td&gt;Choose GPT-3.5 or other models&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅ Jenkins CasC compatible&lt;/td&gt;
&lt;td&gt;Supports Configuration as Code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅ Log filtering&lt;/td&gt;
&lt;td&gt;Use regex patterns to focus on error content&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Jenkins version ≥ &lt;strong&gt;2.479.3&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Java version ≥ &lt;strong&gt;17&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;An &lt;strong&gt;OpenAI API key&lt;/strong&gt; (you can get one at &lt;a href="https://platform.openai.com/account/api-keys" rel="noopener noreferrer"&gt;OpenAI&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to Install
&lt;/h2&gt;

&lt;p&gt;Go to &lt;strong&gt;Manage Jenkins → Manage Plugins → Available&lt;/strong&gt;, then search for:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Explain Error Plugin”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And install it like any other Jenkins plugin.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuration
&lt;/h2&gt;

&lt;p&gt;Once installed, head to &lt;code&gt;Manage Jenkins → Configure System&lt;/code&gt; and scroll to &lt;strong&gt;Explain Error Plugin Configuration&lt;/strong&gt; to enter your OpenAI settings.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Default&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Enable Explanation&lt;/td&gt;
&lt;td&gt;Enable/disable AI explanation&lt;/td&gt;
&lt;td&gt;✅ Enabled&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API Key&lt;/td&gt;
&lt;td&gt;Your OpenAI API key&lt;/td&gt;
&lt;td&gt;Required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API URL&lt;/td&gt;
&lt;td&gt;OpenAI endpoint&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://api.openai.com/v1/chat/completions&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI Model&lt;/td&gt;
&lt;td&gt;Model to use&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gpt-3.5-turbo&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&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%2F0lrtdzedrafx88x5hox8.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%2F0lrtdzedrafx88x5hox8.png" alt="Explain Error Plugin Configuration" width="800" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Prefer managing Jenkins with Configuration as Code? You can configure it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;unclassified&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;explainError&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;enableExplanation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;${AI_API_KEY}"&lt;/span&gt;
    &lt;span class="na"&gt;apiUrl&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.openai.com/v1/chat/completions"&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-3.5-turbo"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to Use It
&lt;/h2&gt;

&lt;h3&gt;
  
  
  In Your Pipeline
&lt;/h3&gt;

&lt;p&gt;Best used in a &lt;code&gt;post { failure { ... } }&lt;/code&gt; block so it automatically analyzes failures:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;failure&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;explainError&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also customize how logs are filtered:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;explainError&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
  &lt;span class="nl"&gt;maxLines:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="nl"&gt;logPattern:&lt;/span&gt; &lt;span class="s1"&gt;'(?i)(error|failed|exception)'&lt;/span&gt;
&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  In Console Output
&lt;/h3&gt;

&lt;p&gt;This works for any job type:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to the console output of a failed build&lt;/li&gt;
&lt;li&gt;Click the “Explain Error” button at the top&lt;/li&gt;
&lt;li&gt;The AI-generated explanation will appear below the button&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Demo Preview
&lt;/h2&gt;

&lt;p&gt;When a build fails, you’ll see a sidebar entry on the build page where the AI explanation will be shown:&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%2F9j9u1furycebwmccbx46.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%2F9j9u1furycebwmccbx46.png" alt="Explain Error Plugin" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or you can view the explanation directly on the console page after clicking the “Explain Error” button:&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%2Fixwgmsz5uwstndipwete.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%2Fixwgmsz5uwstndipwete.png" alt="Explain Error Plugin Console" width="800" height="540"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Error caching&lt;/strong&gt;: Avoid redundant API calls for the same errors (already implemented, pending merge)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-model support&lt;/strong&gt;: Plan to support other AI services like Gemini, Claude, DeepSeek, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More features are under development or in the idea phase — and your feedback is always welcome!&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;The plugin is 100% open source — contributions and suggestions are very welcome!&lt;/p&gt;

&lt;p&gt;If you try the plugin and find it useful, feel free to share this article, or give the project a ⭐ on GitHub:&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/jenkinsci/explain-error-plugin" rel="noopener noreferrer"&gt;https://github.com/jenkinsci/explain-error-plugin&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That’s the best way to support open-source work like this. 🙌&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>jenkins</category>
      <category>ai</category>
      <category>devops</category>
      <category>ci</category>
    </item>
    <item>
      <title>C/C++ Lint Action | clang-format &amp; clang-tidy</title>
      <dc:creator>Xianpeng Shen</dc:creator>
      <pubDate>Fri, 26 Nov 2021 13:49:33 +0000</pubDate>
      <link>https://forem.com/shenxianpeng/cc-lint-action-clang-format-clang-tidy-2o18</link>
      <guid>https://forem.com/shenxianpeng/cc-lint-action-clang-format-clang-tidy-2o18</guid>
      <description>&lt;h3&gt;
  
  
  My Workflow
&lt;/h3&gt;

&lt;p&gt;A Github Action for linting C/C++ code integrating clang-tidy and clang-format to collect feedback provided in the form of thread comments and/or annotations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Submission Category:
&lt;/h3&gt;

&lt;p&gt;Maintainer Must-Haves&lt;/p&gt;

&lt;h3&gt;
  
  
  Yaml File or Link to Code
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/cpp-linter" rel="noopener noreferrer"&gt;
        cpp-linter
      &lt;/a&gt; / &lt;a href="https://github.com/cpp-linter/cpp-linter-action" rel="noopener noreferrer"&gt;
        cpp-linter-action
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A Github Action for linting C/C++ code integrating clang-tidy and clang-format to collect feedback provided in the form of file-annotations, thread-comments, workflow step-summary, and Pull Request reviews.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;C/C++ Linter Action &lt;sup&gt;| clang-format &amp;amp; clang-tidy&lt;/sup&gt;
&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/8e796160bb3d3443e229e628283290e74dbd96127d0c2a5ad9698f4dc5fa001e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f6370702d6c696e7465722f6370702d6c696e7465722d616374696f6e"&gt;&lt;img src="https://camo.githubusercontent.com/8e796160bb3d3443e229e628283290e74dbd96127d0c2a5ad9698f4dc5fa001e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f6370702d6c696e7465722f6370702d6c696e7465722d616374696f6e" alt="GitHub release (latest SemVer)"&gt;&lt;/a&gt;
&lt;a href="https://github.com/marketplace/actions/c-c-linter" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/e94cbd13fbdf76cfa6155e66519c2a285c3c7ecad2c523826d9a85e4fcffa334/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6d61726b6574706c6163652d43253246432532422532422532304c696e7465722d626c75653f6c6f676f3d676974687562" alt="GitHub marketplace"&gt;&lt;/a&gt;
&lt;a href="https://github.com/cpp-linter/cpp-linter-action/actions/workflows/cpp-linter.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/cpp-linter/cpp-linter-action/actions/workflows/cpp-linter.yml/badge.svg" alt="cpp-linter"&gt;&lt;/a&gt;
&lt;a href="https://github.com/cpp-linter/cpp-linter-action/actions/workflows/mkdocs-deploy.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/cpp-linter/cpp-linter-action/actions/workflows/mkdocs-deploy.yml/badge.svg" alt="MkDocs Deploy"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/9a356c958736ca21870028e2da359c2a58807b516e7fb39e2aa57d4089aa8d93/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6370702d6c696e7465722f6370702d6c696e7465722d616374696f6e3f6c6162656c3d6c6963656e7365266c6f676f3d676974687562"&gt;&lt;img src="https://camo.githubusercontent.com/9a356c958736ca21870028e2da359c2a58807b516e7fb39e2aa57d4089aa8d93/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6370702d6c696e7465722f6370702d6c696e7465722d616374696f6e3f6c6162656c3d6c6963656e7365266c6f676f3d676974687562" alt="GitHub"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A Github Action for linting C/C++ code integrating clang-tidy and clang-format
to collect feedback provided in the form of
&lt;a href="https://cpp-linter.github.io/cpp-linter-action/inputs-outputs/#file-annotations" rel="nofollow noopener noreferrer"&gt;&lt;code&gt;file-annotations&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://cpp-linter.github.io/cpp-linter-action/inputs-outputs/#thread-comments" rel="nofollow noopener noreferrer"&gt;&lt;code&gt;thread-comments&lt;/code&gt;&lt;/a&gt;
workflow &lt;a href="https://cpp-linter.github.io/cpp-linter-action/inputs-outputs/#step-summary" rel="nofollow noopener noreferrer"&gt;&lt;code&gt;step-summary&lt;/code&gt;&lt;/a&gt;, and Pull Request reviews (with
&lt;a href="https://cpp-linter.github.io/cpp-linter-action/inputs-outputs/#tidy-review" rel="nofollow noopener noreferrer"&gt;&lt;code&gt;tidy-review&lt;/code&gt;&lt;/a&gt; or &lt;a href="https://cpp-linter.github.io/cpp-linter-action/inputs-outputs/#format-review" rel="nofollow noopener noreferrer"&gt;&lt;code&gt;format-review&lt;/code&gt;&lt;/a&gt;).&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Usage&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Create a new GitHub Actions workflow in your project, e.g. at &lt;a href="https://github.com/cpp-linter/cpp-linter-action/blob/main/.github/workflows/cpp-linter.yml" rel="noopener noreferrer"&gt;.github/workflows/cpp-linter.yml&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The content of the file should be in the following format.&lt;/p&gt;
&lt;div class="highlight highlight-source-yaml notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;    &lt;span class="pl-ent"&gt;steps&lt;/span&gt;:
      - &lt;span class="pl-ent"&gt;uses&lt;/span&gt;: &lt;span class="pl-s"&gt;actions/checkout@v5&lt;/span&gt;
      - &lt;span class="pl-ent"&gt;uses&lt;/span&gt;: &lt;span class="pl-s"&gt;cpp-linter/cpp-linter-action@v2&lt;/span&gt;
        &lt;span class="pl-ent"&gt;id&lt;/span&gt;: &lt;span class="pl-s"&gt;linter&lt;/span&gt;
        &lt;span class="pl-ent"&gt;env&lt;/span&gt;:
          &lt;span class="pl-ent"&gt;GITHUB_TOKEN&lt;/span&gt;: &lt;span class="pl-s"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;
        &lt;span class="pl-ent"&gt;with&lt;/span&gt;:
          &lt;span class="pl-ent"&gt;style&lt;/span&gt;: &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;'&lt;/span&gt;file&lt;span class="pl-pds"&gt;'&lt;/span&gt;&lt;/span&gt;  &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Use .clang-format config file&lt;/span&gt;
          &lt;span class="pl-ent"&gt;tidy-checks&lt;/span&gt;: &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;'&lt;/span&gt;&lt;span class="pl-pds"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Use .clang-tidy config file&lt;/span&gt;
          &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; only 'update' a single comment in a pull request thread.&lt;/span&gt;
          &lt;span class="pl-ent"&gt;thread-comments&lt;/span&gt;: &lt;span class="pl-s"&gt;${{ github.event_name == 'pull_request' &amp;amp;&amp;amp; 'update' }}&lt;/span&gt;
      - &lt;span class="pl-ent"&gt;name&lt;/span&gt;: &lt;span class="pl-s"&gt;Fail fast?!&lt;/span&gt;
        &lt;span class="pl-ent"&gt;if&lt;/span&gt;: &lt;span class="pl-s"&gt;steps.linter.outputs.checks-failed &amp;gt; 0&lt;/span&gt;
        &lt;span class="pl-ent"&gt;run&lt;/span&gt;: &lt;span class="pl-s"&gt;exit 1&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;For all explanations of our available input parameters and…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/cpp-linter/cpp-linter-action" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://github.com/cpp-linter/cpp-linter-action/blob/master/.github/workflows/cpp-linter.yml" rel="noopener noreferrer"&gt;cpp-linter.yml&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cpp-linter&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;opened&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;reopened&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;  &lt;span class="c1"&gt;# let PR-synchronize events be handled by push events&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;cpp-linter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cpp-linter/cpp-linter-action@v2&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;linter&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;GITHUB_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;file&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Fail fast?!&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;steps.linter.outputs.checks-failed &amp;gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;echo "Some files failed the linting checks!"&lt;/span&gt;
        &lt;span class="c1"&gt;# for actual deployment&lt;/span&gt;
        &lt;span class="c1"&gt;# run: exit 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Additional Resources / Info
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://cpp-linter.github.io/cpp-linter-action/" rel="noopener noreferrer"&gt;https://cpp-linter.github.io/cpp-linter-action/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;Annotations&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%2Fgithub.com%2Fshenxianpeng%2Fcpp-linter-action%2Fraw%2Fmaster%2Fdocs%2Fimages%2Fannotations-clang-format.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%2Fgithub.com%2Fshenxianpeng%2Fcpp-linter-action%2Fraw%2Fmaster%2Fdocs%2Fimages%2Fannotations-clang-format.png" alt="annotations-clang-format" width="800" height="400"&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%2Fgithub.com%2Fshenxianpeng%2Fcpp-linter-action%2Fraw%2Fmaster%2Fdocs%2Fimages%2Fannotations-clang-tidy.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%2Fgithub.com%2Fshenxianpeng%2Fcpp-linter-action%2Fraw%2Fmaster%2Fdocs%2Fimages%2Fannotations-clang-tidy.png" alt="annotations-clang-tidy" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thread Comment&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%2Fkt9j9ymi7mkkcfx0nuag.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%2Fkt9j9ymi7mkkcfx0nuag.png" alt="Thread Comment" width="800" height="938"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>actionshackathon21</category>
      <category>opensource</category>
      <category>githubactions</category>
      <category>clangformat</category>
    </item>
  </channel>
</rss>
