<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Martin Todorov</title>
    <description>The latest articles on DEV Community by Martin Todorov (@carlspring).</description>
    <link>https://dev.to/carlspring</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%2F494366%2F1886e8d0-4856-4abf-8902-ed1c85234dad.png</url>
      <title>DEV Community: Martin Todorov</title>
      <link>https://dev.to/carlspring</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/carlspring"/>
    <language>en</language>
    <item>
      <title>Why Security as part of CI/CD Matters (And Where To Start)</title>
      <dc:creator>Martin Todorov</dc:creator>
      <pubDate>Sun, 27 Jul 2025 14:14:44 +0000</pubDate>
      <link>https://dev.to/carlspring/why-security-as-part-of-cicd-matters-and-where-to-start-obh</link>
      <guid>https://dev.to/carlspring/why-security-as-part-of-cicd-matters-and-where-to-start-obh</guid>
      <description>&lt;p&gt;CI/CD pipelines are the backbone of modern software delivery. They automate testing, integration, releasing and deployment—making rapid iteration possible. But that speed also comes with risk. Without proper guardrails, you may end up automating the delivery of vulnerabilities straight into production.&lt;/p&gt;

&lt;p&gt;Security can no longer be something we bolt on at the end. It needs to be baked into every step of your pipeline, becoming an integral part of how software is built and released. This mindset shift is what DevSecOps brings to the table: not a replacement for DevOps, but a natural progression of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Security Must Be Part of DevOps
&lt;/h2&gt;

&lt;p&gt;DevOps emphasizes speed, collaboration, and automation—but in many setups, security practices haven’t kept pace. The traditional model of deferring security reviews to a final QA phase just doesn’t work in a world where teams deploy several times a day.&lt;/p&gt;

&lt;p&gt;DevSecOps enhances DevOps by embedding security into the entire lifecycle: from design and development, to build, deployment, and operations. By automating security checks and making them part of the CI/CD process, teams can prevent vulnerabilities instead of patching them after they've hit production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Ingredients of a Secure CI/CD Pipeline
&lt;/h2&gt;

&lt;p&gt;A well-secured pipeline includes a mix of proactive and reactive measures, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Static Application Security Testing (SAST):&lt;/strong&gt; Scan source code early to catch vulnerabilities like injection risks or hardcoded secrets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic Application Security Testing (DAST):&lt;/strong&gt; Test running applications in staging to find real-world attack surfaces.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Software Composition Analysis (SCA):&lt;/strong&gt; Automatically detect known vulnerabilities in third-party libraries and dependencies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secrets Management &amp;amp; Scanning:&lt;/strong&gt; Avoid hardcoded API keys and use automated scans to prevent accidental leaks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure as Code (IaC) Security:&lt;/strong&gt; Ensure your environment definitions (like Terraform) are free of dangerous misconfigurations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Container Image Scanning:&lt;/strong&gt; Identify vulnerabilities in base images before deploying them to production.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compliance Automation:&lt;/strong&gt; Use security-as-code policies to enforce regulatory controls continuously.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Together, these practices allow you to build confidence into every commit and deployment, without slowing things down.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Happens When You Leave Security Behind
&lt;/h2&gt;

&lt;p&gt;Neglecting security in your CI/CD pipelines isn’t a harmless oversight—it’s an invitation for trouble.&lt;/p&gt;

&lt;p&gt;Hardcoded credentials, unpatched dependencies, and misconfigured infrastructure can all go unnoticed until they become incidents. By then, the fix is no longer cheap or easy—it’s public, costly, and potentially damaging to your users’ trust.&lt;/p&gt;

&lt;p&gt;Secure pipelines enable your team to detect and fix issues early, automate repetitive controls, and avoid the fire drills that come with late-stage security surprises. They’re not just safer—they’re smarter and more scalable.&lt;/p&gt;




&lt;h2&gt;
  
  
  Want to go deeper?
&lt;/h2&gt;

&lt;p&gt;This is just a quick overview of what it means to integrate security into your CI/CD workflows. If you're looking for a more detailed guide—including tools, tips, and best practices—you can:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://medium.com/@carlspring/why-you-need-to-bake-security-into-your-ci-cd-pipelines-7c53a32d5c4d" rel="noopener noreferrer"&gt;Checkout my detailed article about this on Medium&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>cicd</category>
      <category>security</category>
      <category>infosec</category>
    </item>
    <item>
      <title>Writing parallelizable tests with the carlspring/idempotence framework for Java</title>
      <dc:creator>Martin Todorov</dc:creator>
      <pubDate>Sun, 06 Oct 2024 04:18:28 +0000</pubDate>
      <link>https://dev.to/carlspring/writing-parallelizable-tests-with-the-carlspringidempotence-framework-for-java-420n</link>
      <guid>https://dev.to/carlspring/writing-parallelizable-tests-with-the-carlspringidempotence-framework-for-java-420n</guid>
      <description>&lt;h2&gt;
  
  
  Disclaimer
&lt;/h2&gt;

&lt;p&gt;This is a re-post of my article on &lt;a href="https://medium.com/@carlspring/writing-parallelizable-tests-with-the-carlspring-idempotence-framework-for-java-3cbf2673f4cb" rel="noopener noreferrer"&gt;Medium.com&lt;/a&gt; with the hope of reaching more OSS developers as part of #Hacktoberfest.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Have you ever had to deal with flaky parallelized tests that pass most of the time but then suddenly start failing with inconsistent random errors? Have you ever had to fix tests that share the same resource files and modify them in parallel to confuse the heck out of you and the outcomes of your other tests? Have you spent countless nights trying to refactor such code so that it can be properly parallelized and have reproducible and guaranteed results?&lt;/p&gt;

&lt;p&gt;This is a complex topic that is not always straight-forward to resolve, especially in existing large code bases. However, following a simple set of rules can help you get there and the &lt;a href="https://github.com/carlspring/idempotence" rel="noopener noreferrer"&gt;carlspring/idempotence&lt;/a&gt; framework aims to help with this.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is test isolation?
&lt;/h2&gt;

&lt;p&gt;In order for tests to be reproducible all of the time, you need to make sure that their resource files are contained and isolated just to them. What this means is that each test should own its test resources exclusively and other tests should not modify them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is test idempotence?
&lt;/h2&gt;

&lt;p&gt;Test idempotence means that your tests will always return the same results. No matter how many times they have been exectued and no matter what other tests are running in parallel.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the carlspring/idempotence framework for Java
&lt;/h2&gt;

&lt;p&gt;This is a leightweight framework which helps defining and copying test resource files in an isolated way for your JUnit5 tests. The test resources are defined using annotations and are copied in their own directories to help with the implementation of test resource separation and isolation.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the Java carlspring/idempotence framework works
&lt;/h2&gt;

&lt;p&gt;All common test resources are stored under the &lt;code&gt;src/test/resources&lt;/code&gt; directory as usual. Each test method then defines the resources it needs by using the &lt;code&gt;@TestResources&lt;/code&gt; annotation. The framework copies these resources to an isolated directory for each test method. This ensures that it has exclusive access to the resources it requires, preventing interference from other tests running in parallel, including other test methods in the same test class.&lt;/p&gt;

&lt;p&gt;For each build tool, there is a separate dependency that contains path-related transformation logic for the specific directory layout of that tool. (As a very simplified example, among other things. Maven places the built code under &lt;code&gt;target&lt;/code&gt;, whereas Gradle uses &lt;code&gt;build&lt;/code&gt; for this purpose; resources are placed differently, etc). More on this will be explained below.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to write tests using the Java carlspring/idempotence framework
&lt;/h2&gt;

&lt;p&gt;Here are the step you will need to get started.&lt;/p&gt;

&lt;h3&gt;
  
  
  Define The Dependencies
&lt;/h3&gt;

&lt;p&gt;You will need to define the respective dependency for your build tool. You can check what the latest released version is &lt;a href="https://github.com/carlspring/idempotence/releases" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For Gradle (using Groovy DSL):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;testImplementation&lt;/span&gt; &lt;span class="s2"&gt;"org.carlspring.testing.idempotence:idempotence-gradle:1.0.0-rc-3"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Gradle (using Kotlin DSL):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;testImplementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"org.carlspring.testing.idempotence:idempotence-gradle:1.0.0-rc-3"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;For Maven:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.carlspring.testing.idempotence&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;idempotence-maven&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0.0-rc-3&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Add Annotations
&lt;/h3&gt;

&lt;p&gt;Your test class will have to be annotated with the &lt;code&gt;@ExtendWith(TestResourceExtension.class)&lt;/code&gt; annotation. This annotation is responsible for the actual copying of the resources.&lt;/p&gt;

&lt;p&gt;You will also need to annotate your test methods with the &lt;code&gt;@TestResources&lt;/code&gt; annotation to specify the resources that they need.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.foo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.carlspring.testing.idempotence.annotation.TestResource&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.carlspring.testing.idempotence.annotation.TestResources&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.carlspring.testing.idempotence.extension.TestResourceExtension&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@ExtendWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;TestResourceExtension&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="nd"&gt;@TestResources&lt;/span&gt;&lt;span class="o"&gt;({&lt;/span&gt; &lt;span class="nd"&gt;@TestResource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"classpath:/foo.txt"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
                     &lt;span class="nd"&gt;@TestResource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"classpath*:/**/bar.txt"&lt;/span&gt;&lt;span class="o"&gt;)}&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testFoo&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Perform whatever checks you need using these resources&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;For each test method a directory will be created using the following format:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For a Gradle project, with a test called &lt;code&gt;MyTest&lt;/code&gt; with a method &lt;code&gt;testFoo&lt;/code&gt;,
they will be placed under:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;build/test-resources/MyTest-testFoo/nested/dir/foo.txt
build/test-resources/MyTest-testFoo/bar.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;For a Maven project, with a test called &lt;code&gt;MyTest&lt;/code&gt; with a method &lt;code&gt;testFoo&lt;/code&gt;,
they will be placed under:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;target/test-resources/MyTest-testFoo/nested/dir/foo.txt
target/test-resources/MyTest-testFoo/bar.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way your tests will have the resource that they require copied into their own isolated directories. At this point you can modify these test resources from the test methods they belong to and your results should be idempotent, provided that they only depend on file based resources and not other types of shared resources (database, third-party services, etc).&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to find the documentation
&lt;/h2&gt;

&lt;p&gt;The documentation of the Idempotence project can be found &lt;a href="https://carlspring.github.io/idempotence/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can have a look at the &lt;a href="https://carlspring.github.io/idempotence/developers-guide/conceptual-overview/" rel="noopener noreferrer"&gt;Conceptual Overview&lt;/a&gt; for more detailed explanation of how things work.&lt;/p&gt;

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

&lt;p&gt;This is a greenfield project with the core functionality and infrastructure in place, but help is always welcome.&lt;/p&gt;

&lt;p&gt;Contributors who have experience with JUnit, Springframework, MkDocs could help shape the project with some great ideas and solutions. Early adopters who could provide feedback are also very welcome!&lt;/p&gt;

&lt;p&gt;Issues labelled &lt;code&gt;hacktoberfest&lt;/code&gt; or &lt;code&gt;help wanted&lt;/code&gt; are up for grabs and should help you get started quickly. You can find them &lt;a href="https://github.com/carlspring/idempotence/issues?q=label%3A%22hacktoberfest%22%2C%22help+wanted%22" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;One of the most important things when writing test cases is the test data that your tests will use and keeping it sane between runs. By following a set of simple rules to keep this data isolated between your tests, you can achieve idempotence and reliability of your results.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/carlspring/idempotence" rel="noopener noreferrer"&gt;carlspring/idempotence&lt;/a&gt; project provides and easy to use framework which is suitable for both greenfield projects and refactoring legacies.&lt;/p&gt;

</description>
      <category>java</category>
      <category>spring</category>
      <category>junit5</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
