<?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: Kanishk Tantia</title>
    <description>The latest articles on DEV Community by Kanishk Tantia (@kanishkt123).</description>
    <link>https://dev.to/kanishkt123</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F361843%2F8c048cad-de41-4736-bb5c-a314c2b09f71.jpeg</url>
      <title>DEV Community: Kanishk Tantia</title>
      <link>https://dev.to/kanishkt123</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kanishkt123"/>
    <language>en</language>
    <item>
      <title>Runtime Environment Variables with Github Actions</title>
      <dc:creator>Kanishk Tantia</dc:creator>
      <pubDate>Tue, 29 Sep 2020 19:34:36 +0000</pubDate>
      <link>https://dev.to/kanishkt123/runtime-environment-variables-with-github-actions-2if8</link>
      <guid>https://dev.to/kanishkt123/runtime-environment-variables-with-github-actions-2if8</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/microsoft/code-with-engineering-playbook/blob/master/continuous-delivery/devops-provider-recipes/github-actions/runtime-variables/RuntimeVariables.MD" rel="noopener noreferrer"&gt;Github Repo Link&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Runtime Variables in Github Actions
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Objective
&lt;/h2&gt;

&lt;p&gt;While Github Actions is a popular choice for writing and running CI/CD pipelines, especially for open source projects hosted on Github, it lacks specific quality of life features found in other CI/CD environments. One key feature that Github Actions has not yet implemented is the ability to &lt;strong&gt;mock and inject runtime variables&lt;/strong&gt; into a workflow, in order to test the pipeline itself.&lt;/p&gt;

&lt;p&gt;This provides a bridge between a pre-existing feature in Azure Dev Ops, and one that has not yet released inside Github Actions. &lt;/p&gt;

&lt;h2&gt;
  
  
  Target Audience
&lt;/h2&gt;

&lt;p&gt;This guide assumes that you are familiar with CI/CD, and understand the security implications of CI/CD pipelines. We also assume basic knowledge with Github Actions, including how to write and run a basic CI/CD pipeline, checkout repositories inside the action, use Marketplace Actions with version control, etc.&lt;/p&gt;

&lt;p&gt;We assume that you, as a CI/CD engineer, want to inject environment variables or environment flags into your pipelines and workflows in order to test them, and are using Github Actions to accomplish this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage Scenario
&lt;/h2&gt;

&lt;p&gt;Many integration or end-to-end workflows require specific environment variables that are only available at rutime. For example, a workflow might be doing the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmicrosoft%2Fcode-with-engineering-playbook%2Fmaster%2Fcontinuous-delivery%2Fdevops-provider-recipes%2Fgithub-actions%2Fruntime-variables%2Fimages%2Fworkflow-diagram.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmicrosoft%2Fcode-with-engineering-playbook%2Fmaster%2Fcontinuous-delivery%2Fdevops-provider-recipes%2Fgithub-actions%2Fruntime-variables%2Fimages%2Fworkflow-diagram.png" alt="Workflow Diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this situation, testing the pipeline is extremely difficult without having to make external calls to the resource. In many cases, making external calls to the resource can be expensive or time consuming, significantly slowing down inner loop development.&lt;/p&gt;

&lt;p&gt;Azure Dev Ops, as an example, offers a way to define pipeline variables on a manual trigger:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmicrosoft%2Fcode-with-engineering-playbook%2Fmaster%2Fcontinuous-delivery%2Fdevops-provider-recipes%2Fgithub-actions%2Fruntime-variables%2Fimages%2FAzDoExample.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmicrosoft%2Fcode-with-engineering-playbook%2Fmaster%2Fcontinuous-delivery%2Fdevops-provider-recipes%2Fgithub-actions%2Fruntime-variables%2Fimages%2FAzDoExample.PNG" alt="AzDo Example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Github Actions does not do so yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;To workaround this, the easiest solution is to add runtime variables to either commit messages or the PR Body, and &lt;code&gt;grep&lt;/code&gt; for the variable. Github Actions provides &lt;code&gt;grep&lt;/code&gt; functionality natively using a &lt;code&gt;contains&lt;/code&gt; function, which is what we shall be specifically using.  &lt;/p&gt;

&lt;h4&gt;
  
  
  In scope
&lt;/h4&gt;

&lt;p&gt;We will scope this to injecting a single environment variable into a pipeline, with a previously known key and value. &lt;/p&gt;

&lt;h4&gt;
  
  
  Out of Scope
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;While the solution is obviously extensible using shell scripting or any other means of creating variables, this solution serves well as the proof of the basic concept. No such scripting is provided in this guide.&lt;/li&gt;
&lt;li&gt;Additionally, teams may wish to formalize this process using a PR Template that has an additional section for the variables being provided. This is not however included in this guide.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Security Warning
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;This is NOT for injecting secrets&lt;/strong&gt; as the commit messages and PR body can be retrieved by a third party, are stored in &lt;code&gt;git log&lt;/code&gt;, and can otherwise be read by a malicious individual using a variety of tools. Rather, this is for testing a workflow that needs simple variables to be injected into it, as above.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you need to retrieve secrets or sensitive information&lt;/strong&gt;, use the &lt;a href="https://github.com/marketplace/actions/azure-key-vault-get-secrets" rel="noopener noreferrer"&gt;Github Action for Azure Key Vault&lt;/a&gt; or some other similar secret storage and retrieval service.&lt;/p&gt;

&lt;h3&gt;
  
  
  Commit Message Variables
&lt;/h3&gt;

&lt;p&gt;How to inject a single variable into the environment for use, with a &lt;strong&gt;specified key and value.&lt;/strong&gt; In this example, the key is &lt;code&gt;COMMIT_VAR&lt;/code&gt; and the value is &lt;code&gt;[commit var]&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Pre-requisites
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Pipeline triggers are correctly set up to trigger on pushed commits (Here we will use &lt;code&gt;actions-test-branch&lt;/code&gt; as the branch of choice)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Code Snippet
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;on:
  push:
    branches:
      - actions-test-branch

jobs:
  Echo-On-Commit:
    runs-on: ubuntu-latest
    steps:
      - name: "Checkout Repository"
        uses: actions/checkout@v2

      - name: "Set flag from Commit"
        env:
          COMMIT_VAR: ${{ contains(github.event.head_commit.message, '[commit var]') }}
        run: |
          if ${COMMIT_VAR} == true; then
            echo "::set-env name=flag::true"
            echo "flag set to true"
          else
            echo "::set-env name=flag::false"
            echo "flag set to false"
          fi

      - name: "Use flag if true"
        if: env.flag
        run: echo "Flag is available and true"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Available as a .YAML &lt;a href="https://github.com/microsoft/code-with-engineering-playbook/tree/master/continuous-delivery/devops-provider-recipes/github-actions/runtime-variables/examples/commit-example.yaml" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Code Explanation
&lt;/h4&gt;

&lt;p&gt;The first part of the code is setting up Push triggers on the working branch and checking out the repository, so we will not explore that in detail.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  - name: "Set flag from Commit"
    env:
      COMMIT_VAR: ${{ contains(github.event.head_commit.message, '[commit var]') }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a named step inside the only Job in our Github Actions pipeline. Here, we set an environment variable for the step: Any code or action that the step calls will now have the environment variable available.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;contains&lt;/code&gt; is a Github Actions function that is available by default in all workflows. It returns a Boolean &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt; value. In this situation, it checks to see if the commit message on the last push, accessed using &lt;code&gt;github.event.head_commit.message&lt;/code&gt;. The &lt;code&gt;${{...}}&lt;/code&gt; is necessary to use the Github Context and make the functions and &lt;code&gt;github.event&lt;/code&gt; variables available for the command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  run: |
    if ${COMMIT_VAR} == true; then
      echo "::set-env name=flag::true"
      echo "flag set to true"
    else
      echo "::set-env name=flag::false"
      echo "flag set to false"
    fi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;run&lt;/code&gt; command here checks to see if the &lt;code&gt;COMMIT_VAR&lt;/code&gt; variable has been set to &lt;code&gt;true&lt;/code&gt;, and if it has, it sets a secondary flag to true, and echoes this behavior. It does the same if the variable is &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The specific reason to do this is to allow for the &lt;code&gt;flag&lt;/code&gt; variable to be used in further steps instead of having to reuse the &lt;code&gt;COMMIT_VAR&lt;/code&gt; in every step. Further, it allows for the flag to be used in the &lt;code&gt;if&lt;/code&gt; step of an action, as in the next part of the snippet.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: "Use flag if true"
  if: env.flag
  run: echo "Flag is available and true"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this part of the snippet, the next step in the same job is now using the &lt;code&gt;flag&lt;/code&gt; that was set in the previous step. This allows the user to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reuse the flag instead of repeatedly accessing the Github Context&lt;/li&gt;
&lt;li&gt;Set the flag using multiple conditions, instead of just one. For example, a different step might ALSO set the flag to &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt; for different reasons. &lt;/li&gt;
&lt;li&gt;Change the variable in exactly one place instead of having to change it in multiple places&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Shorter Alternative
&lt;/h4&gt;

&lt;p&gt;The "Set flag from commit" step can be simplified to the following in order to make the code much shorter, although not necessarily more readable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: "Set flag from Commit"
  env:
    COMMIT_VAR: ${{ contains(github.event.head_commit.message, '[commit var]') }}
  run: |
    echo "::set-env name=flag::${COMMIT_VAR}"
    echo "set flag to ${COMMIT_VAR}"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Usage
&lt;/h4&gt;

&lt;h5&gt;
  
  
  Including the Variable
&lt;/h5&gt;

&lt;ol&gt;
&lt;li&gt;Push to branch &lt;code&gt;master&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; git add.
&amp;gt; git commit -m "Running Github Actions Test [commit var]"
&amp;gt; git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;This triggers the workflow (as will any push). As the &lt;code&gt;[commit var]&lt;/code&gt; is in the commit message, the &lt;code&gt;${COMMIT_VAR}&lt;/code&gt; variable in the workflow will be set to &lt;code&gt;true&lt;/code&gt; and result in the following:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmicrosoft%2Fcode-with-engineering-playbook%2Fmaster%2Fcontinuous-delivery%2Fdevops-provider-recipes%2Fgithub-actions%2Fruntime-variables%2Fimages%2FCommitTrue.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmicrosoft%2Fcode-with-engineering-playbook%2Fmaster%2Fcontinuous-delivery%2Fdevops-provider-recipes%2Fgithub-actions%2Fruntime-variables%2Fimages%2FCommitTrue.PNG" alt="Commit True Scenario"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  Not Including the Variable
&lt;/h5&gt;

&lt;ol&gt;
&lt;li&gt;Push to  branch &lt;code&gt;master&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; git add.
&amp;gt; git commit -m "Running Github Actions Test"
&amp;gt; git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;This triggers the workflow (as will any push). As the &lt;code&gt;[commit var]&lt;/code&gt; is &lt;strong&gt;not&lt;/strong&gt; in the commit message, the &lt;code&gt;${COMMIT_VAR}&lt;/code&gt; variable in the workflow will be set to &lt;code&gt;false&lt;/code&gt; and result in the following:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmicrosoft%2Fcode-with-engineering-playbook%2Fmaster%2Fcontinuous-delivery%2Fdevops-provider-recipes%2Fgithub-actions%2Fruntime-variables%2Fimages%2FCommitFalse.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmicrosoft%2Fcode-with-engineering-playbook%2Fmaster%2Fcontinuous-delivery%2Fdevops-provider-recipes%2Fgithub-actions%2Fruntime-variables%2Fimages%2FCommitFalse.PNG" alt="Commit False Scenario"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  PR Body Variables
&lt;/h3&gt;

&lt;p&gt;When a PR is made, the PR Body can also be used to setup variables. These variables can be made available to all the workflow runs that stem from that PR, which can help ensure that commit messages are more informative and less cluttered, and reduces the work on the developer.&lt;/p&gt;

&lt;p&gt;Once again, this for an expected key and value. In this case, the key is &lt;code&gt;PR_VAR&lt;/code&gt; and the value is &lt;code&gt;[pr var]&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Pre-requisites
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Pipeline triggers are correctly set up to trigger on a pull request into a specific branch. (Here we will use master as the destination branch.)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Code Snippet
&lt;/h4&gt;



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

jobs:
  Echo-On-PR:
    runs-on: ubuntu-latest
    steps:
      - name: "Checkout Repository"
        uses: actions/checkout@v2

      - name: "Set flag from PR"
        env:
          PR_VAR: ${{ contains(github.event.pull_request.body, '[pr var]') }}
        run: |
          if ${PR_VAR} == true; then
            echo "::set-env name=flag::true"
            echo "flag set to true"
          else
            echo "::set-env name=flag::false"
            echo "flag set to false"
          fi

      - name: "Use flag if true"
        if: env.flag
        run: echo "Flag is available and true"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Available as a .YAML &lt;a href="https://github.com/microsoft/code-with-engineering-playbook/tree/master/continuous-delivery/devops-provider-recipes/github-actions/runtime-variables/examples/pr-example.yaml" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Code Explanation
&lt;/h4&gt;

&lt;p&gt;The first part of the YAML file simply sets up the Pull Request Trigger. The majority of the following code is identical, so we will only explain the differences.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: "Set flag from PR"
  env:
    PR_VAR: ${{ contains(github.event.pull_request.body, '[pr var]') }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this section, the &lt;code&gt;PR_VAR&lt;/code&gt; environment variable is set to &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt; depending on whether or not the &lt;code&gt;[pr var]&lt;/code&gt; string is in the PR Body.&lt;/p&gt;

&lt;h4&gt;
  
  
  Shorter Alternative
&lt;/h4&gt;

&lt;p&gt;Similarly to the above, the YAML step can be simplified to the following in order to make the code much shorter, although not necessarily more readable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: "Set flag from PR"
  env:
    PR_VAR: ${{ contains(github.event.pull_request.body, '[pr var]') }}
  run: |
  echo "::set-env name=flag::${PR_VAR}"
  echo "set flag to ${PR_VAR}"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Usage
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Create a Pull Request into &lt;code&gt;master&lt;/code&gt;, and include the expected variable in the body somewhere:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmicrosoft%2Fcode-with-engineering-playbook%2Fmaster%2Fcontinuous-delivery%2Fdevops-provider-recipes%2Fgithub-actions%2Fruntime-variables%2Fimages%2FPRExample.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmicrosoft%2Fcode-with-engineering-playbook%2Fmaster%2Fcontinuous-delivery%2Fdevops-provider-recipes%2Fgithub-actions%2Fruntime-variables%2Fimages%2FPRExample.PNG" alt="PR Example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The Github Action will trigger automatically, and since &lt;code&gt;[pr var]&lt;/code&gt; is present in the PR Body, it will set the &lt;code&gt;flag&lt;/code&gt; to true, as shown below:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmicrosoft%2Fcode-with-engineering-playbook%2Fmaster%2Fcontinuous-delivery%2Fdevops-provider-recipes%2Fgithub-actions%2Fruntime-variables%2Fimages%2FPRTrue.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmicrosoft%2Fcode-with-engineering-playbook%2Fmaster%2Fcontinuous-delivery%2Fdevops-provider-recipes%2Fgithub-actions%2Fruntime-variables%2Fimages%2FPRTrue.PNG" alt="PR True"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Real World Scenarios
&lt;/h3&gt;

&lt;p&gt;There are many real world scenarios where controlling environment variables can be extremely useful. Some are outlined below:&lt;/p&gt;

&lt;h4&gt;
  
  
  Avoiding Expensive External Calls
&lt;/h4&gt;

&lt;p&gt;Developer A is in the process of writing and testing an integration pipeline. The integration pipeline needs to make a call to an external service such as Azure Data Factory or Databricks, wait for a result, and then echo that result. The workflow could look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmicrosoft%2Fcode-with-engineering-playbook%2Fmaster%2Fcontinuous-delivery%2Fdevops-provider-recipes%2Fgithub-actions%2Fruntime-variables%2Fimages%2FDevAWorkflow.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmicrosoft%2Fcode-with-engineering-playbook%2Fmaster%2Fcontinuous-delivery%2Fdevops-provider-recipes%2Fgithub-actions%2Fruntime-variables%2Fimages%2FDevAWorkflow.png" alt="Workflow A"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The workflow inherently takes time and is expensive to run, as it involves maintaining a Databricks cluster while also waiting for the response. This external dependency can be removed by essentially mocking the response for the duration of writing and testing other parts of the workflow, and mocking the response in situations where the actual response either does not matter, or is not being directly tested.&lt;/p&gt;

&lt;h4&gt;
  
  
  Skipping Long CI processes
&lt;/h4&gt;

&lt;p&gt;Developer B is in the process of writing and testing a CI/CD pipeline. The pipeline has multiple CI stages, each of which runs sequentially. The workflow might look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmicrosoft%2Fcode-with-engineering-playbook%2Fmaster%2Fcontinuous-delivery%2Fdevops-provider-recipes%2Fgithub-actions%2Fruntime-variables%2Fimages%2FDevBWorkflow.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmicrosoft%2Fcode-with-engineering-playbook%2Fmaster%2Fcontinuous-delivery%2Fdevops-provider-recipes%2Fgithub-actions%2Fruntime-variables%2Fimages%2FDevBWorkflow.png" alt="Workflow B"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this case, each CI stage needs to run before the next one starts, and errors in the middle of the process can cause the entire pipeline to fail. While this might be intended behavior for the pipeline in some situations (Perhaps you don't want to run a more involved, longer build or run a time consuming test coverage suite if the CI process is failing), it means that steps need to be commented out or deleted when testing the pipeline itself.&lt;/p&gt;

&lt;p&gt;Instead, an additional step could check for a &lt;code&gt;[skip ci $N]&lt;/code&gt; tag in either the commit messages or PR Body, and skip a specific stage of the CI build. This ensures that the final pipeline does not have changes committed to it that render it broken, as sometimes happens when commenting out/deleting steps. It additionally allows for a mechanism to repeatedly test individual steps by skipping the others, making developing the pipeline significantly easier.&lt;/p&gt;

</description>
      <category>github</category>
      <category>githubactions</category>
      <category>variables</category>
      <category>runtime</category>
    </item>
  </channel>
</rss>
