<?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: CircleCI</title>
    <description>The latest articles on DEV Community by CircleCI (@circleci).</description>
    <link>https://dev.to/circleci</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%2F354%2Fc2fcc743-c2bc-4974-89bc-123a36461347.png</url>
      <title>DEV Community: CircleCI</title>
      <link>https://dev.to/circleci</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/circleci"/>
    <language>en</language>
    <item>
      <title>Setting up continuous integration with CircleCI and GitLab</title>
      <dc:creator>Zan Markan</dc:creator>
      <pubDate>Wed, 07 Jun 2023 23:12:45 +0000</pubDate>
      <link>https://dev.to/circleci/setting-up-continuous-integration-with-circleci-and-gitlab-1mdp</link>
      <guid>https://dev.to/circleci/setting-up-continuous-integration-with-circleci-and-gitlab-1mdp</guid>
      <description>&lt;p&gt;CircleCI supports &lt;a href="https://circleci.com/blog/announcing-gitlab-support/"&gt;GitLab&lt;/a&gt; as a version control system (VCS). In this tutorial you will learn how to set up your first CircleCI CI/CD pipeline for a project hosted on GitLab. As GitLab can be used either as a SaaS tool, as well as self-managed on-premise installation, I will cover the steps to connect it with CircleCI for both.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites and application basics
&lt;/h2&gt;

&lt;p&gt;To follow along with this tutorial, you will need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic knowledge of Git commands&lt;/li&gt;
&lt;li&gt;Git installed and accessible on your machine&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://gitlab.com/users/sign_up"&gt;GitLab account&lt;/a&gt; — either self-managed or SaaS&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://circleci.com/signup/"&gt;CircleCI account&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Starter app
&lt;/h3&gt;

&lt;p&gt;Our starter application is a minimal Python Flask app with a single ‘hello world’ web page, which specifies required dependencies and includes a test. You can access a &lt;a href="https://gitlab.com/cci-devrel-demos/python-app-base"&gt;publicly hosted version of the starter app&lt;/a&gt; on GitLab.com.&lt;/p&gt;

&lt;p&gt;You can get the application by downloading it straight from the GitLab web interface or cloning it via Git.&lt;/p&gt;

&lt;p&gt;For the purposes of this tutorial, you don’t need to write the application from scratch, but if you are interested in complete development instruction, you can read through the beginning of [this blog post](&lt;a href="https://circleci.com/blog/setting-up-continuous-integration-with-github/"&gt;https://circleci.com/blog/setting-up-continuous-integration-with-github/&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitLab SaaS vs self-managed
&lt;/h2&gt;

&lt;p&gt;As mentioned above, this tutorial will teach you how to configure and run your CircleCI pipeline for a project hosted either on a self-managed or hosted version of GitLab. You can learn more about the differences between the hosted and self-managed versions in the &lt;a href="https://docs.gitlab.com/ee/install/migrate/compare_sm_to_saas.html"&gt;GitLab docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Setting up GitLab SaaS requires you only to sign up at gitlab.com. You will also need to make sure you can push to GitLab repositories, either by setting up your &lt;a href="https://docs.gitlab.com/ee/user/ssh.html"&gt;SSH key&lt;/a&gt; or &lt;a href="https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#personal-access-tokens"&gt;personal access token&lt;/a&gt; for using GitLab with either SSH or HTTPS, respectively.&lt;/p&gt;

&lt;p&gt;If you use GitLab self-managed, you will connect to it via your installation URL. This is specific to you, so for the purposes of this tutorial, use the URL &lt;code&gt;yourgitlabinstance.com&lt;/code&gt; as a placeholder.&lt;/p&gt;

&lt;p&gt;Create a new project with the starter app source code. You can use the new project wizard, either at &lt;code&gt;gitlab.com/projects/new&lt;/code&gt; or &lt;code&gt;yourgitlabinstance.com/projects/new&lt;/code&gt;, for SaaS or self-managed respectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a CircleCI config file
&lt;/h2&gt;

&lt;p&gt;Before you set up CircleCI, you can tell it what to eventually start building.&lt;/p&gt;

&lt;p&gt;Create a new directory &lt;code&gt;.circleci&lt;/code&gt; in the top level of the project.&lt;/p&gt;

&lt;p&gt;Now, create a new file &lt;code&gt;config.yml&lt;/code&gt; in that directory (&lt;code&gt;.circleci/config.yml&lt;/code&gt;) — this is your main configuration file for CircleCI.&lt;/p&gt;

&lt;p&gt;Paste the following in the file:&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;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2.1&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;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cimg/python:3.10.11&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="s"&gt;checkout&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;restore_cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deps1-{{ .Branch }}-{{ checksum "requirements.txt" }}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&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;Install dependencies&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;python3 -m venv venv&lt;/span&gt;
            &lt;span class="s"&gt;. venv/bin/activate&lt;/span&gt;
            &lt;span class="s"&gt;pip install -r requirements.txt&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;save_cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deps1-{{ .Branch }}-{{ checksum "requirements.txt" }}&lt;/span&gt;
          &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;venv"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&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;Running tests&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;. venv/bin/activate&lt;/span&gt;
            &lt;span class="s"&gt;python3 tests.py&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;store_artifacts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test-reports/&lt;/span&gt;
          &lt;span class="na"&gt;destination&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python_app&lt;/span&gt;

&lt;span class="na"&gt;workflows&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;run-tests&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="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the CircleCI config file, you define everything you need CircleCI to do. In this case, you have added a single job (&lt;code&gt;test&lt;/code&gt;) and a workflow (&lt;code&gt;run-tests&lt;/code&gt;) containing that job.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;test&lt;/code&gt; job runs in a &lt;a href="https://circleci.com/blog/docker-image-vs-container/"&gt;Docker container&lt;/a&gt; with Python installed, checks out the code at that specific commit, downloads the dependencies required for the app (Flask, in this case), sets up a Python venv, and runs the tests in &lt;code&gt;tests.py&lt;/code&gt;. It also caches the dependencies to make subsequent pipeline runs faster and stores the test artifacts for easy access from CircleCI. To read more about CircleCI configuration, consult the &lt;a href="https://circleci.com/docs/configuration-reference/"&gt;configuration reference&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Save, make a new commit, and push to your GitLab repository. Now it’s time to configure your CircleCI integration with GitLab.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring CircleCI with GitLab SaaS (GitLab.com)
&lt;/h2&gt;

&lt;p&gt;If you don’t have a CircleCI account yet, create one now. Head to &lt;a href="https://circleci.com/signup/"&gt;https://circleci.com/signup/&lt;/a&gt; and follow the instructions to sign up using your preferred method. If you choose GitLab, you will also be prompted to select your GitLab instance. Press &lt;strong&gt;Connect&lt;/strong&gt; next to GitLab.com.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aUUQejhe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://ctf-cci-com.imgix.net/34Js8TAdWkl0nANRkvODxw/cdef5ce2194a0331bed75a31ed986889/2023-05-08-ci-gitlab-18.48.16.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aUUQejhe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://ctf-cci-com.imgix.net/34Js8TAdWkl0nANRkvODxw/cdef5ce2194a0331bed75a31ed986889/2023-05-08-ci-gitlab-18.48.16.png" alt="Connect to your code" width="800" height="655"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This should now prompt you to authorize CircleCI with your GitLab account, giving CircleCI access to your repositories.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eH5w1lRZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://ctf-cci-com.imgix.net/2VSZ1kg5MI1I1R9S9tYpVJ/3683095bd43b7f67dcbd4822452c8b4d/2023-05-08-ci-gitlab-19.09.38.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eH5w1lRZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://ctf-cci-com.imgix.net/2VSZ1kg5MI1I1R9S9tYpVJ/3683095bd43b7f67dcbd4822452c8b4d/2023-05-08-ci-gitlab-19.09.38.png" alt="Authorize CircleCI" width="601" height="429"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Authorizing CircleCI will take you to the project creation wizard. You should see your repository on the list, and it should detect the CircleCI config you committed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PWHYDJf7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://ctf-cci-com.imgix.net/55pwGMRJZ5arUonK1Ru7fG/914d779cd5a35492652aac7c8e57b806/2023-05-08-ci-gitlab-19.16.46.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PWHYDJf7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://ctf-cci-com.imgix.net/55pwGMRJZ5arUonK1Ru7fG/914d779cd5a35492652aac7c8e57b806/2023-05-08-ci-gitlab-19.16.46.png" alt="Create new project" width="718" height="713"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Create Project&lt;/strong&gt; to start building. This has created the project in CircleCI, and what’s left is to commit and push a change to trigger your first CircleCI pipeline.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hpm4hIBj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://ctf-cci-com.imgix.net/4pjBH6grcr53Qs9Z3RpsvH/e2c5618dce322633f4739831674859fe/2023-05-09-ci-gitlab-01.27.40.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hpm4hIBj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://ctf-cci-com.imgix.net/4pjBH6grcr53Qs9Z3RpsvH/e2c5618dce322633f4739831674859fe/2023-05-09-ci-gitlab-01.27.40.png" alt="Make a change" width="800" height="673"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make any change, such as an update to your README file, then commit and push. This will create your first pipeline and start building and running your test.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--f2EPxIAF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://ctf-cci-com.imgix.net/7FKLZa07roF52X4xpiLd3t/225b6190675a9adf76e6ceac52e647ea/2023-05-09-ci-gitlab-01.29.14.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--f2EPxIAF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://ctf-cci-com.imgix.net/7FKLZa07roF52X4xpiLd3t/225b6190675a9adf76e6ceac52e647ea/2023-05-09-ci-gitlab-01.29.14.png" alt="Build status" width="800" height="670"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Seconds later it should be marked as successful. The status of your CircleCI pipeline will be automatically updated in your GitLab UI as well. Navigate to Build/Pipelines (on the left-hand side in GitLab) and the pipeline should show up there as well. You can see an example based on this tutorial in this &lt;a href="https://gitlab.com/cci-devrel-demos/cci-python-app/-/pipelines"&gt;public project&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--co-axm1d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://ctf-cci-com.imgix.net/5hodZ8zxiaNFW7TM7pNLTa/403fe6d9b33bcd1c25840c1f42534f59/2023-05-09-ci-gitlab-01.32.03.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--co-axm1d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://ctf-cci-com.imgix.net/5hodZ8zxiaNFW7TM7pNLTa/403fe6d9b33bcd1c25840c1f42534f59/2023-05-09-ci-gitlab-01.32.03.png" alt="Build/Pipelines" width="800" height="588"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clicking it will show you further details of the pipeline. Clicking the button under external - button &lt;strong&gt;CircleCI: Workflow run tests&lt;/strong&gt; will take you back full circle into your workflow inside CircleCI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--c9RZSdbV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://ctf-cci-com.imgix.net/WGuoPZr3wfwmwPLDhcL7o/bf8ae751b53e7a6e9728d6b385243e77/2023-05-09-ci-gitlab-01.32.41.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--c9RZSdbV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://ctf-cci-com.imgix.net/WGuoPZr3wfwmwPLDhcL7o/bf8ae751b53e7a6e9728d6b385243e77/2023-05-09-ci-gitlab-01.32.41.png" alt="Pipeline details" width="800" height="588"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting CircleCI to a self-managed GitLab instance
&lt;/h2&gt;

&lt;p&gt;Self-managed installations, unlike the hosted SaaS versions, run on infrastructure you control. They will of course also have a different URL to access them. In this tutorial, use &lt;code&gt;yourgitlabinstance.com&lt;/code&gt; as a placeholder for your actual instance URL. This section closely follows the &lt;a href="https://circleci.com/docs/gitlab-integration"&gt;GitLab integration instructions in the CircleCI docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Assuming you have followed the steps to get the project into GitLab and committed your first CircleCI config file, you can proceed with connecting to GitLab.&lt;/p&gt;

&lt;p&gt;If you don’t have a CircleCI account yet, create one now. Head to &lt;a href="https://circleci.com/signup/"&gt;https://circleci.com/signup/&lt;/a&gt; and follow the instructions to sign up with your preferred method.&lt;/p&gt;

&lt;p&gt;If you choose to sign up with GitLab, you will be prompted to select your GitLab instance. Press &lt;strong&gt;Connect&lt;/strong&gt; next to GitLab self-managed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aUUQejhe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://ctf-cci-com.imgix.net/34Js8TAdWkl0nANRkvODxw/cdef5ce2194a0331bed75a31ed986889/2023-05-08-ci-gitlab-18.48.16.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aUUQejhe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://ctf-cci-com.imgix.net/34Js8TAdWkl0nANRkvODxw/cdef5ce2194a0331bed75a31ed986889/2023-05-08-ci-gitlab-18.48.16.png" alt="Connect self-managed" width="800" height="655"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  GitLab self-managed project setup
&lt;/h3&gt;

&lt;p&gt;The wizard guides you through the setup process step by step.&lt;/p&gt;

&lt;p&gt;First enter the URL of your GitLab instance and click &lt;strong&gt;Verify&lt;/strong&gt;. It will suffix it with &lt;code&gt;/api/v4&lt;/code&gt; to complete your instance’s API endpoint.&lt;/p&gt;

&lt;p&gt;Create your &lt;a href="https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html"&gt;personal GitLab access token&lt;/a&gt; with an API scope, paste it in the Personal Access Token field and click &lt;strong&gt;Verify&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Next, pass in the &lt;code&gt;known_hosts&lt;/code&gt; value and click &lt;strong&gt;Verify&lt;/strong&gt;. You can get this by running &lt;code&gt;ssh-keyscan yourgitlabinstance.com&lt;/code&gt; in the terminal and pasting the entire output in the &lt;code&gt;known_hosts field&lt;/code&gt;. This allows CircleCI to &lt;a href="https://circleci.com/docs/gitlab-integration/#establish-the-authenticity-of-an-ssh-host"&gt;verify the authenticity&lt;/a&gt; of your GitLab instance.&lt;/p&gt;

&lt;p&gt;Finally, select your project in the dropdown. This will likely be &lt;code&gt;cci-python-app&lt;/code&gt;. You can also give it a different name. This will set your GitLab self-managed project up for building on CircleCI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yF8X0WyE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://ctf-cci-com.imgix.net/3uHYOJan5yJSACrQlvHYCH/29d1adf431472cfa84bc2d9cf6a6a7be/2023-05-08-ci-gitlab-20.11.21.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yF8X0WyE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://ctf-cci-com.imgix.net/3uHYOJan5yJSACrQlvHYCH/29d1adf431472cfa84bc2d9cf6a6a7be/2023-05-08-ci-gitlab-20.11.21.png" alt="New self-managed project" width="773" height="1084"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Trigger a pipeline by committing a change and pushing it to your GitLab repo. This will start your workflow and show it in the next few seconds.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wmuGpcxn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://ctf-cci-com.imgix.net/vKnYtN1PPmy4QUmF5XH3m/b07d56d8985838bd4e56941c8e1c9402/2023-05-09-ci-gitlab-01.37.59.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wmuGpcxn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://ctf-cci-com.imgix.net/vKnYtN1PPmy4QUmF5XH3m/b07d56d8985838bd4e56941c8e1c9402/2023-05-09-ci-gitlab-01.37.59.png" alt="Project workflows" width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also see your pipeline in the GitLab UI by navigating to CI/CD &amp;gt; Pipelines on the left-hand side. Note that this might look different, depending on what version of GitLab you are using.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GaQ7fczI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://ctf-cci-com.imgix.net/3yPlK18ZvGO75M2hc8dUsC/381d03ef962ea74f903ae24ad6512845/2023-05-09-ci-gitlab-01.33.49.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GaQ7fczI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://ctf-cci-com.imgix.net/3yPlK18ZvGO75M2hc8dUsC/381d03ef962ea74f903ae24ad6512845/2023-05-09-ci-gitlab-01.33.49.png" alt="GitLab pipelines view" width="800" height="588"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clicking on its status it will take you to the pipeline details, from where you can navigate back to the CircleCI UI to give you a 360 degree view of your project and your CI/CD pipeline’s workflows and jobs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Jhb7py_d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://ctf-cci-com.imgix.net/68JW7CkbSe8OZsdCnYjI19/a9bff076e54e4f84dff3054f38295f0e/2023-05-09-ci-gitlab-01.34.42.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Jhb7py_d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://ctf-cci-com.imgix.net/68JW7CkbSe8OZsdCnYjI19/a9bff076e54e4f84dff3054f38295f0e/2023-05-09-ci-gitlab-01.34.42.png" alt="Workflow and jobs" width="800" height="588"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulations! You have successfully configured CircleCI to start building your project on a self-managed GitLab instance.&lt;/p&gt;

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

&lt;p&gt;In this tutorial you have learned how to begin building projects hosted on GitLab with CircleCI. We have covered both on-premise self-managed GitLab as well as the hosted SaaS version on GitLab.com.&lt;/p&gt;

&lt;p&gt;Wishing you successful building!&lt;/p&gt;

</description>
      <category>circleci</category>
      <category>gitlab</category>
      <category>cicd</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>CI/CD for interdepartmental teams</title>
      <dc:creator>Zan Markan</dc:creator>
      <pubDate>Thu, 02 Feb 2023 18:00:00 +0000</pubDate>
      <link>https://dev.to/circleci/cicd-for-interdepartmental-teams-4h8</link>
      <guid>https://dev.to/circleci/cicd-for-interdepartmental-teams-4h8</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;The topic of CI/CD is often considered the domain of DevOps, infrastructure, and development teams. I would argue this thinking misses the great opportunity that is including the entire organisation in the conversation around software delivery lifecycle (SDLC). From QA, to product managers, to of course operators, security, all the way through to the top of engineering and technology leadership. Especially as organisations increasingly rely on software, not only in tech industry but in most other industries as well, it makes sense to spread the DevOps thinking and the use of tools such as CI/CD to more folks, more teams, and more departments.&lt;/p&gt;

&lt;p&gt;Incidentally, that’s what the DevOps movement is all about, and its natural evolution. Bringing the principles of early and continuous collaboration across departments to their entire organisations.&lt;/p&gt;

&lt;p&gt;This article argues for the use of CI/CD across various company departments - to anyone involved in - or adjacent to - the software delivery process, and covers the principles and tools that will benefit them, and points you to how to implement this using CircleCI in your organisation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who this article is for
&lt;/h2&gt;

&lt;p&gt;People who will benefit the most from this article are the ones implementing pipelines themselves - be it DevOps and Software engineers. While this article is not a tutorial, yet it contains ideas and snippets for implementing the topics discussed within.&lt;/p&gt;

&lt;p&gt;As we’re talking about how CI/CD can benefit most of the organisations, this article will be approachable to people with many different backgrounds. From developers to operations teams, all the way to folks dealing with delivery and governance - delivery managers, security teams, engineering leadership.&lt;/p&gt;

&lt;h2&gt;
  
  
  The software delivery lifecycle from the CI/CD perspective
&lt;/h2&gt;

&lt;p&gt;Software delivery lifecycle, from the perspective of the CI/CD processes works kind of like this - the developers on the team write and push code changes, have them reviewed, and then automatically tested or otherwise validated, built, and ultimately deployed to a target environment using the CI/CD system, at which point the running software begins to be monitored by the operations teams.&lt;/p&gt;

&lt;p&gt;What technologies are used, where it is deployed, how it is monitored, and by whom, will all depend on the organisation; From Go microservices running on Kubernetes, to static websites with lambda functions, to iOS applications on the App Store, and everything in between.&lt;/p&gt;

&lt;p&gt;But of course there are many more things we do. Software doesn’t begin in an editor, it more often begins as a story somewhere on a backlog or a ticket in a bug tracker. That’s when we actually start thinking about what needs to be built, and how it should work, and for whom (and whether it ultimately does work or not), so why not use CI/CD to do more than just build, validate, and deploy?&lt;/p&gt;

&lt;h2&gt;
  
  
  Expanding the SDLC for the entire organisation
&lt;/h2&gt;

&lt;p&gt;A modern CI/CD platform can work beyond just building testing and deploying code, and instead it can tie together many more people and teams.&lt;/p&gt;

&lt;p&gt;In this section we will look at some of these capabilities, and how connecting to external tools can make us focus more on the software we're building and ultimately build better software.&lt;/p&gt;

&lt;h3&gt;
  
  
  QA, Product, and before work gets made
&lt;/h3&gt;

&lt;p&gt;QA engineers work best with constant access to latest builds to run tests on, as well as run and automate their their own tests. They are often also existing CI/CD users, who write test code and commit to the codebase.&lt;br&gt;
&lt;a href="https://circleci.com/docs/collect-test-data"&gt;We can create build outputs either directly in CircleCI&lt;/a&gt; with &lt;code&gt;store_artifacts&lt;/code&gt; and &lt;code&gt;store_test_results&lt;/code&gt; as in the example below, as well as of course through third party tools such as AppStore Connect, and deploying to test environments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  jobs:
    integration-test:
      docker:
        - image: ...
      steps:
        - checkout
        ...
        - run-test ...
        - store_artifacts:
            path: tested_app_binary
        - store_test_results:
            path: test-results
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Beyond the CI/CD platform itself, QA engineers also work a lot with product management and ticketing software - be it validating the requirements, logging defects, or confirming that updated products do not indeed have the defects anymore.&lt;br&gt;
&lt;a href="https://circleci.com/docs/jira-plugin"&gt;A CI/CD tool can integrate with a PM tool such as Jira&lt;/a&gt;, so that all your builds and deploys are automatically available and referenceable in it. This of course doesn’t only apply to QA engineers but also for product managers.&lt;/p&gt;

&lt;p&gt;You do so by first connecting CircleCI with Jira, and then making sure that you label each commit with the right ticket name - like &lt;code&gt;AB-234&lt;/code&gt;. Finally, as the last step of your deployment or build job - you can invoke the &lt;a href="https://circleci.com/developer/orbs/orb/circleci/jira"&gt;Jira orb&lt;/a&gt;'s notify command, with which you can mark deployments and builds, as in this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;orbs:
    jira: circleci/jira@1.3.1
workflows:
  build:
    jobs:
      - build:
          post-steps:
            - jira/notify 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Notifications
&lt;/h3&gt;

&lt;p&gt;You can also notify your QA engineers and product managers of new releases waiting for their verification through the tools the teams already use - like Slack. &lt;br&gt;
&lt;a href="https://circleci.com/docs/slack-orb-tutorial"&gt;You can install a CI/CD tool as an application in your Slack workspace&lt;/a&gt;, which will also let it to post on your behalf. There are many ways to use it, frpm informing you when certain workflows and jobs are like deployments completed, tests are failing, and also when your workflow is waiting on an action - such as an approval or review by a QA engineer, product manager, and also security engineer, or a delivery manager. Below is an example of a generic deployment notification:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jobs:
  deploy:
    docker:
      ...
    steps:  
      - perform_deployment
      - slack/notify:
            event: pass
            template: success_tagged_deploy_1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Besides Slack there are of course numerous other tools organisations might use, from other instant messaging products to more conventional text messages and e-mails. All of these tend to have APIs which enable similar integrations to be built.&lt;/p&gt;

&lt;h3&gt;
  
  
  Security, Delivery management, and approvals
&lt;/h3&gt;

&lt;p&gt;We have mentioned a few new roles; Security engineers are crucial for all companies to include in their SDLC processes. In an automated CI/CD pipeline, if a security team member doesn’t approve of a deployment after reviewing all necessary documentation and performing the checks, then the deployment should not complete. &lt;/p&gt;

&lt;p&gt;CircleCI offers two very powerful concepts for ensuring access control - approval jobs and contexts. &lt;br&gt;
Approval jobs introduce a manual step in your otherwise automated pipeline, which must be confirmed by an authenticated user in order for the pipeline to proceed. This is very useful for deployments for example.&lt;br&gt;
Contexts in CircleCI can be applied to individual jobs, and can be restricted to specific user groups when for example connected to GitHub. &lt;br&gt;
When using both of them, we can apply contexts to the subsequent job in the workflow after the approval job, in addition to adding user groups to the context itself.&lt;br&gt;
This means that if a non-authenticated person tries to approve this step, the subsequent step will fail with an unauthorized message. I have written a whole blog post on the topic of implementing access control: &lt;a href="https://circleci.com/blog/access-control-cicd/"&gt;https://circleci.com/blog/access-control-cicd/&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;You can of course combine both with what we covered previously - Jira and Slack, to flag and notify the folks required to act on a deployment when it happens.&lt;/p&gt;

&lt;p&gt;Going a few steps further even, once the relevant team member is notified and sent a link to the relevant pipeline or job, why not give them everything they need to make a decision? We expect this it as part of reviewing pull and merge requests after all.&lt;br&gt;
For every testing job, security scan, and other checks we execute these tools can usually gather reports - why not make all reports available in a single report job. That’s possible by passing reports between jobs using a &lt;a href="https://circleci.com/docs/workspaces"&gt;workspace&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jobs:
  security_scan:
    ...
    steps:
      - ...
      - perform-security-scan
      - persist_to_workspace:
          root: workspace
          paths:
            - security-output
  generate_reports:
    ...
    steps:
      - attach_workspace:
          at: /tmp/workspace
      - store_artifacts:
          path: /tmp/workspace/security-output
      - store_artifacts:
          path: /tmp/workspace/some_other_report_output
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this way you can leverage the power of a workspace to create a single point where all the relevant reports are collated. This can be a lightweight job which can save a busy team a lot of time and effort. Besides security engineers the same steps can be taken to inform delivery managers for example, and the manual approval jobs can be chained one after another, so the review steps are taken in order.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ops, deployment reporting, and going beyond the individual dev team
&lt;/h3&gt;

&lt;p&gt;Now the software is approved and being deployed, we can notify the operations teams of a new deployment.&lt;br&gt;
That means that if any defects have been published, we can trace that back to the problematic deployment, revert that feature, and understand the root cause of breakage. Depending on what tools your operations teams use to monitor the software in production, you can call that API using either an orb or directly, which lets you tie a CircleCI pipeline with a deployment event.&lt;/p&gt;

&lt;p&gt;Finally let’s take a few steps back and realise that we’ve only been talking about a single team and the relevant stakeholders. Apart from very small companies (whose engineers are too busy to read this article anyway) that single team doesn't exist in a vacuum, but works with adjacent teams working on different parts of software, sometimes even integrating one another. So not only is there a single software development cycle, there are many.&lt;/p&gt;

&lt;p&gt;This means that implementing the above steps for a single team helps just that - the single team, but far from the wider organisation. People responsible for working across teams, should take on that work to ensure best practices are followed throughout the organisation. This could be the DevOps team that implement the integrations with security, PM, or ops processes, or the head of engineering looking to find way for their teams of engineers to learn and adopt approaches that work from each other. Looking at insights across multiple teams you could consider the pipeline throughput, mean time to recovery, and other metrics covered in our &lt;a href="https://circleci.com/resources/2022-state-of-software-delivery/"&gt;2022 State of Software Delivery report&lt;/a&gt; to understand and identify the best practices within your own organisation, and areas where you can apply these relatively small improvements for the greatest impact in most teams.&lt;/p&gt;

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

&lt;p&gt;We’re not in the world anymore where CI/CD is the sole domain of the development teams.&lt;br&gt;
The role of DevOps teams is to not only work across the Dev organisations but with the wider teams, promoting the virtues of automation and how it benefits other parts of the business. The DevOps and CI/CD engineers are in fact uniquely positioned to bring that automation to more and more people and roles within the org. &lt;/p&gt;

&lt;p&gt;In this article we have looked at a few ways CI/CD can be used to reach more parts of the company, from sending a slack message to your security engineers telling them of a required review, to letting your QA team know that a new bug fix has been deployed and is ready for testing in their ticketing application, to helping your ops team know that a new deployment has indeed started and could potentially have an impact on the users they are seeing.&lt;/p&gt;

&lt;p&gt;If this article has helped you in a way, I would love to know, also if you have any questions or suggestions about it, or ideas for future articles and guides, reach out to me on &lt;a href="https://twitter.com/zmarkan"&gt;Twitter - @zmarkan&lt;/a&gt; or &lt;a href="//mailto:zan@circleci.com"&gt;email me&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>cicd</category>
      <category>circleci</category>
    </item>
    <item>
      <title>Introducing the CircleCI Config SDK</title>
      <dc:creator>Kyle TechSquidTV</dc:creator>
      <pubDate>Mon, 19 Sep 2022 18:00:00 +0000</pubDate>
      <link>https://dev.to/circleci/introducing-the-circleci-config-sdk-43kc</link>
      <guid>https://dev.to/circleci/introducing-the-circleci-config-sdk-43kc</guid>
      <description>&lt;p&gt;We are excited to announce the new CircleCI Config SDK is now available as an open-source TypeScript library. Developers can now write and manage their CircleCI &lt;code&gt;config.yml&lt;/code&gt; files using TypeScript and JavaScript.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/@circleci/circleci-config-sdk"&gt;NPM Package&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/CircleCI-Public/circleci-config-sdk-ts"&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/CircleCI-Public/circleci-config-sdk-ts/wiki"&gt;Docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For developers used to the ecosystem and flexibility of a full-fledged programming language, sometimes YAML can feel limiting or intimidating. With the Config SDK you can define and generate your YAML config from type-safe and annotated JavaScript. You can even take advantage of package management to modularize any portion of your config code for reuse.&lt;/p&gt;

&lt;p&gt;When paired with CircleCI’s &lt;a href="https://circleci.com/docs/dynamic-config"&gt;dynamic configuration&lt;/a&gt;, the Config SDK makes it possible to dynamically build your CI configuration at run-time, allowing you to choose what you want to execute based on any number of factors, such as the status of your Git repo, an external API, or just the day of the week.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;For our example, let’s imagine we manage several Node.js projects that are all built using the same framework and generally require the same CI configuration. So we decided that we want to build a config “template” that all of our projects will use, and which can be centrally managed and updated. We’ll create and publish an NPM package that will generate the perfect config file for all of our Node projects.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Oql4pp_X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://circleci.com/blog/media/2022-09-19-config-sdk.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Oql4pp_X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://circleci.com/blog/media/2022-09-19-config-sdk.gif" alt="Generating a config" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s build the config template package, and then build the pipelines that will use it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;

&lt;p&gt;We’re going to start by creating a standard NPM package. You can use TypeScript or JavaScript, but we’ll use JavaScript in this example for the sake of speed. The example shown here is based on&lt;a href="https://github.com/CircleCI-Public/circleci-config-sdk-ts/wiki/Write-Package"&gt;this page from the repo’s wiki&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Begin by initializing a JavaScript project in a new directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir &amp;lt;your-package-name&amp;gt;

cd &amp;lt;your-package-name&amp;gt;

npm init -y

npm i --save @circleci/circleci-config-sdk

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

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;@circleci/circleci-config-sdk&lt;/code&gt; package will allow us to define a CircleCI config file with JavaScript. While we could simply define a config and export it, we can also take advantage of dynamic config and export a function instead. In our example, we’ll keep it simple and create a config generation function that will take a &lt;code&gt;tag&lt;/code&gt; parameter for our deployments, and a &lt;code&gt;path&lt;/code&gt; parameter to choose where the config file will be exported to.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create the app
&lt;/h2&gt;

&lt;p&gt;Create an &lt;code&gt;index.js&lt;/code&gt; file and import the CircleCI Config SDK package and Node’s &lt;code&gt;fs&lt;/code&gt; package so we can write the config to a file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const CircleCI = require("@circleci/circleci-config-sdk");
const fs = require('fs');

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

&lt;/div&gt;



&lt;p&gt;Next we’ll start building up the components of our config file using the Config SDK. You’ll notice because we are working with a TypeScript-based library, we are able to receive code hints, type definitions, documentation and auto-completion.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create executor
&lt;/h3&gt;

&lt;p&gt;Given we are building a config for our Node.js projects, we’ll begin by defining the &lt;a href="https://circleci.com/docs/using-docker"&gt;Docker executor&lt;/a&gt; our jobs will use. You can pass in the Docker image, resource class, and any other parameters you may want to configure.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Node executor
const dockerNode = new CircleCI.executors.DockerExecutor(
  "cimg/node:lts"
);

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create jobs
&lt;/h3&gt;

&lt;p&gt;We are building up to a workflow that will test our application on every commit, and deploy it when we provide a certain tag. Like our executor, we’ll define these two jobs, both using the executor we just defined and each with a unique set of steps for their respective purposes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Test Job
const testJob = new CircleCI.Job("test", dockerNode);
testJob.addStep(new CircleCI.commands.Checkout());
testJob.addStep(new CircleCI.commands.Run({ command: "npm install &amp;amp;&amp;amp; npm run test" }));

//Deploy Job
const deployJob = new CircleCI.Job("deploy", dockerNode);
deployJob.addStep(new CircleCI.commands.Checkout());
deployJob.addStep(new CircleCI.commands.Run({ command: "npm run deploy" }));

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

&lt;/div&gt;



&lt;p&gt;Jobs can be instantiated with steps or dynamically added to an existing job like shown above. In this overly simplified example, we lack a &lt;a href="https://circleci.com/docs/caching"&gt;caching&lt;/a&gt; step, but you can see how we build up elements of our configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a workflow
&lt;/h2&gt;

&lt;p&gt;With our jobs defined, it’s time to implement them in a workflow and define how they should run. We mentioned earlier that we want the &lt;code&gt;test&lt;/code&gt; job to run on all commits, and the &lt;code&gt;deploy&lt;/code&gt; job to only run on the given tag.&lt;/p&gt;

&lt;p&gt;Now that we are working with top-level components of our config file, let’s finally define a new CircleCI config object, and name the workflow that we will add our jobs to.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Instantiate Config and Workflow
const nodeConfig = new CircleCI.Config();
const nodeWorkflow = new CircleCI.Workflow("node-test-deploy");
nodeConfig.addWorkflow(nodeWorkflow);

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

&lt;/div&gt;



&lt;p&gt;We are not adding any parameters to our testing job because we want to run it on all commits, so we can directly add it to our config object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nodeWorkflow.addJob(testJob);

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

&lt;/div&gt;



&lt;p&gt;For the deploy job, we need to first define the workflow job so that we can add filters to it. We are going to add one filter now which tells CircleCI to ignore this job for all branches, so it doesn’t execute on every commit. We’ll deal with enabling it for a tag in a moment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const wfDeployJob = new CircleCI.workflow.WorkflowJob(deployJob, {requires: ["test"], filters: {branches: {ignore: ".*"}}});
nodeWorkflow.jobs.push(wfDeployJob);

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Export the config generator function
&lt;/h2&gt;

&lt;p&gt;Now that we have everything defined we are ready to create and export the final piece. We are going to create a function which takes in the tag and path parameters we mentioned earlier and will write what we have defined to a new file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
* Exports a CircleCI config for a node project
*/
export default function writeNodeConfig(deployTag, configPath) {
 // next step
}

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

&lt;/div&gt;



&lt;p&gt;In the newly created &lt;code&gt;writeNodeConfig&lt;/code&gt; function, we’ll add the tag filter being passed in here to the deploy job in our workflow and finally write the config to the file supplied by the &lt;code&gt;path&lt;/code&gt; parameter using the &lt;code&gt;generate&lt;/code&gt; function on the config object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
* Exports a CircleCI config for a node project
*/
export default function writeNodeConfig(deployTag, configPath) {
  wfDeployJob.parameters.filters.tags = {only: deployTag}
  fs.writeFile(configPath, nodeConfig.generate(), (err) =&amp;gt; {
    if (err) {
      console.error(err);
      return
    }
  })
}

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

&lt;/div&gt;



&lt;p&gt;Here is the full source code, which you can also find &lt;a href="https://github.com/CircleCI-Public/circleci-config-sdk-ts/wiki/Write-Package"&gt;in the wiki&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const CircleCI = require("@circleci/circleci-config-sdk");
const fs = require('fs');

// Node executor
const dockerNode = new CircleCI.executors.DockerExecutor(
  "cimg/node:lts"
);

// Test Job
const testJob = new CircleCI.Job("test", dockerNode);
testJob.addStep(new CircleCI.commands.Checkout());
testJob.addStep(new CircleCI.commands.Run({ command: "npm install &amp;amp;&amp;amp; npm run test" }));

//Deploy Job
const deployJob = new CircleCI.Job("deploy", dockerNode);
deployJob.addStep(new CircleCI.commands.Checkout());
deployJob.addStep(new CircleCI.commands.Run({ command: "npm run deploy" }));

//Instantiate Config and Workflow
const nodeConfig = new CircleCI.Config();
const nodeWorkflow = new CircleCI.Workflow("node-test-deploy");
nodeConfig.addWorkflow(nodeWorkflow);

//Add Jobs. Add filters to deploy job
nodeWorkflow.addJob(testJob);
const wfDeployJob = new CircleCI.workflow.WorkflowJob(deployJob, {requires: ["test"], filters: {branches: {ignore: ".*"}}});
nodeWorkflow.jobs.push(wfDeployJob);

/**
* Exports a CircleCI config for a node project
*/
export default function writeNodeConfig(deployTag, configPath) {
  wfDeployJob.parameters.filters.tags = {only: deployTag};
  fs.writeFile(configPath, nodeConfig.generate(), (err) =&amp;gt; {
    if (err) {
      console.error(err);
      return
    }
  });
}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Publish the package
&lt;/h2&gt;

&lt;p&gt;With your &lt;code&gt;index.js&lt;/code&gt; file completed with the &lt;code&gt;writeNodeConfig&lt;/code&gt; function exported, it’s time to &lt;a href="https://docs.npmjs.com/creating-and-publishing-unscoped-public-packages"&gt;publish the package&lt;/a&gt; to your package repository of choice, such as NPM or GitHub.&lt;/p&gt;

&lt;p&gt;When complete, you should be able to import your package in other projects, just like we imported &lt;code&gt;@circleci/circleci-config-sdk&lt;/code&gt; earlier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a CI pipeline
&lt;/h2&gt;

&lt;p&gt;You now have a published NPM package that can generate a CircleCI config file. We can use CircleCI’s dynamic configuration to pull in this package at run-time and dynamically run our generated config file. We can replicate this basic template across our many similar NodeJS projects, and when we want to update or change our config, we will be able to simply update the package we created.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create config.yml
&lt;/h3&gt;

&lt;p&gt;As usual, our CircleCI project will require a &lt;code&gt;.circleci&lt;/code&gt; directory and a &lt;code&gt;config.yml&lt;/code&gt; file inside. The config file in this case will be a basic template used in all of our projects which simply tells CircleCI to enable the dynamic configuration feature for the current pipeline, generate the new config file, and run it. We will also create a &lt;code&gt;dynamic&lt;/code&gt; directory that we will use later.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;└── .circleci/
    ├── dynamic/
    └── config.yml` \

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

&lt;/div&gt;



&lt;p&gt;Use the following &lt;a href="https://github.com/CircleCI-Public/circleci-config-sdk-ts/blob/main/sample/01-dynamic-workflow-javascript/.circleci/config.yml"&gt;example configuration file&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: 2.1
orbs:
  continuation: circleci/continuation@0.3.1
  node: circleci/node@5.0.2
setup: true
jobs:
  generate-config:
    executor: node/default
    steps:
      - checkout
      - node/install-packages:
          app-dir: .circleci/dynamic
      - run:
          name: Generate config
          command: node .circleci/dynamic/index.js
      - continuation/continue:
          configuration_path: ./dynamicConfig.yml
workflows:
  dynamic-workflow:
    jobs:
      - generate-config

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

&lt;/div&gt;



&lt;p&gt;You can find this config file and other examples in the &lt;a href="https://github.com/CircleCI-Public/circleci-config-sdk-ts/wiki/Write-Dynamic-Config-App"&gt;Wiki&lt;/a&gt; on GitHub.&lt;/p&gt;

&lt;p&gt;This config is a boilerplate responsible for executing our package which contains the “real” logic we want to execute.&lt;/p&gt;

&lt;p&gt;Notice the &lt;code&gt;setup&lt;/code&gt; key is set to &lt;code&gt;true&lt;/code&gt;, enabling dynamic config for the pipeline. Using the Node orb, we install a Node app located in &lt;code&gt;.circleci/dynamic&lt;/code&gt; (we’ll come back to this), and run the &lt;code&gt;.circleci/dynamic/index.js&lt;/code&gt; in Node. This is what will use the package we wrote earlier and create a new config file at &lt;code&gt;./dynamicConfig.yml&lt;/code&gt;, which will finally be executed by the &lt;code&gt;continuation&lt;/code&gt; orb.&lt;/p&gt;

&lt;p&gt;We will use a config like this one in all of our Node projects, and it is unlikely to need to be updated or changed often. Rather than modifying this config, we update the package we created earlier.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create the config app
&lt;/h3&gt;

&lt;p&gt;The last thing to do is build our “Config application”. This is the app responsible for implementing our package and acts as the source of our “real” config we plan on executing. Because in this example we have outsourced the majority of the logic of our config to an external package, in this example, our config app is mostly boilerplate as well.&lt;/p&gt;

&lt;p&gt;Change directory into &lt;code&gt;.circleci/dynamic&lt;/code&gt; where we will set up our application. Initialize a new repository and install the package you published previously.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm init -y

npm i &amp;lt;your-package-name&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;After running these two commands, you should have a &lt;code&gt;package.json&lt;/code&gt; file with a dependency showing your package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"dependencies": {
  "my-circleci-node-config": "^1.0.0",
}

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

&lt;/div&gt;



&lt;p&gt;You can &lt;a href="https://docs.npmjs.com/about-semantic-versioning#using-semantic-versioning-to-specify-update-types-your-package-can-accept"&gt;modify the semantic version string&lt;/a&gt; to dictate what version of your package should be pulled at run time. This means, you could update your &lt;code&gt;my-circleci-node-config&lt;/code&gt; package and, if you choose, have all of your CircleCI projects that utilize this package immediately pick up these changes the next time your CI pipeline is triggered.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not Recommended:&lt;/strong&gt; Say you always wanted to pull the latest version of the custom dependency you have created, you could use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"dependencies": {
  "my-circleci-node-config": "x",
},

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

&lt;/div&gt;



&lt;p&gt;To be safer, pull in only minor and patch updates, not major releases.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"dependencies": {
  "my-circleci-node-config": "1.x",
},

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

&lt;/div&gt;



&lt;p&gt;Finally, utilize your custom package in the &lt;code&gt;.circleci/dynamic.index.js.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Our package exports a function named &lt;code&gt;writeNodeConfig&lt;/code&gt; which takes in the value of the &lt;code&gt;tag&lt;/code&gt; we want for triggering deployments, and the &lt;code&gt;path&lt;/code&gt; we want to export the config to. We know the path from earlier in our config.yml, we set to be &lt;code&gt;./dynamicConfig.yml&lt;/code&gt;, because we are in the &lt;code&gt;dynamic&lt;/code&gt; directory, we will prepend &lt;code&gt;..&lt;/code&gt;. For the tag, we’ll use a generic regex string &lt;code&gt;v.*&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import writeNodeConfig from '&amp;lt;your/package&amp;gt;';

writeNodeConfig("v.*", "../dynamicConfig.yml")

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

&lt;/div&gt;



&lt;p&gt;That is our entire application. We simply need to pull whichever version of our package we desire and invoke it to generate our config file from the template we created in the package.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running the pipeline
&lt;/h2&gt;

&lt;p&gt;To recap, we have a boilerplate &lt;code&gt;config.yml&lt;/code&gt; file which instructs CircleCI to enable dynamic configuration, and uses Node.js to build a new config file at run-time. The Node app responsible for building our new config uses a package dependency which contains the “template” of our desired config. We can now use this package in many different projects and update it centrally. Our projects can either pull in the latest version of this package by specifying an &lt;code&gt;x&lt;/code&gt; in the package.json, or we can use tools like dependabot to open a pull request automatically to all of our projects that use this package when it is updated.&lt;/p&gt;

&lt;p&gt;With dynamic configuration and the Config SDK together, the possibilities are endless. The tutorial above was based on &lt;a href="https://github.com/CircleCI-Public/circleci-config-sdk-ts/wiki/Write-Package"&gt;this page from the wiki&lt;/a&gt; on GitHub. Check out the rest of our &lt;a href="https://github.com/CircleCI-Public/circleci-config-sdk-ts/wiki"&gt;wiki&lt;/a&gt; and &lt;a href="https://circleci-public.github.io/circleci-config-sdk-ts/"&gt;documentation&lt;/a&gt; for even more examples of interesting things you can do with the Config SDK.&lt;/p&gt;

&lt;p&gt;We’d love to hear from you and see how you utilize the Config SDK in your own pipelines. Connect with us on &lt;a href="https://twitter.com/CircleCI"&gt;Twitter&lt;/a&gt;, say hello in our &lt;a href="https://discuss.circleci.com/t/circleci-config-sdk-now-g-a/45457"&gt;discussion forum&lt;/a&gt;, or chat with us on &lt;a href="https://discord.gg/5dUX4FstW2"&gt;Discord&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>circleci</category>
      <category>cicd</category>
      <category>sdk</category>
      <category>pipelines</category>
    </item>
    <item>
      <title>Continuous integration for Android projects</title>
      <dc:creator>Zan Markan</dc:creator>
      <pubDate>Fri, 26 Aug 2022 19:00:00 +0000</pubDate>
      <link>https://dev.to/circleci/continuous-integration-for-android-projects-51l7</link>
      <guid>https://dev.to/circleci/continuous-integration-for-android-projects-51l7</guid>
      <description>&lt;p&gt;CircleCI is popular among Android developers for several reasons: it’s quick to get started, fast to execute your builds with high parallelism, (whether native, cross- or multi-platform), and even supports running Android emulators right from CircleCI with our Android machine images.&lt;/p&gt;

&lt;p&gt;This article will show you how to build and test Android applications for an example project on the CircleCI platform. The full source code is available &lt;a href="https://github.com/CircleCI-Public/android-testing-circleci-examples"&gt;on GitHub - CircleCI-Public/android-testing-circleci-examples&lt;/a&gt;, and you can find the working pipelines &lt;a href="https://app.circleci.com/pipelines/github/CircleCI-Public/android-testing-circleci-examples"&gt;in the corresponding CircleCI project&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To get the most out of this article you should have&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Working knowledge of Android development&lt;/li&gt;
&lt;li&gt;Familiarity with Android tooling and testing frameworks&lt;/li&gt;
&lt;li&gt;Ability to use the Gradle build system&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What’s available in CircleCI for Android
&lt;/h2&gt;

&lt;p&gt;We have made a few tools available for you for building Android:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker image&lt;/li&gt;
&lt;li&gt;Android machine image&lt;/li&gt;
&lt;li&gt;Android orb&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Docker image
&lt;/h3&gt;

&lt;p&gt;The Docker image is the main executor teams use. It runs in a Docker container and so is very fast to start, and contains everything you might need to get started building Android projects. The full list of preinstalled tools can be found &lt;a href="https://circleci.com/developer/images/image/cimg/android"&gt;in the documentation&lt;/a&gt;. The images also ship with variants that have Node.js, the Android NDK, and browser tools preinstalled.&lt;/p&gt;

&lt;h3&gt;
  
  
  Machine image
&lt;/h3&gt;

&lt;p&gt;The biggest change is the &lt;a href="https://circleci.com/developer/machine/image/android"&gt;new Android machine image&lt;/a&gt;. This is a virtual machine image, so takes a bit more time than the Docker image mentioned above, but it contains all the tools you may need to build your Android applications, including the SDK, Google Cloud tools for Firebase, &lt;a href="https://dev.to/features/python/"&gt;Python&lt;/a&gt;, Node.JS, and Fastlane. The biggest change however is the support for nested virtualisation, which allows you to run Android emulators from within this machine image.&lt;/p&gt;

&lt;p&gt;Android machine images support nested virtualization, which allow running the x86 emulators in CircleCI jobs. If you have been developing for Android since the early years of the platform, you may remember that emulators were very slow. Then x86 emulators started supporting Intel’s Hyper-V hypervisors, which lets the emulator use the resources of the host computer directly. Using resource directly like this makes the emulators able to run much, much more smoothly and quickly.&lt;/p&gt;

&lt;p&gt;For a long time, support was confined to our local hardware. Limited support on CircleCI slowed down emulators and made it difficult to run UI tests. Nested virtualization solves this problem by adding support for fast emulation to a massively reproducible CI/CD environment, making all the benefits of that available.&lt;/p&gt;

&lt;h3&gt;
  
  
  Android Orb
&lt;/h3&gt;

&lt;p&gt;Finally there is the CircleCI Android orb which provides easy access to both images as executors, as well as handy jobs and commands for installing SDKs, running emulators, caching, testing, and more. You can read more about what the orb offers in the orb docs &lt;a href="https://circleci.com/developer/orbs/orb/circleci/android"&gt;at this link&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing the Android CI demo project
&lt;/h2&gt;

&lt;p&gt;I have created a &lt;a href="https://github.com/zmarkan/android-testing-circleci-examples"&gt;demo project&lt;/a&gt;, which is a fork of Google’s own Android Testing Codelab sources. The Codelab is a simple TO-DO list manager application and contains a combination of unit tests and instrumentation tests, with and without the UI. The project is also available to view &lt;a href="https://app.circleci.com/pipelines/github/zmarkan/android-testing-circleci-examples"&gt;on CircleCI&lt;/a&gt;. If you open it in Android Studio, make sure to switch to the &lt;code&gt;Project&lt;/code&gt; view. Project view lets you view the &lt;code&gt;.circleci/config.yml&lt;/code&gt; file we will be reviewing.&lt;/p&gt;

&lt;p&gt;The project has a single &lt;code&gt;app&lt;/code&gt; module, with the default &lt;code&gt;debug&lt;/code&gt; and &lt;code&gt;release&lt;/code&gt; variants. The &lt;code&gt;test&lt;/code&gt; directory contains unit tests, while the &lt;code&gt;androidTest&lt;/code&gt; directory contains instrumentation tests. The full CircleCI configuration is included, and I will be referring to it in this article. The configuration is located in &lt;code&gt;.circleci/config.yml&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building and testing CI for the sample Android app
&lt;/h2&gt;

&lt;p&gt;Our CI process must do three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run unit tests inside a virtual machine&lt;/li&gt;
&lt;li&gt;Run instrumentation tests on the emulator&lt;/li&gt;
&lt;li&gt;Build a release version of the app&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We will run unit tests and instrumentation tests side by side. If both types of tests are successful, we can assemble the release build. We will also add a condition to continue on to the release build &lt;em&gt;only&lt;/em&gt; if new work has been commited to the “main” branch, and only following successful emulator tests on every Android version from 23 to 30. When our build meets this condition, we will have solid assurance that our application will work on many different Android devices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;em&gt;As I mentioned before, everything from this point on will refer to the CircleCI configuration file in &lt;code&gt;.circleci/config.yml&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Using the CircleCI Android orb
&lt;/h3&gt;

&lt;p&gt;The first step for creating our &lt;a href="https://dev.to/ronpowelljr/what-is-a-ci-cd-pipeline-4lc5-temp-slug-7512512"&gt;CI pipeline&lt;/a&gt; is to use the Android orb, which contains many of the steps already pre-written for you. The latest version is available in the &lt;a href="https://circleci.com/developer/orbs/orb/circleci/android"&gt;orb docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After the orb is defined, the script specifies these jobs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;unit-test&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;android-test&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;release-build&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One workflow, &lt;code&gt;test-and-build&lt;/code&gt;, is also included.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: 2.1

orbs:
  android: "2.1.2"

jobs:
  unit-test:
    ...
  android-test:
    ...
  release-build:
    ...
    # We'll get to this later

workflows:
  test-and-build:
    ...
  # We'll get to this later

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Running unit tests
&lt;/h3&gt;

&lt;p&gt;Our &lt;code&gt;unit-test&lt;/code&gt; job contains an executor from the Android orb: &lt;code&gt;android/android-docker&lt;/code&gt;. As mentioned this runs it in a Docker container which is extremely fast to start up.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;steps&lt;/code&gt; stanza, there are a few things to note. First, we run &lt;code&gt;android/restore-gradle-cache&lt;/code&gt; Gradle cache helps store our dependencies and build artifacts. After running the test command, we also run &lt;code&gt;android/save-gradle-cache&lt;/code&gt; and &lt;code&gt;android/save-build-cache&lt;/code&gt; to make sure subsequent builds run faster by using the cache. These all come from the Android orb, as indicated by the prefix &lt;code&gt;android/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We could also modify what gets cached by passing the &lt;code&gt;find-args&lt;/code&gt; parameter to &lt;code&gt;restore-gradle-cache&lt;/code&gt;. A great advanced example can be found &lt;a href="https://github.com/owntracks/android/blob/59f13afa93a27904e739493d96af64ab36f783eb/.circleci/continue-config.yml#L17-L44"&gt;in this open source project&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The main build step happens in the &lt;code&gt;android/run-tests&lt;/code&gt; command, where we call &lt;code&gt;./gradlew testDebug&lt;/code&gt; within a &lt;code&gt;test-command&lt;/code&gt; parameter. This command runs all unit tests for the &lt;code&gt;debug&lt;/code&gt; build variant. As a bonus, this command comes with a default retry value to help you avoid test flakiness.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jobs:
  unit-test:
    executor:
      name: android/android-docker
      tag: 2022.08.1
    steps:
      - checkout
      - android/restore-gradle-cache
      - android/run-tests:
          test-command: ./gradlew testDebug
      - android/save-gradle-cache
      ...

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Running Android tests on the emulator
&lt;/h3&gt;

&lt;p&gt;Our &lt;code&gt;android-test&lt;/code&gt; job is the one that uses the new Android emulator capability. The job uses the same Android machine executor as the &lt;code&gt;build&lt;/code&gt; job. All subsequent jobs will use the same executor, and the cache restoration steps are also the same.&lt;/p&gt;

&lt;p&gt;Emulator requires us to run on a machine image, so we specified &lt;code&gt;android/android-machine&lt;/code&gt; as the executor. To improve build times, we specify the &lt;code&gt;resource-class&lt;/code&gt; as xlarge. You can also run it on a &lt;code&gt;large&lt;/code&gt; executor, but I have found that the lack of resources causes slower build times. I recommend that you do some experimentation on your own to find the right size executor for your project.&lt;/p&gt;

&lt;p&gt;The next step is even shorter; we need just the &lt;code&gt;android/start-emulator-and-run-tests&lt;/code&gt; command. This command does exactly what it says: it starts the specified emulator and runs the tests. We pass in the &lt;code&gt;test-command&lt;/code&gt; again as the parameter (it uses the &lt;code&gt;android/run-tests&lt;/code&gt; command). The &lt;code&gt;system-image&lt;/code&gt; is the fully qualified Android emulator system image. We currently bundle our Android machine images back to SDK version 23. You could install more by using the &lt;code&gt;sdkmanager&lt;/code&gt; tool.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jobs:
  android-test:
    executor:
      name: android/android-machine
      resource-class: xlarge
    steps:
      - checkout
      - android/start-emulator-and-run-tests:
          test-command: ./gradlew connectedDebugAndroidTest
          system-image: system-images;android-30;google_apis;x86
      ...

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

&lt;/div&gt;



&lt;p&gt;You could code all the emulator setup steps manually using the commands specified in the Android orb: &lt;code&gt;create-avd&lt;/code&gt;, &lt;code&gt;start-emulator&lt;/code&gt;, &lt;code&gt;wait-for-emulator&lt;/code&gt;, and &lt;code&gt;run-tests&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Storing the test results
&lt;/h3&gt;

&lt;p&gt;There is more to testing than just running the tests, as we can get a lot of value from seeing exactly what has failed from right inside the CircleCI dashboard. For that we can use &lt;code&gt;store_test_results&lt;/code&gt; functions built into the CircleCI platform, which will show our passing (or failing) builds.&lt;/p&gt;

&lt;p&gt;The steps differ slightly between unit tests and instrumentation tests, as each of their respective Gradle tasks stores the tests in a different place. For unit tests the tests will be in &lt;code&gt;app/build/test-results&lt;/code&gt;, and for instrumentation tests they will be in &lt;code&gt;app/build/outputs/androidTest-results&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We suggest you create a new &lt;code&gt;Save test results&lt;/code&gt; step, which uses the &lt;code&gt;find&lt;/code&gt; utility and copies all test results files into a common location - like &lt;code&gt;test-results/junit&lt;/code&gt;, and then store it from there. Also make sure to add the &lt;code&gt;when: always&lt;/code&gt; parameter to the step, so the step runs regardless of whether the tests above succeed or fail.&lt;/p&gt;

&lt;h3&gt;
  
  
  Storing unit tests
&lt;/h3&gt;

&lt;p&gt;For this project, we want the XML based results. Calling &lt;code&gt;store_artifacts&lt;/code&gt; makes those results parseable on the CircleCI platform. You can also store the HTML output if you prefer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
- android/run-tests:
  test-command: ./gradlew testDebug
- run:
    name: Save test results
    command: |
        mkdir -p ~/test-results/junit/
        find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/test-results/junit/ \;
    when: always
- store_test_results:
    path: ~/test-results
- store_artifacts:
    path: ~/test-results/junit

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Storing instrumentation tests
&lt;/h3&gt;

&lt;p&gt;There are different regex command for different test types. The rest of the steps to store test results are identical to the unit tests example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- android/start-emulator-and-run-tests:
        test-command: ./gradlew connectedDebugAndroidTest
        system-image: &amp;lt;&amp;lt; parameters.system-image &amp;gt;&amp;gt;
    - run:
        name: Save test results
        command: |
          mkdir -p ~/test-results/junit/
          find . -type f -regex ".*/build/outputs/androidTest-results/.*xml" -exec cp {} ~/test-results/junit/ \;
        when: always
    - store_test_results:
        path: ~/test-results
    - store_artifacts:
        path: ~/test-results/junit

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Making a release build and storing the artifacts
&lt;/h3&gt;

&lt;p&gt;For this project, we need to store the application we are building. To complete this part of the process, we use the &lt;code&gt;release-build&lt;/code&gt; job, which has two parts of note. A &lt;code&gt;run&lt;/code&gt; step calls &lt;code&gt;./gradlew assembleRelease&lt;/code&gt;. Then, &lt;code&gt;store_artifacts&lt;/code&gt; points to where the built APK is. For a full CI/CD project, you could sign and upload that APK to a beta distribution service. You could even create a release on Play Store with Fastlane. Both of those activties are out of scope for this article, though.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jobs:
  ...
  release-build:
    executor:
      name: android/android-machine
      resource-class: xlarge
    steps:
      - checkout
      - android/restore-gradle-cache
      - android/restore-build-cache
      - run:
          name: Assemble release build
          command: |
            ./gradlew assembleRelease
      - store_artifacts:
          path: app/build/outputs/apk/release

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Running tests on multiple Android versions simultaneously
&lt;/h3&gt;

&lt;p&gt;The Android platform evolves all the time, and each version has its own bugs and pecularities. I am sure you have encountered some of them. A good way to avoid undefined behaviour across different versions of Android is to test on as many of them as you can. The CircleCI job matrix feature makes it easier to run jobs on multiple versions.&lt;/p&gt;

&lt;p&gt;To use the job matrix, add a parameter to the job you want to test on multiple versions. Our &lt;code&gt;android-test&lt;/code&gt; job does that using the &lt;code&gt;system-image&lt;/code&gt; parameter. We have also specified a default value for the parameter, so you can run the job without it.&lt;/p&gt;

&lt;p&gt;To use the parameter, specify where you need its value by placing it within pairs of angle brackets - &lt;code&gt;&amp;lt;&amp;lt; &amp;gt;&amp;gt;&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; android-test:
    parameters: # this is a parameter
      system-image:
        type: string
        default: system-images;android-30;google_apis;x86
    executor:
      name: android/android-machine
      resource-class: xlarge
    steps:
      - checkout
      - android/start-emulator-and-run-tests:
          test-command: ./gradlew connectedDebugAndroidTest
          system-image: &amp;lt;&amp;lt; parameters.system-image &amp;gt;&amp;gt; # parameter being used

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

&lt;/div&gt;



&lt;p&gt;To pass values to the parameter in the workflows, use the &lt;code&gt;matrix&lt;/code&gt; parameter of the job we are calling.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;workflows:
  jobs:
  ...
  - android-test:
      matrix:
        alias: android-test-all
        parameters:
          system-image:
            - system-images;android-30;google_apis;x86
            - system-images;android-29;google_apis;x86
            - system-images;android-28;google_apis;x86
            - system-images;android-27;google_apis;x86
            - system-images;android-26;google_apis;x86
            - system-images;android-26;google_apis;x86
            - system-images;android-26;google_apis;x86
            - system-images;android-26;google_apis;x86
      name: android-test-&amp;lt;&amp;lt;matrix.system-image&amp;gt;&amp;gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Making each run faster by caching
&lt;/h3&gt;

&lt;p&gt;Alongside building our application, installing dependencies, and running tests, we often want to leverage cache as well. This allows us to do repeated tasks less often. Android and especially Gradle provides an excellent mechanism for this - &lt;a href="https://docs.gradle.org/current/userguide/build_cache.html"&gt;the Gradle Build cache&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This lets you skip pre-built parts of the application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Choosing what runs when
&lt;/h3&gt;

&lt;p&gt;During development, we create many commits, and developers should be encouraged to push them to a remote repository as often as possible. Each one of these committs creates a new CI/CD build, though, and we might not need every test run on all possible devices for a single commit. On the other hand, if the &lt;code&gt;main&lt;/code&gt; branch is our primary source of truth, we want to run as many tests on that as possible, to ensure it is always working as intended. We might want to initate the release deployment only on &lt;code&gt;main&lt;/code&gt;, and not on any other branch.&lt;/p&gt;

&lt;p&gt;We can use CircleCI’s &lt;code&gt;requires&lt;/code&gt; and &lt;code&gt;filters&lt;/code&gt; stanzas to define workflows that fit our process. Our &lt;code&gt;release-build&lt;/code&gt; job &lt;code&gt;requires&lt;/code&gt; the &lt;code&gt;unit-test&lt;/code&gt; jobs. That means the &lt;code&gt;release-build&lt;/code&gt; is put in the queue until all the &lt;code&gt;unit-test&lt;/code&gt; jobs have passed. Only then is the &lt;code&gt;release-build&lt;/code&gt; job run.&lt;/p&gt;

&lt;p&gt;We can use &lt;code&gt;filters&lt;/code&gt; to set up logical rules for running a particular job only on a specific branch or git tag. For example, we have a filter for our &lt;code&gt;main&lt;/code&gt; branch that runs the &lt;code&gt;android-test&lt;/code&gt; with a full matrix of emulators. In another example, the &lt;code&gt;release&lt;/code&gt; build triggers only on &lt;code&gt;main&lt;/code&gt;, and only when its two required jobs have run successfully.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;workflows:
  test-and-build:
    jobs:
      - unit-test
      - android-test: # Commits to any branch - skip matrix of devices
          filters:
            branches:
              ignore: main
      - android-test: # Commits to main branch only - run full matrix
          matrix:
            alias: android-test-all
            parameters:
              system-image:
                - system-images;android-30;google_apis;x86
                - system-images;android-29;google_apis;x86
                - system-images;android-28;google_apis;x86
                - system-images;android-27;google_apis;x86
                - system-images;android-26;google_apis;x86
                - system-images;android-25;google_apis;x86
                - system-images;android-24;google_apis;x86
                - system-images;android-23;google_apis;x86
          name: android-test-&amp;lt;&amp;lt;matrix.system-image&amp;gt;&amp;gt;
          filters:
            branches:
              only: main 
      - release-build:
          requires:
            - unit-test
            - android-test-all
          filters:
            branches:
              only: main # Commits to main branch

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Improving your Android application CI process
&lt;/h2&gt;

&lt;p&gt;The steps I have described in this article are only a beginning. There are many ways you can improve the flow. Here are just a handful of ideas:&lt;/p&gt;

&lt;h3&gt;
  
  
  Build once, run many times
&lt;/h3&gt;

&lt;p&gt;If you are an experienced Android developer you know that the &lt;code&gt;connectedAndroidTest&lt;/code&gt; will always run the entire build process from the start. Using CircleCI, we could build the entire application and tests once, pass the artifacts down to following jobs, and simply run the tests on the emulators. This process could potentially save several build minutes per job run.&lt;/p&gt;

&lt;p&gt;To make this happen, add three commandline steps in each emulator run: install the app, install the instrumentation app, and run the instrumentation tests. For our application, we would enter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;adb install app/build/outputs/apk/debug/app-debug.apk  
adb install app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk  
adb shell am instrument -w com.example.android.architecture.blueprints.reactive.test/androidx.test.runner.AndroidJUnitRunner 

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

&lt;/div&gt;



&lt;p&gt;It is true that this code sends output to the the command line. That is not the tidy test output that Gradle provides. If you are motivated to make the output look better, &lt;a href="https://stackoverflow.com/questions/33896315/how-to-retrieve-test-results-when-using-adb-shell-am-instrument"&gt;this StackOverflow topic&lt;/a&gt; might help you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Running on real devices
&lt;/h3&gt;

&lt;p&gt;Emulators are one tool, but real world devices are often (sadly) much different. There is nothing that can replace a real-world device test. For that you can use a solution offering real devices in the cloud, like Sauce Labs or Firebase Test Lab.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deploying to beta testers, and releasing the application
&lt;/h3&gt;

&lt;p&gt;This build and test example project is just one part of a wider CI/CD story. You can take your CI/CD process much further. For example, you can automatically release new versions of your applications right to the Play Store. CircleCI has a handful of guides to help you. &lt;a href="https://dev.to/ronpowelljr/continuous-integration-and-deployment-for-android-apps-with-fastlane-36j7-temp-slug-5167162"&gt;This tutorial&lt;/a&gt; is a great place to start. The &lt;a href="https://docs.fastlane.tools/getting-started/android/release-deployment/"&gt;official Fastlane documentation&lt;/a&gt; is another helpful resource.&lt;/p&gt;

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

&lt;p&gt;In this article, I described building an Android application with CircleCI, and testing it. For our sample project, we used unit tests and a matrix of Android platform emulators, using the new CircleCI Android orb and machine images. We also touched on how to store and display test results, and how to orchestrate workflows to run tests will not give us the tidy test output that Gradle provides, and all output is on a portion of devices.&lt;/p&gt;

&lt;p&gt;Do let me know if there is another Android topic you might want me to explore, either in an article or a live stream. Contact me on &lt;a href="https://twitter.com/zmarkan/"&gt;Twitter - @zmarkan&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>circleci</category>
      <category>android</category>
      <category>cicd</category>
    </item>
    <item>
      <title>Implementing access control policies in CI/CD pipelines</title>
      <dc:creator>Zan Markan</dc:creator>
      <pubDate>Fri, 29 Apr 2022 12:00:00 +0000</pubDate>
      <link>https://dev.to/circleci/implementing-access-control-policies-in-cicd-pipelines-1mc5</link>
      <guid>https://dev.to/circleci/implementing-access-control-policies-in-cicd-pipelines-1mc5</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This tutorial covers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Protected branches and security groups in GitHub&lt;/li&gt;
&lt;li&gt;Using contexts in CircleCI&lt;/li&gt;
&lt;li&gt;Setting up approval jobs in CircleCI&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;Imagine yourself in this situation: You are a motivated and skilled DevOps or DevEx engineer. You have a plan to implement automated, complete &lt;a href="https://dev.to/ronpowelljr/what-is-a-ci-cd-pipeline-4lc5-temp-slug-7512512"&gt;CI/CD pipelines&lt;/a&gt;. You know how to do it, and you know how the extra productivity and automation will benefit your team and the whole company. But the project is never approved, because of security concerns.&lt;/p&gt;

&lt;p&gt;Many organizations, especially those in regulated industries, have strict requirements for releasing their software, and rightfully so. Who can trigger a release, and when, under what conditions, and what specific checks are required before release can go ahead must be tightly controlled, auditable, and reversible.&lt;/p&gt;

&lt;p&gt;These kinds of complicated processes often require a dedicated delivery manager to collect and present all relevant feature briefs, test data, security assessment, and rollback plans to a committee of decision makers in the company. That group can give the delivery manager the green light to deploy, often also on a specific schedule.&lt;/p&gt;

&lt;p&gt;There is another approach. You can set up effective and fully automated CI/CD pipelines that include all the checks a human delivery manager and approval committee can complete. This tutorial will show you ways to create fine grained access control for your pipelines. You can use these methods for strictly regulated internal company projects for the enterprise, as well as for popular open source projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;This tutorial assumes you have experience with CI/CD pipelines, and ideally with CircleCI. To implement the steps covered you will also need admin access to your GitHub and CircleCI organizations (and accounts for both services).&lt;/p&gt;

&lt;p&gt;If you do not have administrator access to a GitHub organization, you can create a free one in GitHub and use it with a free CircleCI account.&lt;/p&gt;

&lt;h2&gt;
  
  
  Access control in CI/CD pipelines in enterprise projects
&lt;/h2&gt;

&lt;p&gt;For an enterprise organization it is vital that existing checks are followed and communicated well. The process often includes manual checks of supporting documentation and the potential impact to business before a release can continue. I will guide you through implementing a pipeline that executes a number of verification steps automatically, and continues with deployment to production &lt;em&gt;only&lt;/em&gt; after the dedicated delivery manager manually approves the process.&lt;/p&gt;

&lt;p&gt;To implement access control you will need to set up a few things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Protected branches in GitHub&lt;/li&gt;
&lt;li&gt;Security groups in GitHub&lt;/li&gt;
&lt;li&gt;Contexts in CircleCI&lt;/li&gt;
&lt;li&gt;Approval jobs in CircleCI&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Protected branches
&lt;/h3&gt;

&lt;p&gt;Setting up a protected branch is the first step to setting up access control. A protected branch prohibits team members from pushing code directly to that branch, and instead forces all changes to go through the pull request (PR) process. Commonly you would protect the branch you use to create releases from; &lt;code&gt;main&lt;/code&gt; for example. You can toggle protected branches in the settings for your repo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8974eWIQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://production-cci-com.imgix.net/blog/media/2022-04-20-access-control-protected-branch.png%3Fixlib%3Drb-3.2.1%26w%3D2000%26auto%3Dformat%26fit%3Dmax%26q%3D60%26ch%3DDPR%252CWidth%252CViewport-Width%252CSave-Data" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8974eWIQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://production-cci-com.imgix.net/blog/media/2022-04-20-access-control-protected-branch.png%3Fixlib%3Drb-3.2.1%26w%3D2000%26auto%3Dformat%26fit%3Dmax%26q%3D60%26ch%3DDPR%252CWidth%252CViewport-Width%252CSave-Data" alt="Setting up protected branches in GitHub" width="800" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also specify rules and exceptions, such as review requirements, checks that need to pass before merging, history rules, and much more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lCR8yJa7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://production-cci-com.imgix.net/blog/media/2022-04-20-access-control-protected-branch-rules.png%3Fixlib%3Drb-3.2.1%26w%3D2000%26auto%3Dformat%26fit%3Dmax%26q%3D60%26ch%3DDPR%252CWidth%252CViewport-Width%252CSave-Data" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lCR8yJa7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://production-cci-com.imgix.net/blog/media/2022-04-20-access-control-protected-branch-rules.png%3Fixlib%3Drb-3.2.1%26w%3D2000%26auto%3Dformat%26fit%3Dmax%26q%3D60%26ch%3DDPR%252CWidth%252CViewport-Width%252CSave-Data" alt="Branch protection rules" width="800" height="923"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my example I set up my &lt;code&gt;main&lt;/code&gt; branch as a protected branch that requires a review and PR to pass.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting up security groups
&lt;/h3&gt;

&lt;p&gt;If a user without the correct context privileges triggers a CircleCI pipeline (for example, with a commit), then the job that requires that context will be marked as 403 (unauthorized).&lt;/p&gt;

&lt;p&gt;In our organization we will set up two security groups: &lt;code&gt;development-leads&lt;/code&gt; and &lt;code&gt;delivery-managers&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;All developers in your organization can push to their own branches and issue pull requests, but only team leaders should be required to review any new pull requests. Only when the team leader approves can changes be merged into the protected &lt;code&gt;main&lt;/code&gt; branch. Then, when delivery managers get the green light to ship, they are the ones to trigger releases of software. In this tutorial, we will create a separate security group for them.&lt;/p&gt;

&lt;p&gt;CircleCI will use these security groups with contexts to limit which jobs can be executed by whom, so that only the delivery managers can trigger them manually.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using CircleCI contexts
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://circleci.com/docs/2.0/contexts/"&gt;Contexts&lt;/a&gt; in CircleCI serve a double role. One role limits the scope of secrets shared with a job while the other controls access.&lt;/p&gt;

&lt;p&gt;Only a job that has a context specified to it in a workflow is able to use the context’s secrets as environment variables. Contexts are shared across the entire organization in CircleCI, so they can be reused in multiple projects. You can set them up using the organization settings menu on the left hand side of the CircleCI dashboard.&lt;/p&gt;

&lt;p&gt;For access control, you can specify security groups to any context. For this tutorial,&lt;br&gt;&lt;br&gt;
we will create a context called &lt;code&gt;release&lt;/code&gt; and specify the &lt;code&gt;delivery-mgrs&lt;/code&gt; security group to it.&lt;/p&gt;

&lt;p&gt;Now you can set up your pipeline. The sample project uses the following flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Tests&lt;/li&gt;
&lt;li&gt;Security scans&lt;/li&gt;
&lt;li&gt;Dev environment deployment&lt;/li&gt;
&lt;li&gt;Approval job for the delivery manager&lt;/li&gt;
&lt;li&gt;Production deployment
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;workflows:
 build-test-deploy:
   jobs:
     - test
     - security-scan:
         context: security
     - deploy-app:
         name: deploy-app-dev
         env: dev
         context: deployment-dev
         requires:
           - test
           - security-scan
         filters:
           branches:
             only:
               - main
     - approve-for-prod:
         type: approval
         requires:
           - deploy-app-dev
     - deploy-app:
         name: deploy-app-prod
         env: prod
         requires:
           - approve-for-prod
         context: release-prod


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

&lt;/div&gt;



&lt;p&gt;The pipeline uses contexts for environment variables like our API keys, but also uses the &lt;code&gt;release-prod&lt;/code&gt; context. The &lt;code&gt;release-prod&lt;/code&gt; context is gated so it can only be used by a delivery manager.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting up approval jobs
&lt;/h3&gt;

&lt;p&gt;The final piece of the puzzle is the approval job: &lt;code&gt;approve-for-prod&lt;/code&gt;. Technically, anyone can log in and approve this job. However, the &lt;code&gt;deploy-app-prod&lt;/code&gt; job following it uses the &lt;code&gt;release-prod&lt;/code&gt; context, which only accepts delivery managers’ credentials. If someone without those credentials approves it, the release job will fail with an &lt;code&gt;unauthorized&lt;/code&gt; error, and the whole pipeline will terminate unsuccessfully.&lt;/p&gt;

&lt;h3&gt;
  
  
  Other helpful bits and pieces
&lt;/h3&gt;

&lt;p&gt;One additional control we have set up in our workflow is the branch filter. The development deployment will occur only on the &lt;code&gt;main&lt;/code&gt; branch because of that filter. The &lt;code&gt;main&lt;/code&gt; branch is labelled as protected so the only way to get the code onto the &lt;code&gt;main&lt;/code&gt; branch is by passing the automated checks and code review, potentially by a lead engineer.&lt;/p&gt;

&lt;p&gt;You could also use dedicated QA or Security review steps that require manual approval. Build them the same way as part of the chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Considerations for open source projects
&lt;/h2&gt;

&lt;p&gt;So far we covered the enterprise use case for access control. Most OSS projects do not have the same strict compliance requirements as enterprises. In contrast these projects need to have their contributions opened to a much wider group of people. That means allowing many more people to trigger pipelines.&lt;/p&gt;

&lt;p&gt;Often the company that initiated and owns a popular OSS project continues to employ the core contributors. They will probably be joined by other regular contributors and maintainers that are not part of that company. And then there is everyone else - anyone who occasionally might contribute a fix or a feature.&lt;/p&gt;

&lt;p&gt;For that scenario, you can set up three flows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Company internal flow&lt;/strong&gt;. Members contribute and also administer everything. Company employees are likely the only people allowed to release new versions of software. We can call them “inner core contributors”.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Semi-internal flow&lt;/strong&gt;. These members are part of the organization and will be able to push directly to the main OSS repository. They will be able to use CircleCI for everything, including debugging jobs with SSH and triggering pipelines. Call them “outer core contributors”.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standard flow&lt;/strong&gt;. The rest of the contributors in the community who can issue PRs, otherwise work on their own. We will call them “community contributors”.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For community contributors. the flow is standard: make a fork, then open a pull request. You can toggle CircleCI to build pull requests that will automatically verify their changes.&lt;/p&gt;

&lt;p&gt;You should still have a protected branch, and required checks.&lt;/p&gt;

&lt;p&gt;For the groups of core contributors, you may want to include some secrets as well. Secrets require some more work. Also, passing secrets via forks is inherently insecure. Anyone could extract any secrets you allow to pass by modifying the pipeline in their PR. This could include API keys to certain services, or credentials to where your project is distributed.&lt;/p&gt;

&lt;p&gt;One option is to avoid passing secrets to forks altogether. You will have to push any code after reviewing it into your own org, where it can be executed, and then merged into your default branch. There is a helpful article that &lt;a href="https://dev.to/circleci/triggering-trusted-ci-jobs-on-untrusted-forks-o84-temp-slug-4362685"&gt;explains the process&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The other option is to &lt;em&gt;allow&lt;/em&gt; passing secrets to forks, but to prevent these secrets from being shared unless the code has been thoroughly reviewed and approved by a team member. You can set that up in the CircleCI project settings.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sIWkq49a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://production-cci-com.imgix.net/blog/media/2022-04-20-access-control-circleci-settings.png%3Fixlib%3Drb-3.2.1%26w%3D2000%26auto%3Dformat%26fit%3Dmax%26q%3D60%26ch%3DDPR%252CWidth%252CViewport-Width%252CSave-Data" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sIWkq49a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://production-cci-com.imgix.net/blog/media/2022-04-20-access-control-circleci-settings.png%3Fixlib%3Drb-3.2.1%26w%3D2000%26auto%3Dformat%26fit%3Dmax%26q%3D60%26ch%3DDPR%252CWidth%252CViewport-Width%252CSave-Data" alt="CircleCI sharing secrets across forks" width="800" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you toggle secrets you will need to set up an approval job. Put any secrets in a context that will be accessed only by people who belong to that context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;em&gt;If you use this method, make sure that &lt;strong&gt;all&lt;/strong&gt; contexts in your organization specify the security group. If you do not, a malicious actor could guess your context name in a PR that gets executed and extract environment variables from it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;With your inner and outer core of contributors, you can set up access controls in very much the same way. Maybe only the inner core can release new versions, but anyone in the outer core can merge any pull requests. Or maybe you just have one set of core maintainers who can do everything. The details are up to you!&lt;/p&gt;

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

&lt;p&gt;In this article we have looked at ways to protect your CI/CD pipelines further by setting up access controls to cordon off parts of pipelines (and the associated credentials) to a limited scope of people. This is a versatile approach and works for both enterprise organizations as well as OSS projects.&lt;/p&gt;

&lt;p&gt;We used security groups, protected branches, contexts, and approval jobs in CircleCI to achieve that effect, for both OSS and proprietary projects. Experiment with the best configuration for your organization and release your applications safely and securely.&lt;/p&gt;

</description>
      <category>circleci</category>
      <category>pipelines</category>
      <category>cicd</category>
    </item>
    <item>
      <title>Config best practices: concurrency and parallelism</title>
      <dc:creator>Katy</dc:creator>
      <pubDate>Tue, 29 Mar 2022 11:00:00 +0000</pubDate>
      <link>https://dev.to/circleci/config-best-practices-concurrency-and-parallelism-5o6</link>
      <guid>https://dev.to/circleci/config-best-practices-concurrency-and-parallelism-5o6</guid>
      <description>&lt;p&gt;When is the last time you updated your CI/CD workflow? A year ago? Never? You are not alone, my friends. Reconfiguring workflows can be one of the most daunting tasks for DevOps practitioners. But with new opportunities to &lt;a href="https://dev.to/jerdog/what-developers-get-out-of-the-box-from-the-most-generous-free-plan-anywhere-49ce-temp-slug-3999428"&gt;benefit from CircleCI plans&lt;/a&gt;, there’s one simple and effective place to start: understanding concurrency and parallelism.&lt;/p&gt;

&lt;p&gt;Using concurrency and parallelism can cut your build times significantly. But you need to know what they are and how to find them in your config file.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is concurrency?
&lt;/h2&gt;

&lt;p&gt;Concurrency means that multiple computing tasks are happening at the same time. It’s everywhere in computing. We have so many things happening concurrently: applications running, computers communicating in a network, or even users visiting a website. Concurrency is so commonplace that it’s easy to assume we know how it works. While the definition always remains the same, the practical application of concurrency can be nuanced. So what does concurrency mean within CircleCI?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Simply put, concurrency in CircleCI is the number of tasks that are being executed at any point in time. For example, CircleCI’s free plan provides a concurrency limit of 30, meaning you can run up to 30 tasks at the same time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Computing how many concurrent tasks are happening is a little more complicated than finding out how many jobs are running or how many containers are being used. Pipelines can have all sorts of twists and turns that change the number of concurrent tasks, like &lt;a href="https://circleci.com/docs/2.0/configuration-reference/#logic-statements"&gt;conditional logic&lt;/a&gt; or &lt;a href="https://circleci.com/docs/2.0/parallelism-faster-jobs/"&gt;test splitting&lt;/a&gt;. For this post, I’ll focus on how to manage concurrency and when it matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is parallelism?
&lt;/h2&gt;

&lt;p&gt;It’s hard to write about concurrency in CircleCI without talking about parallelism. The two concepts are often conflated, but have distinct applications. We already know concurrency is the number of executing tasks at any given time in a workflow. We can affect concurrency by changing parallelism, which is where some confusion can start.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Parallelism splits work between identical copies of a particular job.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Parallelism is most often used to &lt;a href="https://dev.to/ronpowelljr/a-guide-to-test-splitting-4jmi-temp-slug-647797"&gt;split up test suites&lt;/a&gt;. All of the copies of the job have the same instructions, but run with different variables. Parallelism is set in the CircleCI configuration file, and the number of parallel jobs counts toward your concurrency total.&lt;/p&gt;

&lt;h2&gt;
  
  
  Applying concurrency and parallelism
&lt;/h2&gt;

&lt;p&gt;Here’s an example using the CircleCI free plan, which has a concurrency limit of 30. Say you have 10 jobs that each take 1 minute to execute. Without concurrency, this workflow would take 10 minutes to complete. With concurrency, each of those jobs could run at the same time, and the workflow would be done in 1 minute instead of 10. If you set parallelism to 3, you can still run 10 jobs at the same time and be within the concurrency limit. You can run 3 copies of 10 jobs for 30 total tasks done in a minute.&lt;/p&gt;

&lt;p&gt;You could just as easily run 4 copies (parallelism of 4) on 7 jobs for a total of 28 concurrent tasks. The free plan allows a maximum parallelism of 4, but other plans have more options if you really need the speed.&lt;/p&gt;

&lt;p&gt;If you have a situation where the total number of simultaneous tasks is more than 30, some of the work will have to wait. For example, if you set parallelism to 4 on 8 jobs, one of those jobs (and all of its copies) will have to wait until there are resources free. The copies of jobs created by parallelism always run simultaneously, so even if you’re only over the concurrency limit by 2 (as in this case), all four copies of one job will wait until another job finishes.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to add parallelism and concurrency to your pipelines
&lt;/h2&gt;

&lt;p&gt;Most of the time, you don’t need to worry about concurrency. Concurrency limits are set by your CircleCI plan and are enforced in the background. You may not need to manage concurrency at all. Most often, you will take advantage of your concurrency by working with parallelism. Setting parallelism is easy: set the value of the parallelism key in the config.yml. Any value greater than 1 means you’re running parallel tasks.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to set parallelism
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; ~/.circleci/config.yml

version: 2
jobs:
  test:
    docker:
      - image: cimg/&amp;lt;language&amp;gt;:&amp;lt;version TAG&amp;gt;
        auth:
          username: mydockerhub-user
          password: $DOCKERHUB_PASSWORD # context / project UI env-var reference
    parallelism: 3

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

&lt;/div&gt;



&lt;p&gt;This example has one job (named test) running on Docker. Setting parallelism to 3 means three copies of this job (called tasks) will run simultaneously on three separate Docker containers. The only differences between these tasks are environment variables so that work can be split among these tasks. This is most often used for test splitting, &lt;a href="https://circleci.com/docs/2.0/parallelism-faster-jobs/"&gt;which you can read more about in our documentation&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;As DevOps practitioners, we care about concurrency because it helps get work done faster by running multiple processes at the same time. Knowing the concurrency limit of your plan and all the tasks that count toward it helps you optimize your builds.&lt;/p&gt;

&lt;p&gt;Concurrency can be a straightforward concept. Jobs finish sooner when at least some of them can run at the same time. Parallelism helps you customize which tasks are done concurrently and is easily set in the config file. Concurrency and parallelism both help finish tasks quicker so you can get on to the important business of failing, passing, and shipping software.&lt;/p&gt;

&lt;p&gt;The next step is to &lt;a href="https://circleci.com/docs/2.0/parallelism-faster-jobs/#using-environment-variables-to-split-tests"&gt;continue learning about test splitting and continue to automate and expedite your jobs&lt;/a&gt;. If you’re interested in expert reviews of your CircleCI configuration to help optimize your work, you can get a custom evaluation from a dedicated support engineer by signing up for a &lt;a href="https://circleci.com/support/plans/"&gt;premium support plan&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>circleci</category>
      <category>cicd</category>
      <category>config</category>
    </item>
    <item>
      <title>Advanced pipeline orchestration with the circleback pattern</title>
      <dc:creator>Zan Markan</dc:creator>
      <pubDate>Fri, 25 Feb 2022 10:00:00 +0000</pubDate>
      <link>https://dev.to/circleci/advanced-pipeline-orchestration-with-the-circleback-pattern-4ee8</link>
      <guid>https://dev.to/circleci/advanced-pipeline-orchestration-with-the-circleback-pattern-4ee8</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This tutorial covers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Orchestrating triggers for a dependent pipeline&lt;/li&gt;
&lt;li&gt;Intro to the circleback pattern&lt;/li&gt;
&lt;li&gt;Creating the config for a circleback pipeline&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;With multiple teams working on many projects, having a single pipeline for your software is just not enough. These projects need to be built and integrated before they can be tested and released. So how do dev teams handle this situation? Many teams approach the problem by breaking down software into smaller parts that do less, and are easier to maintain and build. This approach has resulted in the microservices architectures that are increasingly common in our industry.&lt;/p&gt;

&lt;p&gt;The downside is that breaking software into smaller parts increases complexity. The combination of more parts and higher complexity makes it more difficult to test applications and operate them in production.&lt;/p&gt;

&lt;p&gt;CI/CD pipelines are not an exception here. In &lt;a href="https://dev.to/blog/triggering-pipelines-from-pipelines/"&gt;my previous article in this series&lt;/a&gt;, we looked at triggering pipelines from other pipelines. That post described how to link multiple projects together in CircleCI, so that one deployment kicks off another.&lt;/p&gt;

&lt;p&gt;In this article we will go a few steps further. I will provide an example of pipeline orchestration where the first pipeline not only triggers the other, but also waits on another pipeline to complete, before continuing. I call this the circleback pattern because it “circles back” to the second pipeline to signal when it has completed the work. Using this pattern allows for better integration testing and more complex deployment and release scenarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;This tutorial covers advanced pipeline orchestration techniques, so experience with CircleCI and DevOps is a must.&lt;/li&gt;
&lt;li&gt;The tutorial also builds on a previous tutorial: &lt;a href="https://dev.to/blog/triggering-pipelines-from-pipelines/"&gt;Triggering pipelines from other pipelines&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Resources and sample code
&lt;/h2&gt;

&lt;p&gt;The source code for this example is located in two repositories:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/CircleCI-Public/circleback-cicd-project-a"&gt;Pipeline A - does the triggering&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/CircleCI-Public/circleback-cicd-project-a"&gt;Pipeline B - gets triggered and circles back&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Introducing the circleback pattern
&lt;/h2&gt;

&lt;p&gt;There are three steps in the circleback orchestration of these multiple pipelines:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The first pipeline waits&lt;/li&gt;
&lt;li&gt;The second pipeline terminates&lt;/li&gt;
&lt;li&gt;Results are retrieved from the first pipeline Another way of describing it is that the second pipeline calls or “circles back” to the first, while the first one is suspended and waiting for the signal to continue.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;An alternative approach would be to keep the first pipeline running, checking periodically whether the second pipeline has finished. The main drawback of this approach is the increased cost for the running job’s continuous polling.&lt;/p&gt;

&lt;p&gt;Depending on the status of the second pipeline, the first continues executing until it either terminates successfully or fails.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6hWCJei5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://production-cci-com.imgix.net/blog/media/2022-02-14-circleback-pattern-diagram.png%3Fixlib%3Drb-3.2.1%26w%3D2000%26auto%3Dformat%26fit%3Dmax%26q%3D60%26ch%3DDPR%252CWidth%252CViewport-Width%252CSave-Data" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6hWCJei5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://production-cci-com.imgix.net/blog/media/2022-02-14-circleback-pattern-diagram.png%3Fixlib%3Drb-3.2.1%26w%3D2000%26auto%3Dformat%26fit%3Dmax%26q%3D60%26ch%3DDPR%252CWidth%252CViewport-Width%252CSave-Data" alt="Circle back pattern diagram" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why have pipelines wait for other projects to complete?
&lt;/h2&gt;

&lt;p&gt;As mentioned in the introduction, this is an advanced technique aimed at taming the complexity that stems from working with multiple projects. It can be used by teams working on multiple interdependent projects that they do not want to put in a single repository like a monorepo. Another use would be to have a centralized repository for tests, for example in a hardware company. This technique could also be useful for integration testing of a microservices application, or for orchestrating complex deployment scenarios. There are many possibilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing pipeline triggers
&lt;/h2&gt;

&lt;p&gt;We have 2 pipelines we want to orchestrate&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pipeline A, which does the triggering&lt;/li&gt;
&lt;li&gt;Pipeline B is triggered, and circles back to pipeline A&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Pipeline B is dependent on A, and can be used to validate A.&lt;/p&gt;

&lt;p&gt;Both pipelines need to have API keys set up and available. You can use the API key set as an environment variable (&lt;code&gt;CIRCLECI_API_KEY&lt;/code&gt;) in the job in pipeline A, and also in pipeline B when it calls back. You can either set it in both projects, or at the organization level as a context. For this tutorial, I set it at the organization level as the &lt;code&gt;circleci_api&lt;/code&gt; context, so that both projects can use the same API key.&lt;/p&gt;

&lt;h3&gt;
  
  
  Trigger the pipeline
&lt;/h3&gt;

&lt;p&gt;The triggering process is explained in depth in the first part of this tutorial, &lt;a href="https://dev.to/blog/triggering-pipelines-from-pipelines/"&gt;Triggering pipelines from other pipelines&lt;/a&gt;. In this follow-up tutorial, I will cover just the important differences.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To circle back from the pipeline, pass the original pipeline’s ID to it. Then it can be retrieved and reached with the API.&lt;/li&gt;
&lt;li&gt;You also need to store the triggered pipeline’s ID. You will need to get its result later on.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the sample code, the parameter is called &lt;code&gt;triggering-pipeline-id&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl --request POST \
                --url https://circleci.com/api/v2/project/gh/zmarkan-demos/circleback-cicd-project-b/pipeline \
                --header "Circle-Token: $CIRCLECI_API_KEY" \
                --header "content-type: application/json" \
                --data '{"branch":"main","parameters":{"triggering-pipeline-id":"&amp;lt;&amp;lt; pipeline.id &amp;gt;&amp;gt;"}}'

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

&lt;/div&gt;



&lt;p&gt;To store the pipeline ID, wrap your &lt;code&gt;curl&lt;/code&gt; call in &lt;code&gt;$()&lt;/code&gt; and assign it to the variable &lt;code&gt;CREATED_PIPELINE&lt;/code&gt;. To extract the ID from the response body, use the &lt;code&gt;jq&lt;/code&gt; tool, and write it to the file &lt;code&gt;pipeline.txt&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATED_PIPELINE=$(curl --request POST \
                --url https://circleci.com/api/v2/project/gh/zmarkan-demos/semaphore_demo_project_b/pipeline \
                --header "Circle-Token: $CIRCLECI_API_KEY" \
                --header "content-type: application/json" \
                --data '{"branch":"main","parameters":{"triggering-pipeline-id":"&amp;lt;&amp;lt; pipeline.id &amp;gt;&amp;gt;"}}' \
              | jq -r '.id'
              )
              echo "my created pipeline"
              echo $CREATED_PIPELINE
              mkdir ~/workspace
              echo $CREATED_PIPELINE &amp;gt; pipeline.txt

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

&lt;/div&gt;



&lt;p&gt;Now that you have the file &lt;code&gt;pipeline.txt&lt;/code&gt; created, use &lt;code&gt;persist_to_workspace&lt;/code&gt; to store it and use it in a subsequent job:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- persist_to_workspace:
            root: .
            paths: 
              - pipeline.txt  

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

&lt;/div&gt;



&lt;p&gt;The whole job configuration is here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
jobs:
  trigger-project-b-pipeline:
      docker: 
        - image: cimg/base:2021.11
      resource_class: small
      steps:
        - run:
            name: Ping another pipeline
            command: |
              CREATED_PIPELINE=$(curl --request POST \
                --url https://circleci.com/api/v2/project/gh/zmarkan-demos/semaphore_demo_project_b/pipeline \
                --header "Circle-Token: $CIRCLECI_API_KEY" \
                --header "content-type: application/json" \
                --data '{"branch":"main","parameters":{"triggering-pipeline-id":"&amp;lt;&amp;lt; pipeline.id &amp;gt;&amp;gt;"}}' \
              | jq -r '.id'
              )
              echo "my created pipeline"
              echo $CREATED_PIPELINE
              mkdir ~/workspace
              echo $CREATED_PIPELINE &amp;gt; pipeline.txt
        - persist_to_workspace:
            root: .
            paths: 
              - pipeline.txt  
...

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Orchestrating the waits
&lt;/h3&gt;

&lt;p&gt;The previous job will trigger a pipeline B, which needs to complete before it can circle back to pipeline A. You can use the &lt;code&gt;approval&lt;/code&gt; job in CircleCI like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
workflows:
  node-test-and-deploy:
    jobs:
      ...
      - trigger-project-b-pipeline:
          context: 
            - circleci-api
          requires:
            - build-and-test
          filters:
            branches:
              only: main
      - wait-for-triggered-pipeline:
          type: approval
          requires: 
            - trigger-project-b-pipeline
      - check-status-of-triggered-pipeline:
          requires:
            - wait-for-triggered-pipeline
          context:
            - circleci-api
      ...

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

&lt;/div&gt;



&lt;p&gt;After the job &lt;code&gt;trigger-project-b-pipeline&lt;/code&gt;, enter the &lt;code&gt;wait-for-triggered-pipeline&lt;/code&gt;. Because that job type is &lt;code&gt;approval&lt;/code&gt; it will wait until someone (in this case, the API) manually approves it. (More details in the next section.) After it is approved, add a &lt;code&gt;requires&lt;/code&gt; stanza so it continues to a subsequent job.&lt;/p&gt;

&lt;p&gt;Both jobs that use the CircleCI API have the &lt;code&gt;context&lt;/code&gt; specified, so the API token is available to both as an environment variable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Circle back to pipeline A
&lt;/h3&gt;

&lt;p&gt;For now we are done with pipeline A, and it is pipeline B’s time to shine. CircleCI’s &lt;code&gt;approval&lt;/code&gt; job is a special kind of job that waits until accepted. It is commonly used to hold a pipeline in a pending state until it is approved by a human delivery lead or infosec engineer.&lt;/p&gt;

&lt;p&gt;At this point, pipeline B knows the ID of pipeline A, so you can use the approval API to get it. You only have the ID of the pipeline being run, but not the actual job that needs approval, so you will need more than one API call:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get all jobs in the pipeline&lt;/li&gt;
&lt;li&gt;Find the approval job by name&lt;/li&gt;
&lt;li&gt;Send a request to approve the job&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Approving the job allows pipeline A to continue.&lt;/p&gt;

&lt;p&gt;If the tests fail in pipeline B, then that job automatically fails. A workflow with required jobs will not continue in this case. You can get around by using &lt;code&gt;post-steps&lt;/code&gt; in the pipeline, which always executes. The whole workflow is shown in the next sample code block.&lt;/p&gt;

&lt;p&gt;Parameters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;parameters:
  triggering-pipeline-id:
    type: string
    default: ""

...

workflows:
  node-test-and-deploy:
    jobs:
      - build-and-test:
          post-steps:
            - approve-job-in-triggering-pipeline
          context: 
            - circleci-api       

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

&lt;/div&gt;



&lt;p&gt;Script to perform the approval API call can be implemented like this. For this tutorial, I used a &lt;code&gt;command&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
commands:
  approve-job-in-triggering-pipeline:
    steps:
      - run:
          name: Ping CircleCI API and approve the pending job
          command: |
            echo &amp;lt;&amp;lt; pipeline.parameters.triggering-pipeline-id &amp;gt;&amp;gt;
            if ! [-z "&amp;lt;&amp;lt; pipeline.parameters.triggering-pipeline-id &amp;gt;&amp;gt;"] 
            then
              workflow_id=$(curl --request GET \
                --url https://circleci.com/api/v2/pipeline/&amp;lt;&amp;lt; pipeline.parameters.triggering-pipeline-id &amp;gt;&amp;gt;/workflow \
                --header "Circle-Token: $CIRCLECI_API_KEY" \
                --header "content-type: application/json" \
              | jq -r '.items[0].id')

              echo $workflow_id

              waiting_job_id=$(curl --request GET \
                --url https://circleci.com/api/v2/workflow/$workflow_id/job \
                --header "Circle-Token: $CIRCLECI_API_KEY" \
                --header "content-type: application/json" \
              | jq -r '.items[] | select(.name == "wait-for-triggered-pipeline").id')

              echo $waiting_job_id

              curl --request POST \
                --url https://circleci.com/api/v2/workflow/$workflow_id/approve/$waiting_job_id \
                --header "Circle-Token: $CIRCLECI_API_KEY" \
                --header "content-type: application/json"

            fi
          when: always       
...

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

&lt;/div&gt;



&lt;p&gt;The script first checks for the existence of the &lt;code&gt;triggering-pipeline-id&lt;/code&gt; pipeline parameter. It proceeds only if that parameter exists. The &lt;code&gt;when: always&lt;/code&gt; line in the command makes sure that this executes regardless of termination status.&lt;/p&gt;

&lt;p&gt;Then it makes 3 API calls:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get workflow ID in a pipeline. There is just one workflow in that pipeline for this sample project.&lt;/li&gt;
&lt;li&gt;Get jobs in that workflow, use &lt;code&gt;jq&lt;/code&gt; to select the one that matches the approval job name (&lt;code&gt;wait-for-triggered-pipeline&lt;/code&gt;), and extract the approval job’s ID.&lt;/li&gt;
&lt;li&gt;Make the request to the approval endpoint with the waiting job ID.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For this tutorial, we are storing results like workflow ID and job ID in local bash variables, and using them in subsequent calls to the API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; : &lt;em&gt;If you have more jobs than can be sent in a single response, you might have to handle pagination as well.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now that you have made the approval request, pipeline B is complete, and pipeline A should be running again.&lt;/p&gt;

&lt;h3&gt;
  
  
  Update pipeline A with the result of B
&lt;/h3&gt;

&lt;p&gt;After pipeline A has been approved, the next job in the workflow will begin. If your workflow graph requires it, pipeline A can trigger multiple jobs.&lt;/p&gt;

&lt;p&gt;We still do not have any indication of the result of the previous workflow. To get that information, you can use the API again to get B’s status from pipeline A. An example job could look like that: &lt;code&gt;check-status-of-triggered-pipeline&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;First, you need to retrieve the ID of the triggered pipeline, which is pipeline B. This is the same ID that was persisted in a workspace in an earlier step. Retrieve it using &lt;code&gt;cat&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; - attach_workspace:
          at: workspace
      - run:
          name: Check triggered workflow status
          command: |
            triggered_pipeline_id=$(cat workspace/pipeline.txt)

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

&lt;/div&gt;



&lt;p&gt;Then use the API to retrieve the workflow. Use &lt;code&gt;jq&lt;/code&gt; to get just the status of the first item in the returned array of workflows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;created_workflow_status=$(curl --request GET \
                --url "https://circleci.com/api/v2/pipeline/${triggered_pipeline_id}/workflow" \
                --header "Circle-Token: $CIRCLECI_API_KEY" \
                --header "content-type: application/json" \
              | jq -r '.items[0].status'
            )

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

&lt;/div&gt;



&lt;p&gt;Check that status is not &lt;code&gt;success&lt;/code&gt;. If it is not, use &lt;code&gt;exit&lt;/code&gt; to terminate the job with exit code -1. If the workflow is successful, it will terminate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if [["$created_workflow_status" != "success"]]; then
              echo "Workflow not successful - ${created_workflow_status}"
              (exit -1) 
            fi

            echo "Created workflow successful"

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

&lt;/div&gt;



&lt;p&gt;Here is the full config for the job &lt;code&gt;check-status-of-triggered-pipeline&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; check-status-of-triggered-pipeline:
    docker: 
      - image: cimg/base:2021.11
    resource_class: small 
    steps:
      - attach_workspace:
          at: workspace
      - run:
          name: Check triggered workflow status
          command: |
            triggered_pipeline_id=$(cat workspace/pipeline.txt)
            created_workflow_status=$(curl --request GET \
                --url "https://circleci.com/api/v2/pipeline/${triggered_pipeline_id}/workflow" \
                --header "Circle-Token: $CIRCLECI_API_KEY" \
                --header "content-type: application/json" \
              | jq -r '.items[0].status'
            )
            echo $created_workflow_status
            if [["$created_workflow_status" != "success"]]; then
              echo "Workflow not successful - ${created_workflow_status}"
              (exit -1) 
            fi

            echo "Created workflow successful"

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

&lt;/div&gt;



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

&lt;p&gt;In this article we have reviewed an example of a complex pipeline orchestration pattern that I have named “circleback”. The circleback pattern creates a dependent pipeline and allows you to wait for it to terminate before completing. It involves making several API keys from both projects, the use of an approval job, and the workspace feature of CircleCI to store and pass values such as pipeline ID across jobs in a workflow. The sample projects are located in separate repositories: &lt;a href="https://github.com/CircleCI-Public/circleback-cicd-project-a"&gt;project A&lt;/a&gt;, and &lt;a href="https://github.com/CircleCI-Public/circleback-cicd-project-B"&gt;project B&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If this article has helped you in a way, I would love to know, also if you have any questions or suggestions about it, or ideas for future articles and guides, reach out to me on &lt;a href="https://twitter.com/zmarkan"&gt;Twitter - @zmarkan&lt;/a&gt; or &lt;a href="//mailto:zan@circleci.com"&gt;email me&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>circleci</category>
      <category>pipelines</category>
      <category>cicd</category>
    </item>
    <item>
      <title>Testing locally with CircleCI runners</title>
      <dc:creator>Zan Markan</dc:creator>
      <pubDate>Tue, 18 Jan 2022 10:00:00 +0000</pubDate>
      <link>https://dev.to/circleci/testing-locally-with-circleci-runners-mg6</link>
      <guid>https://dev.to/circleci/testing-locally-with-circleci-runners-mg6</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;In this article you will learn how to set up the CircleCI runner agent on your local machine to run tests. You will also learn how to configure your CircleCI pipeline so that the runner is invoked correctly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Many development teams start their CI/CD journey with a local build box (or six) that run their tests. In several mobile teams I worked on, for example, we had a few Mac Mini boxes with physical devices plugged in that we used for running local UI and unit tests. Eventually we migrated to a cloud-based solution, which brought us much greater stability and many new features. But moving to the cloud also meant our local hardware was obsolete. We had to rely on emulation, or opt for another cloud-based device farm for that.&lt;/p&gt;

&lt;p&gt;With CircleCI’s runners, you can keep using your own devices to run tests on, while benefiting from everything else available in the CircleCI cloud. You can also use runners for tests that &lt;em&gt;need&lt;/em&gt; to run on your own infrastructure, for security-critical scenarios, or when you are developing your own hardware.&lt;/p&gt;

&lt;p&gt;With the launch of the &lt;a href="https://dev.to/blog/new-cicd-free-plan-what-devs-get/"&gt;CircleCI Free plan&lt;/a&gt;, features like runners are now available to everyone. In this article you will learn how to set up the CircleCI runner agent on your local machine to run tests. You will also learn how to configure your CircleCI pipeline so that the runner is invoked correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;This tutorial assumes some experience with CircleCI and an understanding of how pipelines are configured to build and test software projects.&lt;/p&gt;

&lt;p&gt;I have created a &lt;a href="https://github.com/zmarkan-demos/android-testing-runner-example"&gt;sample project&lt;/a&gt; that shows the runner configuration.&lt;/p&gt;

&lt;p&gt;You can also find its builds &lt;a href="https://app.circleci.com/pipelines/github/zmarkan-demos/android-testing-runner-example/7/workflows/8feabfe4-c942-4949-bf88-cfed8aca7615/jobs/30"&gt;in the CircleCI dashboard for the sample project&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; : &lt;em&gt;This example shows an Android application and tests, using the runner on macOS. The principles behind it can be universally applied, though: to iOS apps, custom hardware, or for runner on different infrastructure, like Docker containers, Windows, Linux machines, and more.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How runners work
&lt;/h2&gt;

&lt;p&gt;A runner is a process installed on your infrastructure that communicates with CircleCI. Runners function as their own resource class. Your &lt;code&gt;config.yml&lt;/code&gt; still defines the pipeline, jobs, and workflows, but instead of using CircleCI’s cloud-based resources like containers and virtual machines, you execute it on your own.&lt;/p&gt;

&lt;p&gt;First, install the runner agent locally. This is a daemon process that runs in the background, checking for prompts from CircleCI. When CircleCI signals that a job must be triggered on the runner, the agent executes the workload. It also has access to the same credentials as the cloud version of CircleCI, so it runs seamlessly and can fetch the code from your repositories.&lt;/p&gt;

&lt;p&gt;Once the job is complete, the results and any artifacts are sent back to the cloud service. Only the actual job execution is done on your infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;Implementation consists of these processes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setting up the runner agent locally&lt;/li&gt;
&lt;li&gt;Invoking the runner from your CircleCI &lt;code&gt;config.yml&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Setting up the runner agent
&lt;/h3&gt;

&lt;p&gt;Installing the runner agent depends on which platform you are using. Refer to the setup instructions in the &lt;a href="https://circleci.com/docs/2.0/runner-installation"&gt;CircleCI docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For my sample application, I installed the runner agent on a Mac computer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; : &lt;em&gt;These steps are just a brief overview and not a complete guide.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The main steps to set up the runner are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Register a new runner in your organization&lt;/li&gt;
&lt;li&gt;Install the runner agent, following the instructions for your platform&lt;/li&gt;
&lt;li&gt;Start the runner daemon, and make sure it runs on system startup&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Use the &lt;code&gt;circleci&lt;/code&gt; CLI tool too register a new runner in your organization. If it is your first runner, you may need to create a namespace in that organization. You will be referring to that specific runner from the CircleCI config using that fully qualified name. In my case, that was &lt;code&gt;zan_demos_namespace/mac_runner&lt;/code&gt;; &lt;code&gt;mac_runner&lt;/code&gt; is the name of the runner, and &lt;code&gt;zan_demos_namespace&lt;/code&gt; is the namespace I used.&lt;/p&gt;

&lt;p&gt;Here is a sample command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ circleci runner resource-class create zmarkan-demos-namespace/local-mac-runner "Local Mac OS Runner" --generate-token

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

&lt;/div&gt;



&lt;p&gt;This command will also set up a new API token for this runner to use with CircleCI API in the organization. That is made possible because of the &lt;code&gt;--generate-token&lt;/code&gt; flag. Be sure to store that token for later.&lt;/p&gt;

&lt;p&gt;After registering the runner with CircleCI, install the runner agent following the instructions &lt;a href="https://circleci.com/docs/2.0/runner-installation"&gt;in the docs&lt;/a&gt;. The setup requires software like &lt;code&gt;curl&lt;/code&gt;, &lt;code&gt;sha256sum&lt;/code&gt;, &lt;code&gt;tar&lt;/code&gt;, and &lt;code&gt;gzip&lt;/code&gt; preinstalled. There may be other software required.&lt;/p&gt;

&lt;p&gt;Set up some daemon scripts, and pass in these values:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The API token created in the previous step&lt;/li&gt;
&lt;li&gt;The runner namespace&lt;/li&gt;
&lt;li&gt;The name you specified&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The particulars of these items vary based on the platform you are using. For example, on Mac you need to create a &lt;code&gt;launchd.plist&lt;/code&gt; and start it with &lt;code&gt;launchctl&lt;/code&gt;. On Linux it will be a new service that starts with &lt;code&gt;systemctl&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Invoking the runner from a pipeline
&lt;/h2&gt;

&lt;p&gt;Once the runner agent is in motion, you can invoke it from a job in the &lt;code&gt;.circleci/config.yml&lt;/code&gt; file. Make sure to specify the &lt;code&gt;machine&lt;/code&gt; executor type and the resource class with your runner’s namespace and runner name. Here is an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; runner-test:
    machine: true
    resource_class: zmarkan-demos-namespace/local-mac-runner
    environment:
      JAVA_HOME: /Users/zmarkan/libs/jdk-11.0.2.jdk/Contents/Home
      ANDROID_SDK_ROOT: /Users/zmarkan/Library/Android/sdk
    steps:
      - checkout
      - run:
          name: Run connected check on local runner
          command: |
            ./gradlew connectedDebugAndroidTest

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

&lt;/div&gt;



&lt;p&gt;In my example, I had some Android devices connected to my Mac, so the runner could access that local hardware to run tests on them.&lt;/p&gt;

&lt;p&gt;I also needed to pass in some specific values that come out of the box when using CircleCI’s own infrastructure, like &lt;code&gt;JAVA_HOME&lt;/code&gt; and &lt;code&gt;ANDROID_SDK_ROOT&lt;/code&gt;. This is because they were not readily accessible in the specific shell that CircleCI runner uses. On most modern Macs the shell used is Zsh; CircleCI runs Bash by default.&lt;/p&gt;

&lt;p&gt;The rest of the steps are straightforward and will depend on your application and what you want to execute. In my case that was checking out the code from the repo and running the tests. You could also use &lt;code&gt;store_artifacts&lt;/code&gt; and &lt;code&gt;store_test_results&lt;/code&gt; to process the tests and save outputs. The outputs would then be available in your CircleCI cloud dashboard.&lt;/p&gt;

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

&lt;p&gt;In this article you have learned how to set up a local CircleCI runner for executing CircleCI cloud workloads on your local infrastructure. Runner has many use cases, from security to execution on bespoke hardware, all with the same CI/CD experience that cloud based CircleCI offers.&lt;/p&gt;

&lt;p&gt;If you have any feedback or suggestions about topics I should cover next, reach out to me on &lt;a href="https://twitter.com/zmarkan/"&gt;Twitter - @zmarkan&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>circleci</category>
      <category>cicd</category>
      <category>testing</category>
      <category>runners</category>
    </item>
    <item>
      <title>Build private CircleCI orbs on any organization</title>
      <dc:creator>Zan Markan</dc:creator>
      <pubDate>Thu, 13 Jan 2022 10:00:00 +0000</pubDate>
      <link>https://dev.to/circleci/build-private-circleci-orbs-on-any-organization-14fc</link>
      <guid>https://dev.to/circleci/build-private-circleci-orbs-on-any-organization-14fc</guid>
      <description>&lt;p&gt;Using CircleCI’s orbs is a great way to share CI/CD configuration across projects. Public orbs work well for wide adoption, but private orbs have been helpful for organizations needing to share common internal configuration in a secure, non-public way. Private orbs work only within the organization that publishes them.&lt;/p&gt;

&lt;p&gt;We recently opened up private orbs access to all CircleCI customers, including those on the &lt;a href="https://dev.to/blog/new-cicd-free-plan-what-devs-get/"&gt;Free plan&lt;/a&gt;. This new access opens up a number of new possibilities for your pipelines.&lt;/p&gt;

&lt;p&gt;In this article you will learn about private orbs and how to use them for your own organization. We will be using the sample orb I built, which contains a command and a job that lets you trigger CircleCI pipelines in other projects using cURL. You can find the source code of the project in &lt;a href="https://github.com/zmarkan-demos/api-requester-orb-sample"&gt;this repository&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;This article assumes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Working knowledge of &lt;a href="https://circleci.com/docs/2.0"&gt;CircleCI&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Understanding of how pipelines work&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://circleci.com/docs/2.0/local-cli"&gt;CircleCI CLI&lt;/a&gt; installed and configured locally on your machine&lt;/li&gt;
&lt;li&gt;You are using either a project organization or your personal organization on GitHub&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Use cases for private orbs
&lt;/h2&gt;

&lt;p&gt;Like orbs in general, private orbs are useful for sharing steps and tasks that are common to multiple projects.&lt;/p&gt;

&lt;p&gt;Many organizations have their own frameworks and internal tools used across many teams. With private orbs they can share those tools easily, without opening it up to the wider world. Some use cases for private orbs include deployment to your proprietary Kubernetes clusters or other infrastructure, dealing with custom hardware, all the way to logging or common admin tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Initial setup
&lt;/h2&gt;

&lt;p&gt;We will use the CircleCI CLI for this task. With the CLI you will create a new orb, and register it with CircleCI so it can be referenced by other CircleCI pipelines. The CLI allows you to release new versions of your orb.&lt;/p&gt;

&lt;p&gt;The whole orb creation process is &lt;a href="https://circleci.com/docs/2.0/local-cli/"&gt;documented in the CircleCI docs&lt;/a&gt;. This article will serve as a quick recap of it and explanation of the steps involved.&lt;/p&gt;

&lt;p&gt;Create an empty git repository and note its path. I created mine under my &lt;code&gt;zmarkan-demos&lt;/code&gt; organization, and named it &lt;code&gt;api-requester-orb-sample&lt;/code&gt;, so the path is: &lt;code&gt;git@github.com:zmarkan-demos/api-requester-orb-sample.git&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next, create the actual orb with the CLI’s &lt;code&gt;circleci orb init&lt;/code&gt; command, passing in a local path where you want the orb source to be located. This directory must be new; do not use one that already exists. In my case, this was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;circleci orb init ~/github/api-requester-orb-sample --private

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

&lt;/div&gt;



&lt;p&gt;The main difference between public and private orbs is the &lt;code&gt;--private&lt;/code&gt; flag at the end.&lt;/p&gt;

&lt;p&gt;The CLI asks you to either follow the guided setup, which is what I did, or to do it yourself. I recommend using the automated process is recommended as it will set up everything in the directory with an empty orb template, as well as link it to your repository, create a namespace for your orb, and create a CircleCI project for the new orb, just make sure to copy the git URL from the repository you created earlier.&lt;/p&gt;

&lt;p&gt;Finally you need to push the local code to the remote repository -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd ~/github/api-requester-orb-sample
git push origin master

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

&lt;/div&gt;



&lt;p&gt;Note: All orbs exist in a namespace within your organization. This is the same for any runner agents you have registered already.&lt;/p&gt;

&lt;p&gt;You can also review your new private orbs in your organization settings, where they are clearly labeled as private under the &lt;code&gt;type&lt;/code&gt; section.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HDutLjqp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://production-cci-com.imgix.net/blog/media/2022-01-06-private-orb-list-ui.png%3Fixlib%3Drb-3.2.1%26w%3D2000%26auto%3Dformat%26fit%3Dmax%26q%3D60%26ch%3DDPR%252CWidth%252CViewport-Width%252CSave-Data" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HDutLjqp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://production-cci-com.imgix.net/blog/media/2022-01-06-private-orb-list-ui.png%3Fixlib%3Drb-3.2.1%26w%3D2000%26auto%3Dformat%26fit%3Dmax%26q%3D60%26ch%3DDPR%252CWidth%252CViewport-Width%252CSave-Data" alt="List of orbs in the UI" width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Developing an orb
&lt;/h2&gt;

&lt;p&gt;The orb development process depends on whether you opt for the automated guided process or follow your own. As with the setup section, the CircleCI docs cover both scenarios.&lt;/p&gt;

&lt;p&gt;If you have followed the quick setup route, then the CLI will have generated the whole project for you from template. It has samples for a command, job, executor, and a test for it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SAHp2P-Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://production-cci-com.imgix.net/blog/media/2022-01-06-private-orb-generated-ui.png%3Fixlib%3Drb-3.2.1%26w%3D2000%26auto%3Dformat%26fit%3Dmax%26q%3D60%26ch%3DDPR%252CWidth%252CViewport-Width%252CSave-Data" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SAHp2P-Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://production-cci-com.imgix.net/blog/media/2022-01-06-private-orb-generated-ui.png%3Fixlib%3Drb-3.2.1%26w%3D2000%26auto%3Dformat%26fit%3Dmax%26q%3D60%26ch%3DDPR%252CWidth%252CViewport-Width%252CSave-Data" alt="Orb project view" width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can remove any part of the orb that you do not need. In my case I removed the scripts and executors, and kept the commands and jobs. Orbs are just a collection of CircleCI configuration scripts that get resolved and bundled when you run a pipeline.&lt;/p&gt;

&lt;p&gt;We created 2 scripts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;code&gt;commands/trigger-pipeline.yml&lt;/code&gt; command&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;jobs/trigger-circleci-pipeline.yml&lt;/code&gt; job&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The job wraps the command and executes in the base Docker executor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using the trigger-pipeline command
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;trigger-pipeline&lt;/code&gt; command has 4 parameters, and a single step, as shown in this code sample:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;description: &amp;gt;
  This command triggers CircleCI pipeline specified.
  The job execution environment must have cURL utility available

parameters:
  repo-name:
    type: string
    description: "Repo name to trigger pipeline for"

  branch-name:
    type: string
    default: main
    description: "Branch name to trigger"

  trigger-params-json:
    type: string
    default: "{}"
    description: Pipeline trigger parameters in JSON format

  circle-token-env-var:
    type: env_var_name
    default: CIRCLE_TOKEN
    description: Environment variable containing your CircleCI API Key. Default is $CIRCLECI_API_KEY

steps:
  - run:
      name: Run cURL request
      command: |
        curl --request POST \
            --url "https://circleci.com/api/v2/project/gh/${CIRCLE_PROJECT_USERNAME}/&amp;lt;&amp;lt; parameters.repo-name &amp;gt;&amp;gt;/pipeline" \
            --header "Circle-Token: ${&amp;lt;&amp;lt; parameters.circle-token-env-var &amp;gt;&amp;gt;}" \
            --header "content-type: application/json" \
            --data '{"branch":"&amp;lt;&amp;lt; parameters.branch-name &amp;gt;&amp;gt;","parameters":&amp;lt;&amp;lt; parameters.trigger-params-json &amp;gt;&amp;gt;}"'

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

&lt;/div&gt;



&lt;p&gt;Unlike a full CircleCI pipeline config, this one does not require a &lt;code&gt;version&lt;/code&gt; stanza. With only a single command source, it doesn’t have &lt;code&gt;jobs&lt;/code&gt; or &lt;code&gt;workflows&lt;/code&gt; either. All 4 parameters are also specific to this command, unlike the pipeline parameters available in the full CircleCI config.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;curl&lt;/code&gt; command in the run step hits the CircleCI API to trigger another pipeline. It is &lt;a href="https://dev.to/blog/triggering-pipelines-from-pipelines/"&gt;described in detail in this blog post&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using the trigger-circleci-pipeline job
&lt;/h3&gt;

&lt;p&gt;Writing a job that consumes the command we just created is straightforward. Within the same orb, you can use that command as if it were a local command you had defined in the config. In our example in &lt;code&gt;jobs/trigger-circleci-pipeline.yml&lt;/code&gt; it looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;description: &amp;gt;
  Job that trigger CircleCI pipeline in another project with the payload specified

docker:
  - image: cimg/base:2021.12

parameters:
  repo-name:
    type: string
    description: "Repo name to trigger pipeline for"
  branch-name:
    type: string
    default: main
    description: "Branch name to trigger"

  trigger-params-json:
    type: string
    default: "{}"
    description: Pipeline trigger parameters in JSON format

  circle-token-env-var:
    type: env_var_name
    default: CIRCLE_TOKEN
    description: Environment variable containing your CircleCI API Key. Default is $CIRCLECI_API_KEY

steps:
  - trigger-pipeline:
      repo-name: &amp;lt;&amp;lt; parameters.repo-name &amp;gt;&amp;gt;
      branch-name: &amp;lt;&amp;lt; parameters.branch-name &amp;gt;&amp;gt;
      trigger-params-json: &amp;lt;&amp;lt; parameters.trigger-params-json &amp;gt;&amp;gt;
      circle-token-env-var: &amp;lt;&amp;lt; parameters.circle-token-env-var &amp;gt;&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;This command has the parameters, and as with all other jobs in CircleCI we need the executor: &lt;code&gt;docker&lt;/code&gt; in our case. The &lt;code&gt;steps&lt;/code&gt; stanza contains a single step, invoking our &lt;code&gt;trigger-pipeline&lt;/code&gt; command from before, with any parameters we set.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing and deploying the orb
&lt;/h2&gt;

&lt;p&gt;To build, test, and deploy our orb, the orb template project uses CircleCI itself. Within the config in &lt;code&gt;.circleci/config.yml&lt;/code&gt; most everything is pre-made for you. All you need to do is to write tests for it. By default, it contains a job named &lt;code&gt;integration-test-1&lt;/code&gt;, which you can modify to use your own orb. Here is a snippet that invokes the &lt;code&gt;trigger-pipeline&lt;/code&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jobs:
  integration-test-1:
    docker:
      - image: cimg/base:stable
    steps:
      - checkout
      - api-requester-orb-sample/trigger-pipeline:
          repo-name: pinging-me-softly
          branch-name: main
          trigger-params-json: '{"image-name": "cimg/base:2021.12"}'

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

&lt;/div&gt;



&lt;p&gt;To publish a release version you need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Change from the default &lt;code&gt;alpha&lt;/code&gt; branch to either the &lt;code&gt;master&lt;/code&gt; or &lt;code&gt;main&lt;/code&gt; branch&lt;/li&gt;
&lt;li&gt;Include a &lt;code&gt;[semver:patch|minor|major]&lt;/code&gt; message in the commit&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;In this article you have learned about building private orbs for CircleCI, which are now available to all CircleCI customers. Private orbs allow you to have shared CI/CD pipeline configuration across multiple projects. These private orbs can be used by any team member in your organization, without the risk of exposing your config to the public.&lt;/p&gt;

&lt;p&gt;The process as a whole is almost identical for publishing public orbs. Just add the &lt;code&gt;--private&lt;/code&gt; flag in the &lt;code&gt;circleci orb init&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;To read more about orb development check out &lt;a href="https://circleci.com/docs/2.0/orb-author/"&gt;the docs pages on authoring orbs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To read about testing and verifying bash scripts in your orbs using BATS and ShellCheck, &lt;a href="https://circleci.com/docs/2.0/testing-orbs/"&gt;check out this docs page on orb testing methodologies&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you have any questions or suggestions about this article, or ideas for future articles and guides, reach out to me on &lt;a href="https://twitter.com/zmarkan"&gt;Twitter - @zmarkan&lt;/a&gt; or &lt;a href="//mailto:zan@circleci.com"&gt;email me&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>circleci</category>
      <category>orbs</category>
      <category>cicd</category>
      <category>config</category>
    </item>
    <item>
      <title>What developers get, out-of-the-box, from the most generous free plan anywhere</title>
      <dc:creator>Angel Rivera</dc:creator>
      <pubDate>Tue, 11 Jan 2022 13:00:00 +0000</pubDate>
      <link>https://dev.to/circleci/what-developers-get-out-of-the-box-from-the-most-generous-free-plan-anywhere-2n4l</link>
      <guid>https://dev.to/circleci/what-developers-get-out-of-the-box-from-the-most-generous-free-plan-anywhere-2n4l</guid>
      <description>&lt;p&gt;Freemium plans are a great way for companies to introduce developers to their products and offer a hands-on demonstration of the value they provide. But it can be extremely frustrating for developers when a free tier limits access to key features or doesn’t provide enough capacity to evaluate how the product performs in real-world development scenarios. Not only is this frustrating, but it also diminishes the overall developer experience, resulting in negative and sometimes inaccurate perceptions of the product.&lt;/p&gt;

&lt;p&gt;Many companies struggle to strike the right balance between which features to include in their free tier and at what level of usage they should require a paid account. CircleCI is no exception. Until recently, our free plan just wasn’t enough to provide the best developer experience and demonstrate the value and power that CircleCI can bring to your continuous delivery and release processes. That’s why we decided to overhaul our offerings to provide the most comprehensive free plan available on the market.&lt;/p&gt;

&lt;p&gt;In this post, I’ll discuss the newly released CircleCI Free plan, highlighting some of the most impactful changes and how they will improve the developer experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Free plan details
&lt;/h2&gt;

&lt;p&gt;Developers continually adopt innovative strategies and concepts like continuous delivery and release management processes with the goal of building and releasing software faster and more efficiently. CircleCI enables your team to maximize development velocity by automating their software build and release practices. With our new free tier offerings, you get access to all the features and capabilities you need to make the most of your build minutes. Here’s what you get with the new free plan:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unlimited users&lt;/li&gt;
&lt;li&gt;30,000 credits per month—enough for up to 6,000 build minutes, depending on your compute type&lt;/li&gt;
&lt;li&gt;Access to multiple execution environments, including Docker, Linux, Arm, and Windows, and larger resource classes&lt;/li&gt;
&lt;li&gt;30 concurrent job runs on any of the available compute options&lt;/li&gt;
&lt;li&gt;5 self-hosted runners to run jobs on your own machines&lt;/li&gt;
&lt;li&gt;1 GB of network data transfer to self-hosted runners and 2 GB of data storage for saving caches and workspaces, uploading test results, and building artifacts&lt;/li&gt;
&lt;li&gt;Docker layer caching to speed up your Docker builds&lt;/li&gt;
&lt;li&gt;Flaky test detection on our Insights dashboard for up to 5 tests&lt;/li&gt;
&lt;li&gt;The ability to create private orbs for sharing configuration code with other members of your team&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that I’ve briefly described the awesome products and features included in the new Free plan, let’s take a closer look at some of the features that matter most to developers and their teams.&lt;/p&gt;

&lt;h2&gt;
  
  
  Larger resource classes
&lt;/h2&gt;

&lt;p&gt;Release cycles are growing increasingly shorter so that teams can ship changes and new features to users as quickly as possible. For developers to meet their release cycle requirements, it’s critical that they execute highly efficient CI/CD pipelines on the changes to be released. There are many ways to optimize your CI/CD pipelines, and one of the easiest and most effective is to control the pipeline’s underlying compute node capacity via a feature known as the &lt;a href="https://circleci.com/docs/2.0/configuration-reference/#resourceclass"&gt;resource class&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The resource class feature enables teams to configure and manage the capacity of compute node resources such as CPU and RAM, ensuring that the pipeline has the appropriate horsepower to successfully and expediently complete pipeline jobs. More often than not, pipeline job resource classes are configured with insufficient resource capacities, resulting in dramatically slower runs. These slower runs incrementally extend the duration of pipeline completions, which can lead to delays in the release process. The new Free plan provides access to a wider range of resources classes, enabling teams to dial in the right resources to optimize their pipeline job performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  30x concurrency
&lt;/h2&gt;

&lt;p&gt;Beyond providing appropriate compute capacities for pipeline jobs, another feature teams can use to speed up their pipelines is concurrency, which is the ability to run multiple jobs at the same time across multiple execution environments. Under the new Free plan, you can now run up to 30 jobs concurrently, which can yield significant time savings by allowing you to avoid queuing caused by resource constraints in a given execution environment.&lt;/p&gt;

&lt;p&gt;A great use case for concurrency within pipelines is &lt;a href="https://dev.to/blog/how-bolt-optimized-their-ci-pipeline-to-reduce-their-test-run-time-by-over-3x/"&gt;parallel test execution&lt;/a&gt;. The more tests your project has, the longer it will take for them to complete on a single machine. To reduce this time, you can run tests in parallel by specifying a &lt;code&gt;parallelism&lt;/code&gt; level in your job configuration. Your tests will then run simultaneously across multiple separate executors, allowing you to shorten the amount of time it takes to validate and ship changes to your users. For more information on parallelism and concurrency, review the &lt;a href="https://circleci.com/docs/2.0/parallelism-faster-jobs/"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker layer caching
&lt;/h2&gt;

&lt;p&gt;Docker is the &lt;a href="https://dev.to/blog/benefits-of-containerization/"&gt;containerization&lt;/a&gt; technology available within the CircleCI platform. Docker images allow teams to spin up container environments to run jobs, and many teams build their own Docker images to have custom environments to test and deploy their applications. Docker images are built from Dockerfiles, and each command in the Dockerfile produces a layer in the image. Building Docker images can be one of the most time-consuming tasks in a CI/CD workflow.&lt;/p&gt;

&lt;p&gt;With Docker layer caching, now available on the CircleCI Free plan, you can reduce the time spent on repeated Docker builds by saving individual layers of your Docker image on every job run. The next time you run your workflow, CircleCI will retrieve any unchanged layers from the cache rather than rebuilding the entire image from scratch. This enables teams to efficiently package their apps and build related Docker images without slowing down pipeline executions. For more information about Docker layer caching, check out &lt;a href="https://circleci.com/docs/2.0/docker-layer-caching/"&gt;the documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Private orbs
&lt;/h2&gt;

&lt;p&gt;Orbs are &lt;a href="https://dev.to/blog/automate-and-scale-your-ci-cd-with-circleci-orbs/"&gt;reusable packages of YAML&lt;/a&gt; that make it easier for developers to automate processes and incorporate third-party tools in their pipelines as well as share configuration across projects. While there are many useful orbs available in our &lt;a href="https://circleci.com/developer/orbs"&gt;public orbs registry&lt;/a&gt;, teams working in higly regulated industries such as healthcare, finance, or the public sector often require higher levels of security and compliance.&lt;/p&gt;

&lt;p&gt;With &lt;a href="https://circleci.com/docs/2.0/orb-intro/#private-orbs"&gt;private orbs&lt;/a&gt;, your team gets all of the collaboration and efficiency advantages of orbs along with the increased privacy and security that comes from restricting access to authenticated users within your organization. Your team can create and publish new private orbs using the CLI tool, and authenticated users can view and manage your organization’s private orbs by visiting the Orbs page in the Organization Settings tab of the CircleCI web app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test Insights with flaky test detection
&lt;/h2&gt;

&lt;p&gt;Automatically testing changes to your code is the foundation of &lt;a href="https://circleci.com/continuous-integration/"&gt;continuous integration&lt;/a&gt; and is an essential step toward minimizing risk in your software releases. But the reality is that most tests aren’t perfect. They don’t always execute as expected and can sometimes be flaky, meaning they fail nondeterministically. With the &lt;a href="https://dev.to/blog/monitor-and-optimize-your-ci-cd-pipeline-with-insights-from-circleci/"&gt;CircleCI Insights dashboard&lt;/a&gt;, you can monitor test performance across multiple workflows and development branches to automatically identify tests that are slow, flaky, or fail most often.&lt;/p&gt;

&lt;p&gt;Insights gives developers valuable visibility into test execution and performance data. Improved awareness of the health and performance of your test suite can save your team time and money by eliminating hours spent chasing unidentified bugs and increasing your confidence in the quality of your code. Plus, with Insights, you can monitor other key metrics, including credit usage, success rates, and pipeline duration, so that you can get a complete overview of your workflow performance at a glance. To learn more, visit the &lt;a href="https://circleci.com/docs/2.0/insights/"&gt;Insights documentation&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;In this post, I discussed the newly released CircleCI free plan and highlighted some of the changes that will provide the biggest improvements to the developer experience. With access to the complete feature set on CircleCI’s powerful continuous integration and delivery platform, your team can implement fast, flexible, and efficient CI/CD pipelines that will drastically shorten the time from commit to deploy.&lt;/p&gt;

&lt;p&gt;Automating development processes with continuous delivery is no longer optional for software producers who want to be responsive to their users’ needs and stay ahead of the competition. To learn more about CircleCI’s pricing and how it compares to other plans available on the market, visit our &lt;a href="https://circleci.com/pricing/"&gt;pricing page&lt;/a&gt;. If your team isn’t already benefitting from the time savings and confidence boost that a robust CI/CD solution can provide, sign up for a &lt;a href="http://circleci.com/signup"&gt;free CircleCI account&lt;/a&gt; and get started today.&lt;/p&gt;




</description>
      <category>circleci</category>
      <category>cicd</category>
      <category>free</category>
    </item>
    <item>
      <title>Config best practices: Docker layer caching</title>
      <dc:creator>Jeremy Meiss</dc:creator>
      <pubDate>Tue, 11 Jan 2022 10:00:00 +0000</pubDate>
      <link>https://dev.to/circleci/config-best-practices-docker-layer-caching-3m0</link>
      <guid>https://dev.to/circleci/config-best-practices-docker-layer-caching-3m0</guid>
      <description>&lt;p&gt;Let’s face it: Creating the optimal CI/CD workflow is not always a simple task. In fact, writing effective and efficient configuration code is the biggest hurdle that many developers face in their DevOps journey. But you don’t need to be an expert to set up a fast, reliable testing and deployment infrastructure. With a few straightforward techniques, you can optimize your &lt;code&gt;config.yml&lt;/code&gt; file and unleash the full potential of your CI/CD pipelines.&lt;/p&gt;

&lt;p&gt;In this series, we go into depth on some common recommendations that our solutions engineers make during one-on-one config reviews with enterprise-level customers. Today, we are focused on Docker layer caching (DLC), a powerful technique for saving Docker layers between jobs and speeding up your workflows.&lt;/p&gt;

&lt;p&gt;Only available until recently on the Performance and Scale plans, DLC is now included on the new CircleCI Free plan as well as on installations of CircleCI server. In this post, we’ll talk about what Docker layer caching is, why it matters, and how you can add it to your pipelines.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Docker layer caching?
&lt;/h2&gt;

&lt;p&gt;Docker is the containerization technology used on the CircleCI platform. In both the &lt;a href="https://circleci.com/docs/2.0/executor-types/#using-docker"&gt;Docker executor&lt;/a&gt; and the &lt;a href="https://circleci.com/docs/2.0/executor-types/#using-machine"&gt;machine execution environment&lt;/a&gt;, you can run Docker build commands to containerize your applications for testing and deployment. With Docker layer caching, you can save individual layers of the Docker images you build so that they can be reused in subsequent pipeline runs.&lt;/p&gt;

&lt;p&gt;Docker layer caching can save your team significant time during the build process by bypassing some or all of the image build steps. Docker images are built from Dockerfiles, and each command in the Dockerfile creates a new layer in the image. When you build a Docker image with &lt;code&gt;docker build&lt;/code&gt; or &lt;code&gt;docker compose&lt;/code&gt;, DLC saves the individual layers to a volume attached to the machine or remote Docker instance running the job. The next time you run the image build job, CircleCI will retrieve any unchanged layers from the cache.&lt;/p&gt;

&lt;p&gt;If your Dockerfile stays the same between pipeline runs, the entire image will be retrieved from the cache. If you introduce a change to the Dockerfile between runs, CircleCI will retrieve all the layers up to the change, then build the rest of the image based on the new Dockerfile. The less your Dockerfile changes between runs, the faster your image will build.&lt;/p&gt;

&lt;h2&gt;
  
  
  When should you use Docker layer caching?
&lt;/h2&gt;

&lt;p&gt;Docker containers have fundamentally changed the landscape of software development, allowing teams to build, test, and deploy applications collaboratively, securely, and consistently by packaging binaries and dependencies into a portable unit of software that eliminates the potential for environment conflicts or the “it worked on my machine” conundrum. Many teams have adopted &lt;a href="https://dev.to/blog/benefits-of-containerization/"&gt;containerization&lt;/a&gt; as a way to implement cloud-native development practices and shift their software architecture toward a more distributed approach.&lt;/p&gt;

&lt;p&gt;If your application relies on containers, you may find yourself building the same image on every run of your CI/CD pipeline, which can be a serious drain on your build minutes. By enabling Docker layer caching, you can achieve a significant reduction in build times by reusing cached image layers rather than building them from scratch each time you run your builds.&lt;/p&gt;

&lt;p&gt;Note that DLC will only reduce the time it takes to build your own Docker images with &lt;code&gt;docker build&lt;/code&gt;, &lt;code&gt;docker compose&lt;/code&gt;, or similar docker commands in a remote Docker environment. It does not affect the time it takes to spin up the &lt;a href="https://circleci.com/docs/2.0/glossary/#primary-container"&gt;primary Docker container&lt;/a&gt;. If you are running your pipelines in a Docker container but not building new images as part of your workflow, then you will not see any reduction in build times by implementing DLC.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to add Docker layer caching to your pipelines
&lt;/h2&gt;

&lt;p&gt;You can use Docker layer caching to speed up Docker image builds in both the Docker and the machine execution environments. In the Docker execution environment, any Docker images that you create are built in a secondary container called the remote Docker environment, which adds additional security to the build process and gives you access to a variety of Docker commands as well as the ability to &lt;a href="https://dev.to/blog/debugging-ci-cd-pipelines-with-ssh-access/"&gt;SSH into your builds&lt;/a&gt; for debugging purposes. You can spin up the remote Docker environment with the &lt;code&gt;setup-remote-docker&lt;/code&gt; key, then add Docker layer caching to the build job by setting &lt;code&gt;docker_layer_caching&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: 2
jobs:
  build:
    docker:
      # DLC does nothing here, its caching depends on commonality of the image layers.
      - image: cimg/node:17.3.0
        auth:
        username: mydockerhub-user
          password: $DOCKERHUB_PASSWORD
    steps:
      - checkout
      - setup_remote_docker:
          docker_layer_caching: true
      # DLC will explicitly cache layers here and try to avoid rebuilding.
      - run: docker build .

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

&lt;/div&gt;



&lt;p&gt;In this example &lt;code&gt;config.yml&lt;/code&gt; file, you set &lt;code&gt;docker&lt;/code&gt; as the execution environment for the &lt;code&gt;build&lt;/code&gt; job and set up a remote Docker environment with &lt;code&gt;docker_layer_caching&lt;/code&gt; set to &lt;code&gt;true&lt;/code&gt;. CircleCI will cache the layers of the Docker image you build with the &lt;code&gt;docker build&lt;/code&gt; command so that the next time you run this job, you can avoid rebuilding any unchanged layers.&lt;/p&gt;

&lt;p&gt;The machine execution environment does not require a remote Docker environment to run &lt;code&gt;docker&lt;/code&gt; or &lt;code&gt;docker-compose&lt;/code&gt; commands, so you can include the &lt;code&gt;docker_layer_caching: true&lt;/code&gt; key directly below your machine executor key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: 2
jobs:
  build_elixir:
    machine:
      image: ubuntu-2004:202104-01
      docker_layer_caching: true
    steps:
      - checkout
      - run:
          name: build Elixir image
          command: docker build -t circleci/elixir:example .

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

&lt;/div&gt;



&lt;p&gt;In this example, you set the &lt;code&gt;ubuntu-2004:202104-01&lt;/code&gt; Linux image as your machine executor type, then set &lt;code&gt;docker_layer_caching: true&lt;/code&gt; to enable Docker layer caching for this environment. When you build the Elixir image with the &lt;code&gt;docker build&lt;/code&gt; command, CircleCI will cache the individual layers to be reused in future runs.&lt;/p&gt;

&lt;p&gt;Once you have enabled DLC for your project, any layers that are saved will be available for three days between job runs. Any cached layers that are not reused after three days will be deleted. You can create up to 50 DLC volumes per project. For more information on how to implement Docker layer caching in your projects, as well as some potential use cases and limitations, visit the &lt;a href="https://circleci.com/docs/2.0/docker-layer-caching/"&gt;DLC documentation&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;Docker layer caching is an important part of speeding up your Docker builds on CircleCI and is now included in the CircleCI Free plan. If your team builds containerized applications, you can save valuable development time by reusing unchanged Docker layers within your projects. This not only makes your team more efficient and saves your organization money, but it also helps you deliver value to your users faster, a key differentiator in today’s software development landscape.&lt;/p&gt;

&lt;p&gt;DLC is only one of many different optimizations you can make to your config. Other cache-based optimizations include persisting data in workspaces and caching dependencies for faster builds. For more information on dependency caching, see &lt;a href="https://dev.to/ronpowelljr/config-best-practices-dependency-caching-apj-temp-slug-5820582"&gt;Config best practices: dependency caching&lt;/a&gt;. Stay tuned for other deep dives into available config optimizations in future installments of this series.&lt;/p&gt;

&lt;p&gt;To get started using the most powerful CI/CD platform to build, test, and deploy your applications faster and with more confidence, &lt;a href="https://circleci.com/signup/"&gt;sign up for a free plan&lt;/a&gt; today. If you are interested in an expert-level review of your CircleCI configuration, you can get a personalized, one-on-one evaluation from a dedicated support engineer by signing up for a &lt;a href="https://circleci.com/support/premium-support/"&gt;premium support plan&lt;/a&gt;.&lt;/p&gt;




</description>
      <category>docker</category>
      <category>circleci</category>
      <category>cicd</category>
    </item>
    <item>
      <title>Trigger your CircleCI pipelines from a GitHub Actions workflow</title>
      <dc:creator>Kyle TechSquidTV</dc:creator>
      <pubDate>Fri, 17 Dec 2021 17:30:00 +0000</pubDate>
      <link>https://dev.to/circleci/trigger-your-circleci-pipelines-from-a-github-actions-workflow-1l7j</link>
      <guid>https://dev.to/circleci/trigger-your-circleci-pipelines-from-a-github-actions-workflow-1l7j</guid>
      <description>&lt;p&gt;If you are already a GitHub user, you may know that GitHub Actions provides you with powerful tools to increase efficiencies in your software delivery life cycle. Actions can be impactful for team collaborations and process simplification. For example, you can automate things like building a container, welcoming new users to your open source projects, managing branches, or triaging issues.&lt;/p&gt;

&lt;p&gt;It’s important to use the right tool for the right job. Using GitHub Actions along with CircleCI allows you to automate aspects of your version control system while also benefiting from features that are only available in your CircleCI pipelines. Imagine extending your VCS workflow to include advanced features like &lt;a href="https://dev.to/blog/debugging-ci-cd-pipelines-with-ssh-access/"&gt;SSH debugging&lt;/a&gt;, &lt;a href="https://dev.to/blog/a-guide-to-test-splitting/"&gt;test splitting&lt;/a&gt;, robust &lt;a href="https://circleci.com/docs/2.0/configuration-reference/#resourceclass"&gt;CPU and RAM options&lt;/a&gt; and GPU and &lt;a href="https://dev.to/blog/managing-ci-cd-pipelines-with-arm-compute-resource-classes/"&gt;Arm support&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For example, you can use Actions for team collaboration and process simplification while accelerating your build, test, and deploy stages with CircleCI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NVj-QIiy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://production-cci-com.imgix.net/blog/media/2021-12-17-github-actions-with-circleci.png%3Fixlib%3Drb-3.2.1%26w%3D2000%26auto%3Dformat%26fit%3Dmax%26q%3D60%26ch%3DDPR%252CWidth%252CViewport-Width%252CSave-Data" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NVj-QIiy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://production-cci-com.imgix.net/blog/media/2021-12-17-github-actions-with-circleci.png%3Fixlib%3Drb-3.2.1%26w%3D2000%26auto%3Dformat%26fit%3Dmax%26q%3D60%26ch%3DDPR%252CWidth%252CViewport-Width%252CSave-Data" alt="A Workflow using both GitHub Actions and CircleCI" width="880" height="286"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To make it even easier to kick off your CircleCI pipelines from any event on GitHub, our team built the Trigger CircleCI Pipeline action, which is now &lt;a href="https://github.com/marketplace/actions/trigger-circleci-pipeline"&gt;available in the GitHub Marketplace&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rsJz5vKi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://production-cci-com.imgix.net/blog/media/2021-12-17-trigger-circleci-pipeline-marketplace.png%3Fixlib%3Drb-3.2.1%26w%3D2000%26auto%3Dformat%26fit%3Dmax%26q%3D60%26ch%3DDPR%252CWidth%252CViewport-Width%252CSave-Data" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rsJz5vKi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://production-cci-com.imgix.net/blog/media/2021-12-17-trigger-circleci-pipeline-marketplace.png%3Fixlib%3Drb-3.2.1%26w%3D2000%26auto%3Dformat%26fit%3Dmax%26q%3D60%26ch%3DDPR%252CWidth%252CViewport-Width%252CSave-Data" alt="Trigger CircleCI Pipeline action listing in GitHub Marketplace" width="863" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this article, we will describe a few ways you can incorporate the Trigger CircleCI Pipeline action into your workflow to make the most of your GitHub automation credits while benefiting from CircleCI’s world-class continuous integration capabilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trigger CircleCI Pipeline: A GitHub Action for triggering workflows in CircleCI
&lt;/h2&gt;

&lt;p&gt;With the Trigger CircleCI Pipeline action, you can kick off a CircleCI pipeline from any event on a given branch or tag. The action passes along a set of pipeline parameters containing metadata that can be used to control the flow of your CircleCI pipelines and workflows.&lt;/p&gt;

&lt;p&gt;One potential use case for the Trigger CircleCI Pipeline action is triggering a CircleCI pipeline whenever a pull request is opened by a developer. Triggering on a pull request allows you to test changes in a PR even if the last commit was made prior to the PR being opened (or to trigger a build and test cycle any time changes are pushed to the branch a PR was opened from).&lt;/p&gt;

&lt;p&gt;Another use case for the Trigger CircleCI Pipeline action is triggering a build and deployment from CircleCI whenever a &lt;a href="https://docs.github.com/en/repositories/releasing-projects-on-github/about-releases"&gt;release&lt;/a&gt; is created, edited, or published in GitHub. Triggering on a release allows you to build and deploy an application—such as deploying a Dockerized microservice to a Kubernetes cluster or publishing a binary to an app store—when the repo owner specifies a new release version of the application.&lt;/p&gt;

&lt;p&gt;You can view complete implementations of these two use cases, including templates for both your CircleCI and GitHub Actions configuration files, in the &lt;a href="https://github.com/CircleCI-Public/trigger-circleci-pipeline-action/tree/main/examples"&gt;Examples directory of the Trigger CircleCI Pipeline repository&lt;/a&gt;. Next we’ll explore an example of using the Trigger CircleCI Pipeline Action to initiate a CircleCI workflow when a new release is published.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use the Trigger CircleCI Pipeline Action to trigger a pipeline from a new release
&lt;/h2&gt;

&lt;p&gt;The first step in setting up GitHub Actions to work with CircleCI is to create a GitHub Actions workflow for the desired CircleCI pipeline. You can do this by adding a workflow YAML file (we’ll use &lt;code&gt;main.yml&lt;/code&gt;) to &lt;code&gt;./.github/workflows&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the following example, you use the &lt;code&gt;on&lt;/code&gt; and &lt;code&gt;types&lt;/code&gt; syntax to specify that the &lt;code&gt;trigger-circleci&lt;/code&gt; action triggers when a new release is published. Select a custom &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;id&lt;/code&gt; for the step to provide additional contextual metadata in your CircleCI pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;on:
  release:
    types: [published]
jobs:
  trigger-circleci:
    runs-on: ubuntu-latest
    steps:
      - name: &amp;lt;customize name&amp;gt;
        id: &amp;lt;customize id&amp;gt;
        uses: circleci/trigger_circleci_pipeline@v1.0
        env:
          CCI_TOKEN: $

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

&lt;/div&gt;



&lt;p&gt;Next, create an &lt;a href="https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository"&gt;encrypted secret&lt;/a&gt; named &lt;code&gt;CCI_TOKEN&lt;/code&gt; containing the &lt;a href="https://circleci.com/docs/2.0/managing-api-tokens/"&gt;personal API token&lt;/a&gt; that will be used to trigger the pipelines. We recommend making this a &lt;a href="https://docs.github.com/en/developers/overview/managing-deploy-keys#machine-users"&gt;machine user&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now that you have your GitHub workflow set up, you can modify your CircleCI config file to run when your GitHub Action kicks off. Start by adding the &lt;a href="https://circleci.com/docs/2.0/pipeline-variables/"&gt;pipeline parameter&lt;/a&gt; definitions to your CircleCI config. This data will be entered by the GitHub Action when triggered.&lt;/p&gt;

&lt;p&gt;Add the following to the top of your &lt;code&gt;.circleci/config.yml&lt;/code&gt; file. Make sure you specify version 2.1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: 2.1
parameters:
  GHA_Event:
    type: string
    default: ""
  GHA_Actor:
    type: string
    default: ""
  GHA_Action:
    type: string
    default: ""
  GHA_Meta:
    type: string
    default: ""

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

&lt;/div&gt;



&lt;p&gt;The action generates several pipeline parameters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;GHA_Actor&lt;/code&gt; indicates which user triggered the pipeline.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GHA_Action&lt;/code&gt; is the &lt;code&gt;id&lt;/code&gt; assigned in the workflow configuration.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GHA_Event&lt;/code&gt; is the type of GitHub event that triggered the pipeline.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GHA_Meta&lt;/code&gt; is an optional additional metadata parameter that allows you to specify additional metadata using &lt;a href="https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#inputs"&gt;input parameters&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can use this pipeline parameter data to &lt;a href="https://circleci.com/docs/2.0/pipeline-variables/#conditional-workflows"&gt;run workflows conditionally&lt;/a&gt;. In this example, the &lt;code&gt;GHA_Event&lt;/code&gt; parameter will be populated with the value &lt;code&gt;release&lt;/code&gt;, and you can use a &lt;a href="https://circleci.com/docs/2.0/configuration-reference/#using-when-in-workflows"&gt;&lt;code&gt;when&lt;/code&gt; clause&lt;/a&gt; in your CircleCI config to specify workflows that should run only when triggered by the GitHub workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jobs:
  release:
    docker:
      - image: cimg/node:lts
    steps:
      - run: npm install
      - run: npm build
      - run: npm publish

workflows:
  release:
    when:
      equal: ["release", &amp;lt;&amp;lt; pipeline.parameters.GHA_Event &amp;gt;&amp;gt;]
    jobs:
      - release

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

&lt;/div&gt;



&lt;p&gt;This config snippet specifies a &lt;code&gt;release&lt;/code&gt; job that publishes an npm package and a &lt;code&gt;release&lt;/code&gt; workflow that invokes the &lt;code&gt;release&lt;/code&gt; job. In the &lt;code&gt;when&lt;/code&gt; clause, you specify that the &lt;code&gt;release&lt;/code&gt; workflow will run only when the GitHub workflow runs and populates the &lt;code&gt;GHA_Event&lt;/code&gt; parameter with the value &lt;code&gt;release&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Although this example demonstrates how to set up a release trigger, you can use the same techniques to kick off a CircleCI pipeline from any of the available &lt;a href="https://docs.github.com/en/actions/learn-github-actions/events-that-trigger-workflows"&gt;GitHub events for triggering workflows&lt;/a&gt;. To view the complete setup for triggering CircleCI from events on a pull request, visit the &lt;a href="https://github.com/CircleCI-Public/trigger-circleci-pipeline-action/tree/main/examples/01-Trigger-Workflow-On-Pull_Request"&gt;example GitHub repo&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to prevent double execution of jobs in GitHub and CircleCI
&lt;/h2&gt;

&lt;p&gt;It is important to emphasize that GitHub Actions runs alongside native CircleCI integration. By default, when a repository is connected to CircleCI, if a workflow within that project’s configuration does not specify any conditionals or filters that would otherwise prevent execution, then the workflow will execute on every push event by default. This means that it is possible to accidentally run a job twice, once on the push event from CircleCI and again on other events triggered by the GitHub Action.&lt;/p&gt;

&lt;p&gt;If you are relying on GitHub Actions to provide all of your API triggers, ensure that each of your CircleCI configuration’s workflows contains a conditional limiting its execution to only the GitHub Action trigger, as in the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;workflows:
  # This workflow is set to be triggered conditionally, only when
  # the GitHub Action is triggered.
  # With no other workflows, normal push events will be ignored.
  when: &amp;lt;&amp;lt; pipeline.parameters.GHA_Action &amp;gt;&amp;gt;
  test:
    jobs:
      - test

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

&lt;/div&gt;



&lt;p&gt;Using the &lt;code&gt;when&lt;/code&gt; clause in your workflow declaration allows you to specify that CircleCI should run the workflow only when the specified &lt;code&gt;GHA_Action&lt;/code&gt; is triggered and not after normal push events.&lt;/p&gt;

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

&lt;p&gt;GitHub Actions is a useful tool for automating a variety of version control processes, from checking out a Git repository at a particular version to automatically creating or merging pull requests to updating README files based on changes to your code. With the help of the Trigger CircleCI Pipeline action, you can combine the time-saving benefits of version control automation with the powerful workflow acceleration that only the fastest, most secure, and feature-rich continuous integration platform can provide.&lt;/p&gt;

&lt;p&gt;To add the Trigger CircleCI Pipeline action to your repository, visit the &lt;a href="https://github.com/marketplace/actions/trigger-circleci-pipeline"&gt;GitHub Marketplace&lt;/a&gt; and copy the workflow syntax to your &lt;code&gt;workflow.yml&lt;/code&gt; file. If your team is not already using CircleCI to validate and ship changes to your users quickly and confidently, &lt;a href="https://circleci.com/signup/"&gt;sign up for a free account&lt;/a&gt; today.&lt;/p&gt;

</description>
      <category>githubactions</category>
      <category>circleci</category>
      <category>cicd</category>
    </item>
  </channel>
</rss>
