<?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: Liam Conroy Hampton</title>
    <description>The latest articles on DEV Community by Liam Conroy Hampton (@liamchampton).</description>
    <link>https://dev.to/liamchampton</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%2F407456%2F26d720ee-0e84-46d0-9c76-05bf5b62e703.jpeg</url>
      <title>DEV Community: Liam Conroy Hampton</title>
      <link>https://dev.to/liamchampton</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/liamchampton"/>
    <language>en</language>
    <item>
      <title>What is the difference between the Azure Command Line Interface and Azure Developer Command Line Interface?</title>
      <dc:creator>Liam Conroy Hampton</dc:creator>
      <pubDate>Mon, 24 Jul 2023 14:18:30 +0000</pubDate>
      <link>https://dev.to/liamchampton/what-is-the-difference-between-the-azure-command-line-interface-and-azure-developer-command-line-interface-5cl3</link>
      <guid>https://dev.to/liamchampton/what-is-the-difference-between-the-azure-command-line-interface-and-azure-developer-command-line-interface-5cl3</guid>
      <description>&lt;p&gt;Let's start by saying they are both great developer tools for Azure and they both allow you to interact with services in two different ways. So let's dig into what they are and when you should use them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the &lt;a href="https://aka.ms/az-blog-what-is-az" rel="noopener noreferrer"&gt;Azure Command Line Interface&lt;/a&gt; (Az CLI)?
&lt;/h2&gt;

&lt;p&gt;The Azure (CLI) is a command-line tool that you can use to manage and control your Azure resources directly from the terminal. It is a cross-platform tool that can be installed in a number of ways (Windows, Mac, Linux, Docker and Azure Cloud Shell).&lt;/p&gt;

&lt;p&gt;However, it doesn't stop there. You are also able to install a number of extensions to add additional functionality to the Azure CLI. Some examples of extensions are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Azure Interactive Mode&lt;/li&gt;
&lt;li&gt;Azure DevOps&lt;/li&gt;
&lt;li&gt;Azure Kubernetes Service&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A full list of extensions can be found &lt;a href="https://aka.ms/az-blog-az-extensions" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;My personal favourite is the Azure Interactive Mode, an AI based extension. You can checkout my blog post on this here: &lt;a href="https://dev.to/liamchampton/step-by-step-how-to-setup-and-use-azure-cli-interactive-mode-292e"&gt;https://dev.to/liamchampton/step-by-step-how-to-setup-and-use-azure-cli-interactive-mode-292e&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When using the Azure CLI you would use the alias &lt;code&gt;az&lt;/code&gt; and a subcommand typically follows for an action to take. This is just a few of the commands available to you and you can manage almost all of your Azure resources using the Azure CLI.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Example use case of the Azure CLI
&lt;/h3&gt;

&lt;p&gt;A typical example of when to use the Azure CLI is if you are creating a simple resource group that will hold a Virtual Machine and you need complete control over the commands being executed and how this Virtual Machine will be deployed.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the &lt;a href="https://aka.ms/az-blog-what-is-azd" rel="noopener noreferrer"&gt;Azure Developer Command Line Interface&lt;/a&gt; (Azd CLI)?
&lt;/h2&gt;

&lt;p&gt;The Azure Developer CLI is a tool primarily developer-centric. This tool is aimed at creating and deploying Azure applications and infrastructure using only a handful of commands. The Azd CLI is open-source and has 3 main goals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduce the time required for a developer to be productive&lt;/li&gt;
&lt;li&gt;Demonstrate opinionated best practices for Azure development&lt;/li&gt;
&lt;li&gt;Help developers understand core Azure development constructs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When using the Azd CLI you would typically follow this workflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Select a template - This template will be written in Bicep or Terraform and it outlines the infrastructure you want to deploy within Azure.&lt;/li&gt;
&lt;li&gt;Login to Azure using the command &lt;code&gt;azd auth login&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Run the command &lt;code&gt;azd init&lt;/code&gt; and it will initialise the project with the selected template.&lt;/li&gt;
&lt;li&gt;Package it all up, provision and deploy the application using the command &lt;code&gt;azd up&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As you continue to iterate, write code and develop your solutions you can continue to update your deployed application by only running the command &lt;code&gt;azd deploy&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you happen to change the underlying infrastructure files then you only need to run the command &lt;code&gt;azd provision&lt;/code&gt; again and it will handle the rest for you.&lt;/p&gt;

&lt;p&gt;Here are some of the commands available to you when using the Azd CLI:&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Example use case of the Azure Developer CLI
&lt;/h3&gt;

&lt;p&gt;A typical use case of the Azd CLI is if you have a full application consisting of multiple complex services that all connect to one anther and will be a very arduous task to set them up manually in the portal or through many Azure CLI commands. This would also bode well if you are working in a distributed team and you want to ensure everyone is using the same infrastructure and application code.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to use the Azure CLI and when to use the Azure Developer CLI?
&lt;/h2&gt;

&lt;p&gt;Both CLI's allow you to deploy services and infrastructure to Azure. However, the Azure CLI is more of a general purpose tool that allows you to manage and control your Azure resources directly from the terminal with a lot of freedom to edit, change and have more of a granular control over each command executed. The Azure Developer CLI is more of a developer-centric tool with a focus on speeding up deployments by having a lot of the dots connected for you within a single application. This isn't to say you lack control but you certainly have less to worry about when it comes to the deployment process.&lt;/p&gt;

&lt;p&gt;Happy terminal'ing!&lt;/p&gt;

&lt;p&gt;If you have any questions or some feedback, I'd love to hear so feel free to drop me a line 📝&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/liamchampton" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/liam-conroy-hampton/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/p&gt;

</description>
      <category>azure</category>
      <category>cli</category>
      <category>developer</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Step-by-Step: How to setup and use Azure CLI Interactive mode</title>
      <dc:creator>Liam Conroy Hampton</dc:creator>
      <pubDate>Thu, 13 Jul 2023 11:55:47 +0000</pubDate>
      <link>https://dev.to/liamchampton/step-by-step-how-to-setup-and-use-azure-cli-interactive-mode-292e</link>
      <guid>https://dev.to/liamchampton/step-by-step-how-to-setup-and-use-azure-cli-interactive-mode-292e</guid>
      <description>&lt;p&gt;The Azure Command Line Interface (CLI) is a developer tool that allows users to control Azure services using command line commands. It is a cross-platform tool that can be installed in a number of ways (Windows, Mac, Linux, Docker and Azure Cloud Shell).&lt;/p&gt;

&lt;p&gt;It also has the ability to have a number of extensions installed to add additional functionality, assisting with your development and deployments to the cloud. One of these extensions is the newly released AZ Interactive extension that is &lt;strong&gt;now in preview&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Useful links:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aka.ms/azi-blog-install-az-cli" rel="noopener noreferrer"&gt;Install Azure CLI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aka.ms/azi-blog-documentation" rel="noopener noreferrer"&gt;Azure CLI Interactive documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aka.ms/azi-blog-github-guide" rel="noopener noreferrer"&gt;Azure Interactive GitHub Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is AZ Interactive?
&lt;/h2&gt;

&lt;p&gt;Using any CLI can sometimes be cumbersome, especially if you are new to the tool. AZ Interactive is a new AI-based extension for the Azure CLI and somewhat of a cheat code for developers. It allows you to interact with Azure resources in a more interactive and intuitive way than usual. It is a great tool for those who are new to the Azure CLI and want to learn how to use it, or for those who are more experienced and want to be more efficient.&lt;/p&gt;

&lt;p&gt;It sets out to solve a few problems that developers face when using the Azure CLI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Discoverability of services, commands and parameters&lt;/li&gt;
&lt;li&gt;Reducing the time taken to learn the Azure CLI and its commands&lt;/li&gt;
&lt;li&gt;Speed up the process of writing commands and deploying resources&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;To use AZ Interactive, you will need to have the Azure CLI installed. You can find instructions on how to install the Azure CLI &lt;a href="https://aka.ms/azi-blog-install-az-cli" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing AZ Interactive
&lt;/h2&gt;

&lt;p&gt;To install the AZ Interactive extension, you will need to run the following command from your terminal (once you have the Azure CLI installed):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az extension add &lt;span class="nt"&gt;--name&lt;/span&gt; interactive &lt;span class="nt"&gt;--upgrade&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will install the extension and any dependencies that are required. Once the installation is complete, you can run the following command to start the interactive mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az interactive
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those are the only commands you need to install and start using AZ Interactive. It is that simple!&lt;/p&gt;

&lt;p&gt;Once you have it running, your terminal will look something like this:&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Using AZ Interactive
&lt;/h2&gt;

&lt;p&gt;Now you have this awesome tool installed, what sort of super power does it provide? Let's take a look at some of the features.&lt;/p&gt;

&lt;h3&gt;
  
  
  Command Suggestions
&lt;/h3&gt;

&lt;p&gt;One of the great features of AZ Interactive is the command suggestions. As you type, it will suggest commands that match what you have typed. It is somewhat similar to tab completion you may find in other tools, but it is a lot more intuitive and it will match commands based on what you have typed so far and allow you to chose from a list.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Command Scenarios
&lt;/h3&gt;

&lt;p&gt;Another great feature of AZ Interactive is the command scenarios. This is where AZ Interactive allows you to select a scenario and then it will guide you through the process of creating the resources required for that scenario and provide you with the commands needed to do so.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Search for commands and scenarios
&lt;/h3&gt;

&lt;p&gt;You also have a search capability that allows you to search for commands, parameters and resources. This is great if you know what you are looking for and want to have the CLI generate the command(s) for you. For instance, if you search with the prompt "connect an app service to mongodb", it will generate a number of commands within a scenario that you can run.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Running commands outside of interactive mode
&lt;/h3&gt;

&lt;p&gt;You may notice that you are abstracted away from your normal terminal shell at this point and tucked into an "az interactive" shell. This does not mean that you cannot run commands outside of interactive mode. You can run any command you like by prefixing it with "#". This will run the command as normal and return the output to the terminal for you. For example, if I want to know my current working directory, I would typically run the command "pwd". In interactive mode, I would run "#pwd" and it would return the output to the terminal in the same manner.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  JMESPath query support
&lt;/h3&gt;

&lt;p&gt;This is a powerful feature and probably one of my favourites. JMESPath is a query language for JSON that allows you to extract and transform elements of JSON. AZ Interactive supports JMESPath queries and allows you to run them against the output of commands. This is great if you want to filter the output of a command to only return the data you are interested in. For example, if I want to get a the name of my resource group from the JSON object returned in a previous command I can do just that by using &lt;code&gt;??name&lt;/code&gt; as seen in the example below.&lt;/p&gt;

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

&lt;p&gt;This is not all either. You can also use this to inject jmespath query into future commands allowing you to use this data throughout your session. For example, if I want to get the name of my resource group and use it in a command to delete the resource group, I can do that by using &lt;code&gt;??name&lt;/code&gt; in the command as seen below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foa6u63trhtqvd411gjpc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foa6u63trhtqvd411gjpc.png" alt="azure interactive jmespath query support in a new command" width="800" height="689"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Status codes
&lt;/h3&gt;

&lt;p&gt;When running terminal commands you may be used to seeing a status code returned. This is a number that indicates whether the command was successful or not. This is also supported within this extension and you can find the previous status code of each command by simply using the &lt;code&gt;$&lt;/code&gt; symbol. This will return the status code of the previous command.&lt;/p&gt;

&lt;p&gt;I previously ran a command to delete a resource group and it returned a status code of 0, indicating that the command was successful.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Setting Scope
&lt;/h3&gt;

&lt;p&gt;When you are working within a certain command group you can set the scope of the commands. This means that you can run commands without having to specify the command group every time. For example, if I want to run a number of commands to work within resource groups, I can set the scope to be groups using the command &lt;code&gt;%% group&lt;/code&gt;. From there, I can run any command within that group without having to specify the prefix every time. This saves time and acts as a shorthand for you.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Fun colour themes
&lt;/h3&gt;

&lt;p&gt;This is a fun way to spice up your terminal. You have the ability to change the colours you want to use with a number of different styles. This changes the text colour, drop down lists and more!&lt;/p&gt;

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

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

&lt;p&gt;By default, all of the AI capabilities are turned on but if you are not a fan of having all the noise in your terminal and you want to get back to the basics, you can turn it off by running the command &lt;code&gt;az config set interactive.enable_recommender=False&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Overall this is a great tool to use and I would highly recommend it to anyone who is new to the Azure CLI or wants to speed up their development and deployment processes from within the terminal. It is a great tool to have in your arsenal and I am sure it will only get better as it is developed further.&lt;/p&gt;

&lt;p&gt;For more examples of how to use the Azure CLI Interactive mode, you can checkout the documentation &lt;a href="https://aka.ms/azi-blog-documentation" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy terminal'ing!&lt;/p&gt;

&lt;p&gt;If you have any questions or some feedback, I'd love to hear so feel free to drop me a line 📝&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/liamchampton" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/liam-conroy-hampton/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/p&gt;

</description>
      <category>terminal</category>
      <category>azure</category>
      <category>cli</category>
      <category>ai</category>
    </item>
    <item>
      <title>Unit Testing - Table Tests in Go</title>
      <dc:creator>Liam Conroy Hampton</dc:creator>
      <pubDate>Thu, 27 May 2021 15:29:14 +0000</pubDate>
      <link>https://dev.to/liamchampton/unit-testing-table-tests-in-go-2nmo</link>
      <guid>https://dev.to/liamchampton/unit-testing-table-tests-in-go-2nmo</guid>
      <description>&lt;p&gt;There are many types of testing that takes place throughout the software development lift cycle (SDLC) but in this post I will concentrate on table testing within unit tests. &lt;/p&gt;

&lt;p&gt;First let’s look at WHAT test cases are, specifically unit testing. Unit testing is a granular level of testing within your project. It tests the individual parts of the puzzle for fitment and correctness - "Does this function behave how I expect it to behave?". &lt;/p&gt;

&lt;p&gt;WHY do we use unit testing? - The aim of unit testing is to get high code coverage and check each moving part of your program. You shouldn't need to run your program everytime you want to check one small piece of functionality. That is only a good way to test "the happy path", its manual and time consuming. So, what if things don’t go as expected? You should be able to test failures and handle unexpected output from the operating function. With unit testing, you can do this, and you should do this.&lt;/p&gt;

&lt;p&gt;In practise, unit testing is a must but it can get messy very quickly. I will show you using an example function below.&lt;/p&gt;

&lt;h2&gt;
  
  
  Function
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"Liam"&lt;/span&gt;
    &lt;span class="n"&gt;reversedStr&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;reverseString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reversedStr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;reverseString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;reversedStr&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;reversedStr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;reversedStr&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;reversedStr&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function will take the string "Liam" and reverse it. The result of running this program should be "maiL".&lt;/p&gt;

&lt;p&gt;So lets write some tests for the &lt;code&gt;reverseString()&lt;/code&gt; function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test Function
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"testing"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestReverseString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"reverse of Liam"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"Liam"&lt;/span&gt;
        &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"maiL"&lt;/span&gt;
        &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;reverseString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"expected %s, got %s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"reverse of foobar"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"foobar"&lt;/span&gt;
        &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"raboof"&lt;/span&gt;
        &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;reverseString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"expected %s, got %s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"reverse of testing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"testing"&lt;/span&gt;
        &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"gnitset"&lt;/span&gt;
        &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;reverseString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"expected %s, got %s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see by the tests above; with only 3 test cases this is quite a lot of code. This is still valid, but it is long and messy. Just imagine what these tests might look like if the original function was a bit more complex.&lt;/p&gt;

&lt;p&gt;Let’s simplify these cases with a table test.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test Function Simplified
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestReverseString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;tests&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;input&lt;/span&gt;  &lt;span class="kt"&gt;string&lt;/span&gt;
        &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="p"&gt;}{&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Liam"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"maiL"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"foobar"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"raboof"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"testing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"gnitset"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;testCase&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;tests&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;reverseString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;testCase&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;testCase&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"expected %s, got %s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That looks much better but what did I just do?&lt;/p&gt;

&lt;p&gt;To begin with, I created a struct that houses each individual test case input and expected output of the type &lt;code&gt;string&lt;/code&gt;. This is what the original function expects as input and what it returns as an output.&lt;/p&gt;

&lt;p&gt;Next, I created a range loop. This loop iterates through the test cases in the &lt;code&gt;struct&lt;/code&gt; containing the &lt;code&gt;input / output&lt;/code&gt;. Inside the loop is a single test case that will be fed the &lt;code&gt;input / output&lt;/code&gt; for each test case from the &lt;code&gt;struct&lt;/code&gt;. The code inside the loop is the same code used in the first set of test cases but introducing the loop removes the need to duplicate test cases if the only part changing is the input / output.&lt;/p&gt;

&lt;p&gt;Just like that, I have simplified the tests, made them easier to follow and easier to ammend.&lt;/p&gt;

&lt;p&gt;This code can be found at &lt;a href="https://github.com/liamchampton/go-string-manipulation" rel="noopener noreferrer"&gt;https://github.com/liamchampton/go-string-manipulation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have any questions or want to see more content like this, feel free to drop me a line 📝&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/liamchampton" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; | &lt;a href="https://twitter.com/liamchampton" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; | &lt;a href="https://www.instagram.com/liamhampton/" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt; | &lt;a href="//www.linkedin.com/in/liam-conroy-hampton"&gt;LinkedIn&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>testing</category>
      <category>go</category>
      <category>devops</category>
    </item>
    <item>
      <title>Deploy your Application using GitHub Actions</title>
      <dc:creator>Liam Conroy Hampton</dc:creator>
      <pubDate>Mon, 10 May 2021 15:49:08 +0000</pubDate>
      <link>https://dev.to/liamchampton/deploy-your-application-using-github-actions-55hh</link>
      <guid>https://dev.to/liamchampton/deploy-your-application-using-github-actions-55hh</guid>
      <description>&lt;p&gt;To make it easier for you to consume I have created this tutorial by breaking it down into bite size chunks in GitHub. It makes a bit more sense and makes reading / following the workshop a little easier, as opposed to having a long thread of pictures and code snippets. &lt;strong&gt;Everything in this tutorial is free - no credit card is needed at all&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Workshop Links:
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Workshop Tutorial
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/IBMDeveloperUK" rel="noopener noreferrer"&gt;
        IBMDeveloperUK
      &lt;/a&gt; / &lt;a href="https://github.com/IBMDeveloperUK/Deploy-To-IBM-Cloud-With-GitHub-Actions" rel="noopener noreferrer"&gt;
        Deploy-To-IBM-Cloud-With-GitHub-Actions
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Deploy applications to IBM Cloud Foundry using GitHub Actions
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


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


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/liamchampton" rel="noopener noreferrer"&gt;
        liamchampton
      &lt;/a&gt; / &lt;a href="https://github.com/liamchampton/github-actions-demo" rel="noopener noreferrer"&gt;
        github-actions-demo
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Demo the use of GitHub Actions into IBM Cloud Foundry
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;





&lt;p&gt;The purpose of this tutorial is to show you how to create a small Go application on your system and then deploy it into IBM Cloud Foundry using GitHub Actions.&lt;/p&gt;

&lt;p&gt;In this tutorial there are a few bits of tech involved.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://ibm.biz/BdffAw" rel="noopener noreferrer"&gt;IBM Cloud&lt;/a&gt; - The cloud provider of choice&lt;/li&gt;
&lt;li&gt;IBM Cloud Foundry - The cloud service&lt;/li&gt;
&lt;li&gt;Golang Application (or an application of your choice)&lt;/li&gt;
&lt;li&gt;GitHub platform - The code repository platform&lt;/li&gt;
&lt;li&gt;GitHub Actions - The platform service&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://www.ibm.com/cloud/cloud-foundry" rel="noopener noreferrer"&gt;IBM Cloud Foundry&lt;/a&gt; is a neat tool that allows you to run your apps in the cloud with very little hassle. You essentially create the app you wish to run in the cloud, set up a small config file (this is optional) and then you push it into IBM Cloud via the CLI. It's a sleek process as far as Cloud deployments are concerned. IBM Cloud Foundry is free to use, and it is included in the Lite Tier account which you can &lt;a href="https://ibm.biz/BdffAw" rel="noopener noreferrer"&gt;sign up&lt;/a&gt; for free. Check out the &lt;a href="https://cloud.ibm.com/docs/cloud-foundry-public" rel="noopener noreferrer"&gt;docs&lt;/a&gt; for more information and supported runtimes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; is a great code repository platform which is widely used by developers all over the world. A fantastic feature within GitHub is called GitHub Actions. GitHub Actions is essentially a pipeline tool integrated into GitHub allowing you to deploy your code into an environment of your choice. This is the beginning  of your CI/CD journey with your application.&lt;/p&gt;

&lt;p&gt;To do this, you need to create a workflow configuration file outlining the platform and all the configurations you need and then specify how to deploy your application. Much like other pipeline tooling, it has images and buildpacks available for you to use.&lt;/p&gt;

&lt;h2&gt;
  
  
  A possible use case
&lt;/h2&gt;

&lt;p&gt;You have just built your amazing personal website and manually deployed it into the cloud hosting provider. It outlines your achievements, your personal projects, and your work history.&lt;/p&gt;

&lt;p&gt;This works well for the time being as it holds current, up-to-date information. But let's say you have just earned a new qualification and you want it to add it to your website. You will now need to write the new code, wrap it up, push the code into GitHub and then manually deploy it again.&lt;/p&gt;

&lt;p&gt;This is where GitHub Actions comes in. It will automate the last part for you. All you should do is focus on writing the code. Let the deployment be taken care for you.&lt;/p&gt;

&lt;p&gt;This is just one example and running the risk of turning this blog into a DevOps discussion but that is another can of worms for another time. I hope you enjoy the workshop tutorial and find is useful! 🎉&lt;/p&gt;

&lt;p&gt;If you have any questions or want to see more content like this, feel free to drop me a line 📝&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/liamchampton" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; | &lt;a href="https://twitter.com/liamchampton" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; | &lt;a href="https://www.instagram.com/liamhampton/" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt; | &lt;a href="//www.linkedin.com/in/liam-conroy-hampton"&gt;LinkedIn&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>cloud</category>
      <category>github</category>
      <category>pipeline</category>
    </item>
    <item>
      <title>Interacting with IBM Cloud</title>
      <dc:creator>Liam Conroy Hampton</dc:creator>
      <pubDate>Mon, 29 Mar 2021 16:20:23 +0000</pubDate>
      <link>https://dev.to/liamchampton/interacting-with-ibm-cloud-3bf9</link>
      <guid>https://dev.to/liamchampton/interacting-with-ibm-cloud-3bf9</guid>
      <description>&lt;p&gt;Many people think the best and only way to interact with a cloud vendor is via the web browser.&lt;/p&gt;

&lt;p&gt;I do not disagree that it is a great method, but it isn't the only way and in some cases it might not be the best way. This article  will outline the 3 main ways you can interact with IBM Cloud services. If you don't already have an account, you can &lt;a href="https://ibm.biz/BdfY5S" rel="noopener noreferrer"&gt;sign up&lt;/a&gt; for a free tier Lite account and try them for yourself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1 - Web browser cloud management console&lt;/strong&gt;&lt;br&gt;
The web browser is great for visualising what you are doing in your cloud account. Here you can visit your account dashboard with an overview of active and inactive services, keep up to date with recent IBM news and gain access to quick start templates. By using this method, you will feel more in control of what you are doing and therefore put aside any axiety of spending cloud credits by accident or starting the wrong service with the wrong resources.&lt;/p&gt;

&lt;p&gt;Pros:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visualise your workload&lt;/li&gt;
&lt;li&gt;Feel more in control&lt;/li&gt;
&lt;li&gt;Easily find quick start guides&lt;/li&gt;
&lt;li&gt;Easily calculate costs with available tools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Time consuming&lt;/li&gt;
&lt;li&gt;Repetitive tasks become arduous&lt;/li&gt;
&lt;li&gt;Can take time to get used to the console layout&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example use case: If you wish to set up a 30 days free Kubernetes cluster and visualise the progress and visit the Kubernetes dashboard this would be a great method of interaction.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;2 - Command Line Interface (CLI)&lt;/strong&gt;&lt;br&gt;
Using a CLI is great for efficiency, once logged into the CLI you have access to IBM Cloud services via the API's. If you are using this method, you may already know what services you are wanting to use and how to use them. That being said, even if you don't you can always find your way through the plain text interface by using the &lt;code&gt;-h&lt;/code&gt; flag. I find the best part about cloud vendor CLI's is more often than not they will be available within a Docker container. For example, &lt;a href="https://hub.docker.com/r/ibmcom/ibm-cloud-developer-tools-amd64" rel="noopener noreferrer"&gt;IBM Cloud Developer Tools&lt;/a&gt;. This makes them super portable and doesn't require you to install them onto your local machine. Second to that, some even have a CLI integrated into the browser that allows you to use the CLI through a browser window. If you have an IBM Cloud Account then you can visit and use the &lt;a href="https://cloud.ibm.com/shell" rel="noopener noreferrer"&gt;IBM Cloud Shell&lt;/a&gt; to interact with yours.&lt;/p&gt;

&lt;p&gt;Pros:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Great for repetitive tasks (you can write scripts around them)&lt;/li&gt;
&lt;li&gt;Can be containerised&lt;/li&gt;
&lt;li&gt;Standard layout&lt;/li&gt;
&lt;li&gt;Quick implementations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not every product offering will have an API or have a specific command embedded into the released CLI&lt;/li&gt;
&lt;li&gt;No visual representation of actions&lt;/li&gt;
&lt;li&gt;Usually require some level of command line confidence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example use case: You are wanting to create a new IBM Cloud Function with an Action and a Trigger to process a batch job on request.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;3 - Software Development Kit's (SDK's)&lt;/strong&gt;&lt;br&gt;
This one is less frequently used and less frequently spoken about. Thus making it the method most often forgotten about. An SDK is a set of tools and libraries that you can directly inject into your own source code of your chosen language to create and communicate between applications. Certain product offerings will have their own specific SDK's. An SDK usually contains many API's. There is an amazing video explaining the difference between API's and SDK's - &lt;a href="https://www.youtube.com/watch?v=kG-fLp9BTRo" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=kG-fLp9BTRo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see the &lt;a href="https://cloud.ibm.com/docs?tab=api-docs&amp;amp;" rel="noopener noreferrer"&gt;IBM Cloud API's and SDK's&lt;/a&gt; list showing which product offerings have an associated SDK ready for you to use.&lt;/p&gt;

&lt;p&gt;Pros:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Language specific&lt;/li&gt;
&lt;li&gt;Lots of SDK's available&lt;/li&gt;
&lt;li&gt;Great to import and use straight away&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can be difficult to understand&lt;/li&gt;
&lt;li&gt;Can be large in size&lt;/li&gt;
&lt;li&gt;Sometimes challenging to work out if you need one or not&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example use case: You have written a Go program and want to interact directly with IBM Watson. You can use the Go SDK to do this.&lt;/p&gt;

&lt;p&gt;For this example you would install it with the following bash command (this is just the starting point for the purpose of this article and not a complete code example):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;go get &lt;span class="nt"&gt;-u&lt;/span&gt; github.com/watson-developer-cloud/go-sdk/v2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And to use it, it needs to be imported it into your application code directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"github.com/watson-developer-cloud/go-sdk/v2/servicev1"&lt;/span&gt;

&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;serviceErr&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;servicev1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewServiceV1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;servicev1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ServiceV1Options&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Version&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="s"&gt;"2018-03-05"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you have any questions or want to see more content like this, drop me a line!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/liamchampton" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/liamchampton" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.instagram.com/liamhampton/" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt;&lt;br&gt;
&lt;a href="//www.linkedin.com/in/liam-conroy-hampton"&gt;LinkedIn&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>webconsole</category>
      <category>sdk</category>
      <category>cli</category>
    </item>
    <item>
      <title>2 Clouds 1 Pipeline</title>
      <dc:creator>Liam Conroy Hampton</dc:creator>
      <pubDate>Fri, 05 Feb 2021 18:39:59 +0000</pubDate>
      <link>https://dev.to/liamchampton/2-clouds-1-pipeline-19cd</link>
      <guid>https://dev.to/liamchampton/2-clouds-1-pipeline-19cd</guid>
      <description>&lt;p&gt;You've probably heard of CI/CD or DevOps. Maybe you have read my Toolchain article or listened to the &lt;a href="https://techjam.dev/" rel="noopener noreferrer"&gt;Tech Jam&lt;/a&gt; podcast I co-host.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/liamchampton" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F407456%2F26d720ee-0e84-46d0-9c76-05bf5b62e703.jpeg" alt="liamchampton"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/liamchampton/build-test-deploy-your-go-app-using-ibm-cloud-toolchain-1onc" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Build/Test/Deploy your Go App using IBM Cloud Toolchain&lt;/h2&gt;
      &lt;h3&gt;Liam Conroy Hampton ・ Sep 24 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#cloud&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#devops&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#go&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#beginners&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;Wherever you have heard it, it is a hot topic and there are so many elements to it. In this blog I will show you how I deploy two microservices into two different clouds. However, I have a plot twist. I am only using 1 pipeline. This is called multi-cloud deployment, a method that has many benefits from cost savings to security and reliability. This is becoming a more popular method of cloud deployment and this article just scratches the surface.&lt;/p&gt;

&lt;p&gt;The 3 takeaways from this article:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Learn something new about CI/CD&lt;/li&gt;
&lt;li&gt;Learn how to write a Tekton pipeline&lt;/li&gt;
&lt;li&gt;Understand how easy it is to deploy into more than one cloud&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For context, I have written a client app in Golang and a server app in Node.js. The Go app will submit/POST a piece of data through a form input box and the Node app will receive this and display it. Pretty simple but it does the job.&lt;/p&gt;

&lt;p&gt;If you also want to do this, here are some pre-reqs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ibm.biz/Bdf44X" rel="noopener noreferrer"&gt;IBM Cloud Account&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt;DigitalOcean Cloud Account&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/" rel="noopener noreferrer"&gt;GitHub Account&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2 microservices (ensure they are both in GitHub or equivalent). Feel free to use mine and just sub in the values throughout the demo &lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://github.com/liamchampton/microservice-node-demo" rel="noopener noreferrer"&gt;Node.js server app&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/liamchampton/microservice-go-demo" rel="noopener noreferrer"&gt;Golang client app&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Building a TekTon pipeline
&lt;/h2&gt;

&lt;p&gt;TekTon is purpose build for Knative applications. It handles containers and deployment into Knative environments seemlessly. Whereas you would previously have a Jenkinsfile or travis.yaml in the root of your project you dont neceessarily need this in TekTon (at least for this demo anyway).&lt;/p&gt;

&lt;p&gt;A TekTon pipeline provides new resources through Custom Resource Definitions (CRD's). These are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pipeline&lt;/li&gt;
&lt;li&gt;Task&lt;/li&gt;
&lt;li&gt;TaskRuns&lt;/li&gt;
&lt;li&gt;PipelineRuns&lt;/li&gt;
&lt;li&gt;PipelineResources&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A TekTon pipeline can consist of many tasks and within the tasks can be many steps. This will become clearer as we go along.&lt;/p&gt;

&lt;p&gt;The most fundamental part to always remember is the pipeline is decoupled and the building blocks are isolated containers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1 - Set up an IBM and DigitalOcean Cloud Accounts and acquire access keys
&lt;/h2&gt;

&lt;p&gt;Just follow these links to sign up (they are free)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ibm.biz/Bdf44X" rel="noopener noreferrer"&gt;IBM Cloud Account&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt;DigitalOcean Cloud Account&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  IBM token creation
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Sign into the IBM Cloud Managemant Console&lt;/li&gt;
&lt;li&gt;Manage -&amp;gt; Access (IAM) -&amp;gt; API keys -&amp;gt; &lt;code&gt;Create an IBM Cloud API key&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  DigitalOcean token creation
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Sing into the DigitalOcean Management Console&lt;/li&gt;
&lt;li&gt;Select API from the list on the left&lt;/li&gt;
&lt;li&gt;Select the &lt;code&gt;Token/Keys&lt;/code&gt; tab&lt;/li&gt;
&lt;li&gt;Click &lt;code&gt;Generate New Token&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Keep both of these api keys safe and ensure you know which is which. You will not be able to see them again.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2 - Write the pipeline yaml
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;File 1&lt;/strong&gt; - &lt;code&gt;deployment-pipeline.yaml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In this file you can see the main flow of the pipeline. It will firstly execute &lt;code&gt;pipeline-ibm-cloud-install-task&lt;/code&gt; and then afterwards it will execute &lt;code&gt;pipeline-do-cloud-install-task&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;apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: deployment-pipeline
spec:
  params:
    - name: ibmcloudapikey
      description: The IBM Cloud API Key
    - name: doauth
      description: The DigitalOcean API Key
    - name: file
      description: The node app repository contents to download
    - name: uuid
      description: A unique identifier
  tasks:
    - name: pipeline-ibm-cloud-install-task
      taskRef:
        name: ibm-cloud-install-task
      params:
        - name: ibmcloudapikey
          value: $(params.ibmcloudapikey)
        - name: file
          value: $(params.file)
        - name: uuid
          value: $(params.uuid)
    - name: pipeline-do-cloud-install-task
      runAfter: pipeline-ibm-cloud-install-task
      taskRef:
        name: do-cloud-install-task
      params:
        - name: doauth
          value: $(params.doauth)
        - name: uuid
          value: $(params.uuid)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;File 2&lt;/strong&gt; - &lt;code&gt;ibm-cloud-install-task.yaml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is a &lt;code&gt;Task&lt;/code&gt; and it has a single step. The primary image declared is &lt;code&gt;ibmcom/ibm-cloud-developer-tools-amd64:1.2.3&lt;/code&gt; and it has the &lt;code&gt;ibmcloud cli&lt;/code&gt; pre-installed and set up. First it downloads a zip of my project from GitHub. Secondly, it uses the ibmcloud cli to authenticate my IBM Cloud account and pushed my project up to CloudFoundry.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: ibm-cloud-install-task
spec:
  params:
    - name: ibmcloudapikey
      type: string
    - name: file
      type: string
    - name: uuid
      type: string
  steps:
    - name: login-and-deploy-function
      image: ibmcom/ibm-cloud-developer-tools-amd64:1.2.3
      script: |
        #!/usr/bin/env sh
        apk add zip
        mkdir -p ./application
        wget $(params.file) -O nodeapp.zip
        unzip ./nodeapp.zip -d ./application
        rm nodeapp.zip
        echo $(params.uuid)
        cd application/microservice-node-demo-main

        ibmcloud login -a cloud.ibm.com -r eu-gb -g Default -apikey $(params.ibmcloudapikey)
        ibmcloud cf install
        ibmcloud target --cf
        ibmcloud cf push liams-node-app -m 128M
        echo PUSHED TO IBM CLOUD CF
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Be sure to change the name of your app by changing the line &lt;code&gt;ibmcloud cf push&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;File 3&lt;/strong&gt; - &lt;code&gt;do-cloud-install-task.yaml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This &lt;code&gt;Task&lt;/code&gt; is using a vanilla Alpine image, installing the DigitalOcean CLI (&lt;code&gt;doctl&lt;/code&gt;), creating an &lt;code&gt;app spec&lt;/code&gt; (a deployment &lt;code&gt;.yaml&lt;/code&gt; file DigitalOcean expects) and then finally deploying the app. The &lt;code&gt;app spec&lt;/code&gt; consists of the constraints I wish to impose on my application upon deployment. As you can see, I have hard coded an environment variable (&lt;code&gt;APPROUTE&lt;/code&gt;) for my application to use to connect to my other app deployed in IBM Cloud. This could be subsituted with a parameter but this is just a basic demo.&lt;/p&gt;

&lt;p&gt;In the code below, make sure you copy your own values into the bits that need changing (&lt;code&gt;repo_clone_url&lt;/code&gt; and &lt;code&gt;APPROUTE&lt;/code&gt; value) and tailor it to your applications needs. &lt;a href="https://www.digitalocean.com/docs/app-platform/references/app-specification-reference/" rel="noopener noreferrer"&gt;DigitalOcean App Spec&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you are using my repositories just sub in the values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: do-cloud-install-task
spec:
  params:
      - name: doauth
        type: string
      - name: uuid
        type: string
  steps:
    - name: login-and-deploy-function
      image: alpine:3.13.0
      script: |
        #!/usr/bin/env sh
        echo pipeline-uuid-$(params.uuid)
        apk add wget
        wget https://github.com/digitalocean/doctl/releases/download/v1.54.0/doctl-1.54.0-linux-amd64.tar.gz
        tar xf doctl-1.54.0-linux-amd64.tar.gz
        mv doctl /usr/local/bin
        mkdir -p ./appspec
        cd appspec/
        touch client-go-app.yaml
        ls -la
        cat &amp;gt;&amp;gt; client-go-app.yaml &amp;lt;&amp;lt;EOF
        name: client-go-app
        services:
          - name: go-app
            git:
              repo_clone_url: &amp;lt;your-github-project-url-to-deploy-into-digital-ocean&amp;gt;
              branch: do-deploy
            build_command: go build -o goapp
            run_command: ./goapp
            envs:
              - key: APPROUTE
                value: https://&amp;lt;your-ibmcloud-app-name&amp;gt;.eu-gb.mybluemix.net
            instance_count: 1
        EOF
        pwd
        doctl auth init -t $(params.doauth)
        doctl apps create --spec client-go-app.yaml
        echo App deployed to DigitalOcean

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

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;As it stands this will not work and you'll find out why shortly&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once these files have been created, create a new repository in GitHub and push these files into it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3 - Build your Toolchain in IBM Cloud
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Login to your IBM Cloud account&lt;/li&gt;
&lt;li&gt;Navigate to the DevOps section in IBM Cloud using the navigation menu on the left (its about half way down the list)&lt;/li&gt;
&lt;li&gt;Select your region (I chose London) and then click on &lt;code&gt;Create toolchain&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Scroll down to the bottom and select "Build your own toolchain"&lt;/li&gt;
&lt;li&gt;Give it a name and leave the region and resource group as the defaults&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You have now created a foundation to build on. At this point your toolchain will be empty, so lets fill it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the top right, click on the button &lt;code&gt;Add tool&lt;/code&gt; and search for &lt;code&gt;GitHub&lt;/code&gt;. This will be used to access the microservices in GitHub or an equivalent server. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fill out the details: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Server - Where the projects lives (default is GitHub).&lt;/li&gt;
&lt;li&gt;Repository type - Change this to &lt;code&gt;Existing&lt;/code&gt; since your projects already exists.&lt;/li&gt;
&lt;li&gt;Repository URL - This is the HTTPS project URL (not the &lt;code&gt;.git&lt;/code&gt; URL).&lt;/li&gt;
&lt;li&gt;Integration Owner - This is your GitHub username. You may be propted to allow Toolchain access to your GitHub profile. Once connected, it will auto-populte.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ignore the checkboxes &lt;code&gt;Enable GitHub Issues&lt;/code&gt; and &lt;code&gt;Track deployment of code changes&lt;/code&gt; as we do not need them for this demo.&lt;/p&gt;

&lt;p&gt;Repeat these steps and add a new GitHub &lt;code&gt;tool&lt;/code&gt; in the Toolchain for each GitHub repository. 1 for each microservice and 1 for the Tekton pipeline repository.&lt;/p&gt;

&lt;p&gt;Once you have done this, add one final tool. Thats right, FINAL tool! Click &lt;code&gt;Add tool&lt;/code&gt; and search for &lt;code&gt;Delivery Pipeline&lt;/code&gt;. This is the workhorse in this Toolchain.&lt;/p&gt;

&lt;p&gt;Select it and proceed to fill out the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pipeline name - Give it a unique name&lt;/li&gt;
&lt;li&gt;Pipeline type - Here you have 2 options. &lt;code&gt;Classic&lt;/code&gt;, which provides a graphical interface and allows you to deploy your applications into CloudFoundry and &lt;code&gt;Tekton&lt;/code&gt;, a cloud native CI/CD pipeline tool. &lt;strong&gt;Select &lt;code&gt;Tekton&lt;/code&gt; from the list.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now click on &lt;code&gt;Create Integration&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you get an error box saying &lt;code&gt;"Continuous Delivery service required"&lt;/code&gt; dont panic. In the main IBM Cloud search bar, search for continuous delivery and select "Continuous Delivery" - You only need to do this once! &lt;br&gt;
Its very simple to set up this service. Make sure the region is set to the same as your toolchain (mine is London), give it a sensible name such as "toolchain delivery service" and click &lt;code&gt;Create&lt;/code&gt;. Now head back to your Toolchain and the error should be gone.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It should now look like this:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frmkkvmx79k8tl4jd1mse.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frmkkvmx79k8tl4jd1mse.png" alt="toolchai tools" width="800" height="960"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 4 - Configure the Tekton pipeline
&lt;/h2&gt;

&lt;p&gt;Click on the &lt;code&gt;Delivery Pipeline&lt;/code&gt; tool and this will take you to the &lt;code&gt;TektonPipeline Configuration&lt;/code&gt; dashboard.&lt;/p&gt;

&lt;p&gt;On the left side of the screen you will see a list. These are as follows:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Definitions&lt;/strong&gt; - This specifies the pipeline code to be run upon a trigger. We created 3 Tekton &lt;code&gt;.yaml&lt;/code&gt; files in Step 2. Click on &lt;code&gt;Add&lt;/code&gt; and you will be given a popout. For the &lt;code&gt;Repository&lt;/code&gt; select the Tekton pipeline repository that has the &lt;code&gt;.yaml&lt;/code&gt; files we created earlier in. Chose the &lt;code&gt;main&lt;/code&gt; branch in the next box and leave &lt;code&gt;Path&lt;/code&gt; blank if you have left the files in the root directory of the project repository. Click &lt;code&gt;Add&lt;/code&gt;. Once the code has loaded in, click on &lt;code&gt;Validate&lt;/code&gt;, wait for this to finish and then click &lt;code&gt;Save&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Worker&lt;/strong&gt; - This is essentially how your pipeline will run. You can have dedicated private workers or ones that from a shared pool of resources. We will just use a shared resource so select &lt;code&gt;IBM Managed workers (Tekton Pipelines vx.xx.x) in LONDON&lt;/code&gt; and click &lt;code&gt;Save&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Triggers&lt;/strong&gt; - These specify what happens when an event occurs. More often than not, they will be event triggers from a webhook on GitHub, such as a pull request or a new commit or merge. However in this blog we will be using a manual trigger. We'll set this up shortly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Environment properties&lt;/strong&gt; - Key:Value pairs that can be used from within your pipeline. These are referenced as &lt;code&gt;$(PARAMS)&lt;/code&gt; in the &lt;code&gt;.yaml&lt;/code&gt; files. In here we need to &lt;code&gt;Add&lt;/code&gt; 4 evironment properties for this pipeine to run correctly and they are:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Key&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;doauth&lt;/td&gt;
&lt;td&gt;Secure&lt;/td&gt;
&lt;td&gt;DigitalOcean api key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;file&lt;/td&gt;
&lt;td&gt;Text&lt;/td&gt;
&lt;td&gt;.zip url of 1 project repsitory (mine is my node project)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ibmcloudapikey&lt;/td&gt;
&lt;td&gt;Secure&lt;/td&gt;
&lt;td&gt;IBM Cloud api key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;uuid&lt;/td&gt;
&lt;td&gt;Text&lt;/td&gt;
&lt;td&gt;Unique identifier e.g 1234&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;.zip&lt;/code&gt; url = url + /archive/main.zip for example: &lt;code&gt;https://github.com/liamchampton/microservice-node-demo/archive/main.zip&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Other settings&lt;/strong&gt; - Use these settings for more granular control over builds. For this demo we will not be touching these.&lt;/p&gt;

&lt;p&gt;Now everything has been set up. The pipeline code has been imported, the workers have been set and the evironment properties have been set. Seems like it is good to go.. right? Try and click on &lt;code&gt;Run Pipeline&lt;/code&gt; in the top right of your screen.&lt;/p&gt;

&lt;p&gt;PSYCH! Got cha! This will not work because we have not got a trigger. It doesn't know what to do when that button is clicked so we need to tell it. &lt;/p&gt;

&lt;p&gt;Like I mentioned, it would usually be a trigger from an event that happens on a repository, such as a pull request or merge but we will create a manual trigger.&lt;/p&gt;

&lt;p&gt;We need to revisit our pipeline code repository and add some more files. I have named these &lt;code&gt;hello-xxx.yaml&lt;/code&gt; to give a sense I am envoking a new conversation with it but you can call them whatever you like, just make sure to change the corrosponding code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;File 4&lt;/strong&gt; - &lt;code&gt;hello-lister.yaml&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;apiVersion: tekton.dev/v1beta1
kind: EventListener
metadata:
  name: hello-listener
spec:
  triggers:
    - binding:
        name: hello-trigger-binding
      template:
        name: hello-trigger-template
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;File 5&lt;/strong&gt; - &lt;code&gt;hello-trigger-binding.yaml&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;apiVersion: tekton.dev/v1beta1
kind: TriggerBinding
metadata:
  name: hello-trigger-binding
spec:
  params:
    - name: ibmcloudapikey
      value: $(event.ibmcloudapikey)
    - name: doauth
      value: $(event.doauth)
    - name: file
      value: $(event.file)
    - name: uuid
      value: $(event.uuid)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;File 6&lt;/strong&gt; - &lt;code&gt;hello-trigger-template.yaml&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;apiVersion: tekton.dev/v1beta1
kind: TriggerTemplate
metadata:
  name: hello-trigger-template
spec:
  params:
    - name: ibmcloudapikey
      description: The IBM Cloud API Key
    - name: doauth
      description: The DigitalOcean API Key
    - name: file
      description: The node app repository to be downloaded
    - name: uuid
      description: A unique identifier
  resourcetemplates:
    - apiVersion: tekton.dev/v1beta1
      kind: PipelineRun
      metadata:
        name: pipelinerun-$(params.uuid)
      spec:
        pipelineRef:
          name: deployment-pipeline
        params:
          - name: ibmcloudapikey
            value: $(params.ibmcloudapikey)
          - name: doauth
            value: $(params.doauth)
          - name: file
            value: $(params.file)
          - name: uuid
            value: $(params.uuid)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Push these new files into your main branch on GitHub and inside your pipeline dashboard in IBM Cloud, go to &lt;code&gt;Definitions&lt;/code&gt; -&amp;gt; click the 3 dots on the repository already imported -&amp;gt; &lt;code&gt;Edit&lt;/code&gt; -&amp;gt; click on the &lt;code&gt;Update&lt;/code&gt; button -&amp;gt; &lt;code&gt;Validate&lt;/code&gt; -&amp;gt; &lt;code&gt;Save&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Head to the &lt;code&gt;Triggers&lt;/code&gt; page and then click &lt;code&gt;Add trigger&lt;/code&gt;. Select &lt;code&gt;Manual&lt;/code&gt;. You should only have 1 EventListener to choose from and it should be called &lt;code&gt;hello-listener&lt;/code&gt;. On the &lt;code&gt;Worker&lt;/code&gt; box, select the option &lt;code&gt;Inherit from Pipeline Configuration&lt;/code&gt; as this will use the shared pool or works, just like we set up earlier. Click &lt;code&gt;Save&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Wahoo! You have finished setting up your Tekton pipeline!&lt;/p&gt;

&lt;p&gt;Now all thats left to do is run it.. click &lt;code&gt;Run Pipeline&lt;/code&gt;, enter a &lt;code&gt;uuid&lt;/code&gt; value for the pipeline run and click &lt;code&gt;Run&lt;/code&gt;. Watch the magic happen 🎉&lt;/p&gt;

&lt;h2&gt;
  
  
  My challenge for you
&lt;/h2&gt;

&lt;p&gt;Create a new &lt;code&gt;Task&lt;/code&gt; to clean up each deployment at the end of the pipeline run and let me know how you got on 😄&lt;/p&gt;

&lt;p&gt;If you have any questions or want to see more content like this, drop me a line!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/liamchampton" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/liamchampton" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.instagram.com/liamhampton/" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt;&lt;br&gt;
&lt;a href="//www.linkedin.com/in/liam-conroy-hampton"&gt;LinkedIn&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>pipeline</category>
      <category>cloudnative</category>
      <category>devops</category>
    </item>
    <item>
      <title>Code Engine - A developers dream!</title>
      <dc:creator>Liam Conroy Hampton</dc:creator>
      <pubDate>Mon, 23 Nov 2020 17:50:18 +0000</pubDate>
      <link>https://dev.to/liamchampton/code-engine-a-developers-dream-47ap</link>
      <guid>https://dev.to/liamchampton/code-engine-a-developers-dream-47ap</guid>
      <description>&lt;p&gt;Code Engine? What is Code Engine? This is a slick new tool that IBM Cloud has released into Beta. It takes your already containerised app OR source code (that's right, it takes both), and then deploys that into the wild. This is literally a developers dream. You code it, they deploy it. It really is that simple. Look, I'll show you the only steps you need to take..&lt;/p&gt;

&lt;p&gt;1) &lt;a href="https://ibm.biz/BdqNmK" rel="noopener noreferrer"&gt;Sign into&lt;/a&gt; IBM Cloud or &lt;a href="https://ibm.biz/BdqNmK" rel="noopener noreferrer"&gt;create&lt;/a&gt; an IBM Cloud account&lt;br&gt;
2) Write some code and put it into GitHub OR containerise your application and store it in a container registry - literally anywhere you want&lt;br&gt;
3) Link up Code Engine and watch that puppy deploy&lt;/p&gt;

&lt;p&gt;As always, I will be using a Golang application for this tutorial as that's my favourite flavour but you can use anything you like.&lt;/p&gt;

&lt;p&gt;Before we start, you need to get an API key set up. Follow these easy steps:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ibm.biz/BdqNmK" rel="noopener noreferrer"&gt;Login or Sign up&lt;/a&gt; for a free IBM Cloud account and then head to &lt;strong&gt;Manage&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Access (IAM)&lt;/strong&gt; -&amp;gt; &lt;strong&gt;View All of your API keys&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Create an IBM Cloud API key&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Give the key a name and description and MAKE A NOTE OF THE KEY. You will not see this key again and you need it later.&lt;/p&gt;

&lt;p&gt;Now for the juicy stuff.&lt;/p&gt;

&lt;p&gt;Head to the search bar and type in &lt;strong&gt;Code Engine&lt;/strong&gt; and select the catalogue option as shown below&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftlt53rci2ne2mb9xh5vz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftlt53rci2ne2mb9xh5vz.png" alt="search bar" width="800" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Now let's be real, playing with containers is great but not everyone knows how to containerise their app or know the ins and outs of containerisation. Since lots of developers just deliver code, we will select the option to &lt;strong&gt;"Run your source code"&lt;/strong&gt;. All this needs is a github link and Code Engine does the heavy lifting here.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdiun3o0ogyxzv99ho5v7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdiun3o0ogyxzv99ho5v7.png" alt="run your source code" width="800" height="356"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select this option and click on "Start creating -&amp;gt;"&lt;/p&gt;

&lt;p&gt;Next you will be prompted to select "Application" or "Job".&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Application - A project you intend to keep alive, such as a HTTP server&lt;/li&gt;
&lt;li&gt;Job - A block of code you intend to run to completion, such as a function&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this tutorial, we are going to select "Application" as we want to make a HTTP server. Beneath that option, you will be promped to create a project. A project is what houses this deployed application. Click on "Create" and fill in the details on the panel that pops out and then click "Create" to make the project (shown below).&lt;/p&gt;

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

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

&lt;p&gt;Now we can carry on with the application. Give it a name, select "Source Code" because that's what we are using, specify the &lt;code&gt;.git&lt;/code&gt; repository url and then click on "Specify build details" - this is the most important part.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Note&lt;/strong&gt; I am using a simple &lt;a href="https://github.com/liamchampton/gohttpserver.git" rel="noopener noreferrer"&gt;golang http server&lt;/a&gt; I had in GitHub - feel free to use it too&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;A window will pop out and the details will be pre-configured - only change these if you need to specify something other than the root of the directory and a different branch.&lt;/p&gt;

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

&lt;p&gt;Next, on the "Strategy" stage you will be asked how you would like this built. Dockerfile or Cloud Native Buildpack? This might seem a bit confusing but fear not, this is just how you want the code to be bundled up and run. For ease, we will just leave it pre-configured as the &lt;code&gt;Dockerfile&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;Finally, the output stage. If you do not already have a container registry / repository in place you need to set one up. This is just so that Code Engine has a place to store the built image of your source code.&lt;/p&gt;

&lt;p&gt;It might look a little garish and something like this&lt;/p&gt;

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

&lt;p&gt;Click on "Add" to add a registry and you will the be presented with a bunch of fields to fill out that look like this..&lt;/p&gt;

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

&lt;p&gt;Now, lets take a second to walk through these bits&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Registry name - This is the name you will identify the registry with, you can choose whatever you like. As seen above I have chosen "http-project-registry"&lt;/li&gt;
&lt;li&gt;Registry server - The eagle eyed reader might have noticed that this project is based on a server in Dallas. At the point of writing this, Code Engine is in beta meaning Dallas is the only available deployment location. I am using IBM Cloud container registry so my sever address is &lt;code&gt;us.icr.io&lt;/code&gt;. You can choose Dockerhub or any other container registry.&lt;/li&gt;
&lt;li&gt;Password - If you are not using IBM Cloud container registry, you will need to provide your user/password. If you ARE using IBM Cloud container registry like me, you will only be prompted for the password as the "Username" is pre-filled. Remeber that API I asked you to make earlier? - that API key goes in here as the password.&lt;/li&gt;
&lt;li&gt;Email - This is optional, I haven't put it in but there is no harm in specifying a valid email address.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Click "Add" and you will then get a pop out that looks similar to the one below. You may have to enter a repository name if this is your first project. You can call this anything you like.&lt;/p&gt;

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

&lt;p&gt;Click on "Done" and then click on "Deploy".&lt;/p&gt;

&lt;p&gt;Wait for the applicaiton to be built and deployed. Click on "Application URL" to view the deployed application.&lt;/p&gt;

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

&lt;p&gt;.. And just like that, you have a cloud native application built from raw source code. As I said earlier, you just need to focus on pushing your code and let Code Engine do the rest!&lt;/p&gt;

&lt;p&gt;Now close the browser tab / window that is running the application. Have you spotted anything weird in the project window? There might be some lag to this but you might notice you have "0 instances" running.&lt;/p&gt;

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

&lt;p&gt;This is just another one of those cool perks where you would only pay for what you use on a larger project. Under the covers, Code Engine uses Knative which has this awesome feature of being able to scale down to 0 if no traffic is being received. Checkout the &lt;a href="https://knative.dev/" rel="noopener noreferrer"&gt;Knative&lt;/a&gt; docs to read more about this!&lt;/p&gt;

&lt;h3&gt;
  
  
  Disclaimer
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;At the time of writing this, Code Engine is in beta so you may experience fluctuating behaviour and projects are kept alive for only 7 days.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you have any questions or want to see more content like this, feel free to reach out!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/liamchampton" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/liamchampton" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.instagram.com/liamhampton/" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt;&lt;br&gt;
&lt;a href="//www.linkedin.com/in/liam-conroy-hampton"&gt;LinkedIn&lt;/a&gt;&lt;/p&gt;

</description>
      <category>code</category>
      <category>developer</category>
      <category>cloud</category>
      <category>cloudnative</category>
    </item>
    <item>
      <title>Get GitHub's service status using Golang on IBM Cloud</title>
      <dc:creator>Liam Conroy Hampton</dc:creator>
      <pubDate>Thu, 22 Oct 2020 16:11:37 +0000</pubDate>
      <link>https://dev.to/liamchampton/get-github-s-service-status-using-golang-on-ibm-cloud-3j3g</link>
      <guid>https://dev.to/liamchampton/get-github-s-service-status-using-golang-on-ibm-cloud-3j3g</guid>
      <description>&lt;p&gt;How many times have you had a service go down leaving you searching your Twitter feed to find out if it's really down or if it's just you?&lt;/p&gt;

&lt;p&gt;Golang has a knack and good reputation for many things but one that stands out like a sore thumb is the low memory footprint.&lt;/p&gt;

&lt;p&gt;For this project, it is perfect for a lightweight HTTP server and client. The low data usage makes it compatible for &lt;em&gt;most&lt;/em&gt; cloud providers free tier accounts and it compiles to binaries that are cross-platform. This means you can deploy your server to the cloud and share your client binary and it will run on all systems.&lt;/p&gt;

&lt;p&gt;In this article I will show you how to create the following elements and connect them:&lt;br&gt;
1) A cloud-hosted Golang HTTP server&lt;br&gt;
2) A Golang client to consume the HTTP server data&lt;br&gt;
3) How to host the server in IBM Cloud Foundry&lt;br&gt;
4) How to build and install the client binary onto your own machine&lt;/p&gt;

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

&lt;p&gt;This is really fun because it can be adjusted for other services really easily, after all it is just providing and consuming JSON data!&lt;/p&gt;

&lt;p&gt;What will you need for this?&lt;br&gt;
1) IBM Cloud Lite account&lt;br&gt;
2) IBM Cloud CLI + Cloud Foundry CLI&lt;br&gt;
3) GitHub account + git installed (optional)&lt;br&gt;
4) Golang installed/setup on your machine&lt;/p&gt;
&lt;h1&gt;
  
  
  Pre-req set up
&lt;/h1&gt;

&lt;p&gt;1) Sign up to &lt;a href="https://www.ibm.com/uk-en/cloud/free?cm_mmc=Inpersondirected-_-Audience+Developer_Developer+Conversation-_-WW_WW-_-Oct2020-liam_hampton-get_github_s_service_status_using_golang_on_ibm_cloud___dev-global-devadvgrp-london&amp;amp;cm_mmca1=000039JL&amp;amp;cm_mmca2=10010797" rel="noopener noreferrer"&gt;IBM Cloud&lt;/a&gt;&lt;br&gt;
2) Login/signup to &lt;a href="https://github.com/" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. This is optional should you wish to push your code to a repository or clone mine. Install &lt;a href="https://git-scm.com/doc" rel="noopener noreferrer"&gt;git&lt;/a&gt; to interact with GitHub&lt;br&gt;
3) Golang installation can be tricky but the &lt;a href="https://golang.org/doc/" rel="noopener noreferrer"&gt;official docs&lt;/a&gt; are where it's at!&lt;br&gt;
4) Install the &lt;a href="https://cloud.ibm.com/docs/cli?topic=cli-install-ibmcloud-cli" rel="noopener noreferrer"&gt;IBM Cloud CLI&lt;/a&gt; + Cloud Foundry CLI (use command &lt;code&gt;ibmcloud cf install&lt;/code&gt; once you have the IBM Cloud CLI installed)&lt;/p&gt;
&lt;h1&gt;
  
  
  Create a Go HTTP server
&lt;/h1&gt;

&lt;p&gt;First, we are going to create a server to act as a stepping stone endpoint that the client will call instead of going straight to the GitHub API. For this, it might seem a little overkill but if you were to expand on this project it would be very useful.&lt;/p&gt;

&lt;p&gt;First, let's make a simple server and get it into IBM Cloud Foundry, OR you can fork / clone &lt;a href="https://github.com/liamchampton/gohttpserver" rel="noopener noreferrer"&gt;this one from my github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In a terminal, navigate into &lt;code&gt;$HOME/go/src/github.com&lt;/code&gt; and create your project folder. Call it &lt;code&gt;github-status-server&lt;/code&gt;. If you are copying from GitHub, make sure you clone the repository into this directory.&lt;/p&gt;

&lt;p&gt;Note - if you do not have this folder tree already (go/src/github.com), then create it and make sure go is installed on your system correctly. To test your installation and check the installed version, enter the command &lt;code&gt;go version&lt;/code&gt; into a terminal window.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd&lt;/code&gt; into this new project folder and enter the command &lt;code&gt;go mod init&lt;/code&gt; (in some cases you may need to specify the exact project path after &lt;code&gt;init&lt;/code&gt;). This will initialise the project to use go modules to help with dependency tracking.&lt;/p&gt;

&lt;p&gt;Make a new file in this directory and call it &lt;code&gt;main.go&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Open this project in your preferred editor. I use VSCode or GoLand.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;main.go&lt;/code&gt; you will need the following code (if you are copying from GitHub, you will just need to amend the code to suit):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"bytes"&lt;/span&gt;
    &lt;span class="s"&gt;"encoding/json"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"io/ioutil"&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;
    &lt;span class="s"&gt;"net/http"&lt;/span&gt;
    &lt;span class="s"&gt;"os"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// Response struct will pick out the elements of JSON we want to display&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Components&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Name&lt;/span&gt;        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"name"`&lt;/span&gt;
        &lt;span class="n"&gt;Description&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"description"`&lt;/span&gt;
        &lt;span class="n"&gt;Status&lt;/span&gt;      &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"status"`&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Description&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"description"`&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Setup the HTTP server in one housing function&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;SetUpRoutes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Create the route handler listening on '/'&lt;/span&gt;
    &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HandleFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Starting server on port 8080"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Start the server&lt;/span&gt;
    &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ListenAndServe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;":8080"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;SetUpRoutes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Calling GitHub API for Data"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// GitHub API&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://kctbh9vrtdwd.statuspage.io/api/v2/summary.json"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Pull out the body of the response&lt;/span&gt;
    &lt;span class="n"&gt;responseData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ioutil&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// Unmarshal the reponse data into the struct specified at the top&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;responseObject&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;responseData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;responseObject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Turn unmarshalled json into a byte array for the write stream&lt;/span&gt;
    &lt;span class="n"&gt;responseBodyBytes&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewEncoder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;responseBodyBytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;responseObject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;byteArray&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;responseBodyBytes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bytes&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;byteArray&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Tada! We have got a simple HTTP server that will return only the part of the GitHub status API that we have stated in the struct. You can adjust this to taste.&lt;/p&gt;

&lt;p&gt;To run this and see it in action, all you have to do is enter the command &lt;code&gt;go run main.go&lt;/code&gt; into a terminal from within the root of the project directory. You may be asked to allow a network connection (at least on Mac you might).&lt;/p&gt;

&lt;p&gt;If you go to &lt;code&gt;localhost:8080&lt;/code&gt; in your web browser you should see the following JSON output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"Components"&lt;/span&gt;&lt;span class="p"&gt;:[{&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Git Operations"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Performance of git clones, pulls, pushes, and associated operations"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"operational"&lt;/span&gt;&lt;span class="p"&gt;},{&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"API Requests"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Requests for GitHub APIs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"operational"&lt;/span&gt;&lt;span class="p"&gt;},{&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Webhooks"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Real time HTTP callbacks of user-generated and system events"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"operational"&lt;/span&gt;&lt;span class="p"&gt;},{&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Visit www.githubstatus.com for more information"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"operational"&lt;/span&gt;&lt;span class="p"&gt;},{&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Issues"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Requests for Issues on GitHub.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"operational"&lt;/span&gt;&lt;span class="p"&gt;},{&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Pull Requests"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Requests for Pull Requests on GitHub.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"operational"&lt;/span&gt;&lt;span class="p"&gt;},{&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"GitHub Actions"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Workflows, Compute and Orchestration for GitHub Actions"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"operational"&lt;/span&gt;&lt;span class="p"&gt;},{&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"GitHub Packages"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"API requests and webhook delivery for GitHub Packages"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"operational"&lt;/span&gt;&lt;span class="p"&gt;},{&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"GitHub Pages"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Frontend application and API servers for Pages builds"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"operational"&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;&lt;span class="nl"&gt;"Status"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"All Systems Operational"&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This looks gross, I know! But only the client app will consume this so you don't really need it to be readable. By all means, feel free to make it readable, nicely formatted JSON.. make it a personal challenge.&lt;/p&gt;

&lt;h1&gt;
  
  
  Push the server into IBM Cloud Foundry - its so easy!
&lt;/h1&gt;

&lt;p&gt;Make sure you are signed up to &lt;a href="https://www.ibm.com/uk-en/cloud/free?cm_mmc=Inpersondirected-_-Audience+Developer_Developer+Conversation-_-WW_WW-_-Oct2020-liam_hampton-get_github_s_service_status_using_golang_on_ibm_cloud___dev-global-devadvgrp-london&amp;amp;cm_mmca1=000039JL&amp;amp;cm_mmca2=10010797" rel="noopener noreferrer"&gt;IBM Cloud&lt;/a&gt; and have the &lt;a href="https://cloud.ibm.com/docs/cli?topic=cli-install-ibmcloud-cli" rel="noopener noreferrer"&gt;CLI&lt;/a&gt; installed.&lt;/p&gt;

&lt;p&gt;Once it is installed, make sure you are logged into IBM Cloud via your terminal. You can log in with the simple command &lt;code&gt;ibmcloud login&lt;/code&gt; or if you have a federated ID use the command &lt;code&gt;ibmcloud login --sso&lt;/code&gt;. &lt;a href="https://www.ibm.com/uk-en/cloud/free?cm_mmc=Inpersondirected-_-Audience+Developer_Developer+Conversation-_-WW_WW-_-Oct2020-liam_hampton-get_github_s_service_status_using_golang_on_ibm_cloud___dev-global-devadvgrp-london&amp;amp;cm_mmca1=000039JL&amp;amp;cm_mmca2=10010797" rel="noopener noreferrer"&gt;Signup&lt;/a&gt; if you don't already have an account.&lt;/p&gt;

&lt;p&gt;After you have logged in, make sure you also have the Cloud Foundry CLI installed. To install it, just use the command &lt;code&gt;ibmcloud cf install&lt;/code&gt;. This will allow you to interact with Cloud Foundry quick and easily through the terminal.&lt;/p&gt;

&lt;p&gt;Now all you need to do is target Cloud Foundry. Again, this is easily done with the command &lt;code&gt;ibmcloud target --cf&lt;/code&gt;. Now you are able to interact with IBM Cloud Foundry.&lt;/p&gt;

&lt;p&gt;It's time to push the app up. To do this, use the command &lt;code&gt;ibmcloud cf push github-status -m 128mb&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Broken down, &lt;code&gt;ibmcloud cf push&lt;/code&gt; will connect to Cloud Foundry through IBM Cloud and push up your code. Using a build pack and the name you give it, in this case I called it &lt;code&gt;github-status&lt;/code&gt;, it builds and creates a service for you. The &lt;code&gt;-m 128mb&lt;/code&gt; just states the amount of memory you wish to allocate to this service. Since it is a basic HTTP server you do not need much memory at all.&lt;/p&gt;

&lt;h1&gt;
  
  
  Create a Go (or a node, python, swift etc..) Client for local system use
&lt;/h1&gt;

&lt;p&gt;This is the magic of microservices, they don't all have to be the same language, they just need a common way to chat to one another. For this example I am using Go so you can see how easy it is for you to use it from anywhere on your local system environment.&lt;/p&gt;

&lt;p&gt;Just like before, in a terminal navigate into &lt;code&gt;$HOME/go/src/github.com&lt;/code&gt; and create your project folder. Call it &lt;code&gt;get-github-status&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd&lt;/code&gt; into this new project folder and enter the command &lt;code&gt;go mod init&lt;/code&gt; (in some cases you may need to specify the exact project path after &lt;code&gt;init&lt;/code&gt;). This will initialise the project to use go modules to help with dependency tracking.&lt;/p&gt;

&lt;p&gt;You guessed it.. make a new file in this directory and call it &lt;code&gt;main.go&lt;/code&gt; and open this project in your preferred editor.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;main.go&lt;/code&gt; you will need the following code (you may notice it is very similar to the server code). The main difference is that this will make a single request when you want it to, not just sit running like the server does. Make sure you change the endpoint link in the first line of the &lt;code&gt;main()&lt;/code&gt; function to that of your Cloud Foundry route. This will be found in the terminal output after your push up to the cloud. &lt;/p&gt;

&lt;p&gt;My example is below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxixmvu8ikoj9ug9bkxba.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxixmvu8ikoj9ug9bkxba.png" alt="Cloud Foundry Route" width="800" height="398"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"bytes"&lt;/span&gt;
    &lt;span class="s"&gt;"encoding/json"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"io/ioutil"&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;
    &lt;span class="s"&gt;"net/http"&lt;/span&gt;
    &lt;span class="s"&gt;"os"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Components&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Name&lt;/span&gt;        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"name"`&lt;/span&gt;
        &lt;span class="n"&gt;Description&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"description"`&lt;/span&gt;
        &lt;span class="n"&gt;Status&lt;/span&gt;      &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"status"`&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Description&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"description"`&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c"&gt;// Calling the hosted HTTP server&lt;/span&gt;
    &lt;span class="c"&gt;// Edit this with your route&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://YOU-ROUTE-ENDPOINT"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Check the request didn't return an error&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Pull out the body of the response&lt;/span&gt;
    &lt;span class="n"&gt;responseData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ioutil&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// Unmarshal the data into the format given in the struct&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;responseObject&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;responseData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;responseObject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Pretty print the JSON making it easier to read&lt;/span&gt;
    &lt;span class="n"&gt;responseBodyBytes&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewEncoder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;responseBodyBytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;responseObject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;byteArray&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;responseBodyBytes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bytes&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="n"&gt;byteBuffer&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Indent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;byteBuffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;byteArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"  "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;byteBuffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wahoo 🎉&lt;/p&gt;

&lt;p&gt;You now have a server providing data and a client to consume it.&lt;/p&gt;

&lt;p&gt;Run the client locally using the command &lt;code&gt;go run main.go&lt;/code&gt; and you should hopefully see the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"Components"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"Git Operations"&lt;/span&gt;,
      &lt;span class="s2"&gt;"description"&lt;/span&gt;: &lt;span class="s2"&gt;"Performance of git clones, pulls, pushes, and associated operations"&lt;/span&gt;,
      &lt;span class="s2"&gt;"status"&lt;/span&gt;: &lt;span class="s2"&gt;"operational"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;,
    &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"API Requests"&lt;/span&gt;,
      &lt;span class="s2"&gt;"description"&lt;/span&gt;: &lt;span class="s2"&gt;"Requests for GitHub APIs"&lt;/span&gt;,
      &lt;span class="s2"&gt;"status"&lt;/span&gt;: &lt;span class="s2"&gt;"operational"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;,
    &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"Webhooks"&lt;/span&gt;,
      &lt;span class="s2"&gt;"description"&lt;/span&gt;: &lt;span class="s2"&gt;"Real time HTTP callbacks of user-generated and system events"&lt;/span&gt;,
      &lt;span class="s2"&gt;"status"&lt;/span&gt;: &lt;span class="s2"&gt;"operational"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;,
    &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"Visit www.githubstatus.com for more information"&lt;/span&gt;,
      &lt;span class="s2"&gt;"description"&lt;/span&gt;: &lt;span class="s2"&gt;""&lt;/span&gt;,
      &lt;span class="s2"&gt;"status"&lt;/span&gt;: &lt;span class="s2"&gt;"operational"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;,
    &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"Issues"&lt;/span&gt;,
      &lt;span class="s2"&gt;"description"&lt;/span&gt;: &lt;span class="s2"&gt;"Requests for Issues on GitHub.com"&lt;/span&gt;,
      &lt;span class="s2"&gt;"status"&lt;/span&gt;: &lt;span class="s2"&gt;"operational"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;,
    &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"Pull Requests"&lt;/span&gt;,
      &lt;span class="s2"&gt;"description"&lt;/span&gt;: &lt;span class="s2"&gt;"Requests for Pull Requests on GitHub.com"&lt;/span&gt;,
      &lt;span class="s2"&gt;"status"&lt;/span&gt;: &lt;span class="s2"&gt;"operational"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;,
    &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"GitHub Actions"&lt;/span&gt;,
      &lt;span class="s2"&gt;"description"&lt;/span&gt;: &lt;span class="s2"&gt;"Workflows, Compute and Orchestration for GitHub Actions"&lt;/span&gt;,
      &lt;span class="s2"&gt;"status"&lt;/span&gt;: &lt;span class="s2"&gt;"operational"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;,
    &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"GitHub Packages"&lt;/span&gt;,
      &lt;span class="s2"&gt;"description"&lt;/span&gt;: &lt;span class="s2"&gt;"API requests and webhook delivery for GitHub Packages"&lt;/span&gt;,
      &lt;span class="s2"&gt;"status"&lt;/span&gt;: &lt;span class="s2"&gt;"operational"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;,
    &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"GitHub Pages"&lt;/span&gt;,
      &lt;span class="s2"&gt;"description"&lt;/span&gt;: &lt;span class="s2"&gt;"Frontend application and API servers for Pages builds"&lt;/span&gt;,
      &lt;span class="s2"&gt;"status"&lt;/span&gt;: &lt;span class="s2"&gt;"operational"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;]&lt;/span&gt;,
  &lt;span class="s2"&gt;"Status"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"description"&lt;/span&gt;: &lt;span class="s2"&gt;"All Systems Operational"&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Providing you have set up the Golang environment correctly on your system, you should now be able to build/install a binary of the client. This will allow you to call the program from wherever you are on your system.&lt;/p&gt;

&lt;p&gt;An example use case - you are developing a really cool app and you need to push your code up to GitHub but you are getting an error in your terminal. Well, now you can use your chosen command to call this program instead of having to search the internet for a service status 😉&lt;/p&gt;

&lt;p&gt;To do this, you simply use the command &lt;code&gt;go install&lt;/code&gt;. This will build a binary and store it within the directory &lt;code&gt;go/src/bin&lt;/code&gt;. Providing this is on your &lt;code&gt;PATH&lt;/code&gt; you can call it from anywhere. &lt;/p&gt;

&lt;p&gt;Official docs specify this. To see the full explanation use the command &lt;code&gt;go help install&lt;/code&gt; in your terminal from within your project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;usage: go install [-i] [build flags] [packages]

Install compiles and installs the packages named by the import paths.

Executables are installed in the directory named by the GOBIN environment
variable, which defaults to $GOPATH/bin or $HOME/go/bin if the GOPATH
environment variable is not set. Executables in $GOROOT
are installed in $GOROOT/bin or $GOTOOLDIR instead of $GOBIN.
etc...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is my example of me calling it from my &lt;code&gt;$HOME&lt;/code&gt; directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;➜  ~ get-github-status
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"Components"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"Git Operations"&lt;/span&gt;,
      &lt;span class="s2"&gt;"description"&lt;/span&gt;: &lt;span class="s2"&gt;"Performance of git clones, pulls, pushes, and associated operations"&lt;/span&gt;,
      &lt;span class="s2"&gt;"status"&lt;/span&gt;: &lt;span class="s2"&gt;"operational"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;,
etc...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you have issues calling the binary from outside of this directory, use the following command and try again:&lt;br&gt;
&lt;code&gt;export PATH=$PATH:$(go env GOPATH)/bin&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And there you have it, a simple example of 2 microservices running in a hybrid like scenario. Neither one is dependant on the other. You can switch them up and modify this to fit your needs.&lt;/p&gt;

&lt;p&gt;For example, the following code is for a python client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://YOU-ROUTE-ENDPOINT&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;pretty_json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pretty_json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you have any questions or want to see more content like this, feel free to reach out!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/liamchampton" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/liamchampton" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.instagram.com/liamhampton/" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt;&lt;br&gt;
&lt;a href="//www.linkedin.com/in/liam-conroy-hampton"&gt;LinkedIn&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alternatively, you can see what my team get up to and our other projects on our website &lt;a href="https://ibmdeveloperuk.github.io" rel="noopener noreferrer"&gt;IBM Developer UK&lt;/a&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>go</category>
      <category>beginners</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Build/Test/Deploy your Go App using IBM Cloud Toolchain</title>
      <dc:creator>Liam Conroy Hampton</dc:creator>
      <pubDate>Thu, 24 Sep 2020 12:45:08 +0000</pubDate>
      <link>https://dev.to/liamchampton/build-test-deploy-your-go-app-using-ibm-cloud-toolchain-1onc</link>
      <guid>https://dev.to/liamchampton/build-test-deploy-your-go-app-using-ibm-cloud-toolchain-1onc</guid>
      <description>&lt;p&gt;Whether you're a project manager, part of a dev team, or flying solo, there is always the looming issue of incremental changes to your project. Gone are the days of waterfall development - Agile is the 'in' thing. You are running fortnightly sprints and releasing on a regular basis. You've probably seen a lot of options for deployment methods, lots of continuous integration/continuous delivery (CI/CD) pipelines, and much more.&lt;/p&gt;

&lt;p&gt;On the face of it, this is a journey for getting the application on your local system deployed into the cloud in stages using a pipeline.&lt;/p&gt;

&lt;p&gt;A pipeline allows you to work on small features independently and deploy them one by one without taking down the application, or better yet, prevent you from having to write the application all in one go and then deploying it in one big push. This will allow you to fail small and fail fast. In return, leaving less technical debt and allowing faster development.&lt;/p&gt;

&lt;p&gt;The diagram below outlines the aim of this using a simple pull request example&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh9lo3isuxsqjmmv7b3h5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh9lo3isuxsqjmmv7b3h5.png" alt="Pull Request" width="800" height="529"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you can see how simple it really is, in this blog, I will show you how to build, test, and deploy your application under one roof in a matter of minutes using IBM Cloud Toolchain. That's right.. in a matter of minutes.&lt;/p&gt;

&lt;p&gt;But first, you will need some prerequisites:&lt;br&gt;
1) IBM Cloud Lite account - sign up &lt;a href="https://ibm.biz/Bdq3RU" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;br&gt;
2) GitHub account&lt;br&gt;
3) Golang installed on your machine&lt;/p&gt;

&lt;p&gt;Let's get started!&lt;/p&gt;
&lt;h2&gt;
  
  
  Create your Go app and get it into GitHub
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Step 1 - Create an empty repository in GitHub
&lt;/h3&gt;

&lt;p&gt;Navigate to your GitHub profile, click on the &lt;code&gt;+&lt;/code&gt; in the top right corner and select "New repository". Give it a name and make sure it is public. Feel free to also add a license .gitignore file and a README.md if you like&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F55azj26ry9cdcxj3nw8q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F55azj26ry9cdcxj3nw8q.png" alt="Create New Repository" width="800" height="421"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 2 - Let's create a simple Golang HTTP Server with an accompanying test
&lt;/h3&gt;

&lt;p&gt;In a terminal clone your new repository into &lt;code&gt;$HOME/go/src/github.com&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Navigate into the cloned project using the &lt;code&gt;cd&lt;/code&gt; command and initiate go modules with the command &lt;code&gt;go mod init&lt;/code&gt; (in some cases you may need to specify the exact project path) and then open it in your preferred editor (I use Visual Studio Code)&lt;/p&gt;

&lt;p&gt;Note - if you do not have this folder tree already (go/src/github.com), then create it&lt;/p&gt;

&lt;p&gt;Create a test file in the root of the project (main_test.go):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "net/http"
    "net/http/httptest"
    "testing"
)

func TestHomeRoute(t *testing.T) {
    t.Run("returns message", func(t *testing.T) {
        request, _ := http.NewRequest(http.MethodGet, "/", nil)
        response := httptest.NewRecorder()

        Home(response, request)

        got := response.Body.String()
        want := "This is a toolchain test PR"

        if got != want {
            t.Errorf("got %q, want %q", got, want)
        }
    })
}

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

&lt;/div&gt;



&lt;p&gt;Run the test and watch it fail using the following command in your terminal&lt;br&gt;
&lt;code&gt;go test ./...&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now it is time to write just enough code for the test to pass (this is called TDD - test-driven development)&lt;/p&gt;

&lt;p&gt;Create a main file in the project root (main.go). This will be home to the sever code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "fmt"
    "net/http"
)

func main() {
    // Create the route handler listening on '/'
    http.HandleFunc("/", Home)
    fmt.Println("Starting server on port 8080")

    // Start the sever
    http.ListenAndServe(":8080", nil)
}

func Home(w http.ResponseWriter, r *http.Request) {
    // Assign the 'msg' variable with a string value
    msg := "This is a toolchain test PR"

    // Write the response to the byte array - Sprintf formats and returns a string without printing it anywhere
    w.Write([]byte(fmt.Sprintf(msg)))
}

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

&lt;/div&gt;



&lt;p&gt;Run the test command &lt;code&gt;go test ./...&lt;/code&gt; and your test should pass&lt;/p&gt;

&lt;p&gt;To see this in action, you can run the program with the &lt;code&gt;go run main.go&lt;/code&gt; command and navigating to &lt;code&gt;localhost:8080&lt;/code&gt; in your web browser&lt;/p&gt;

&lt;p&gt;To quit the program use the commands &lt;code&gt;control + C&lt;/code&gt; in your terminal&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3 - Push your code into the GitHub repository
&lt;/h3&gt;

&lt;p&gt;Let's get this code into GitHub.. Don't worry it's pretty simple, just follow the following commands&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git add .&lt;/code&gt; - this command will add all of the new/modified files into staging ready to be committed&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git commit -m "initial commit"&lt;/code&gt; - this command commits the changes ready to be pushed with a message so they can easily be identified&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git push origin master&lt;/code&gt; - this will push the changes into the master/main branch - this is fine for an initial commit but going forward you will use feature branches&lt;/p&gt;

&lt;p&gt;Awesome - you now have a simple Golang HTTP server with a test that you can push to any cloud, but what if you wanted to branch out and have others work on this? What if you had to add incremental changes and automate the deployment of it? - manual deployments need precision, they are time-consuming and weight on any chain for a team!&lt;/p&gt;

&lt;p&gt;Let's use IBM Cloud Toolchain for this. &lt;br&gt;
"What is IBM Cloud Toolchain?" you ask...&lt;/p&gt;

&lt;p&gt;Well, that's quite simple. It is a tool that allows you to concatenate actions, called stages. Each stage will have 'jobs' and these allow you to choose what you want to do with your application in that stage, be it build, test, or deploy - heck, why not all of them?&lt;/p&gt;

&lt;p&gt;In this blog, we will run a test stage to ensure the code compiles and the tests pass on the pull request. Then once the pull request is merged into the main production branch another stage will compile the code, run the tests, and then automatically deploy the application into Cloud Foundry. Sound good? - let's go!&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating a toolchain
&lt;/h2&gt;

&lt;p&gt;Login or &lt;a href="https://ibm.biz/Bdq3RU" rel="noopener noreferrer"&gt;sign up&lt;/a&gt; to IBM Cloud&lt;/p&gt;

&lt;p&gt;Navigate to the DevOps section in IBM Cloud using the navigation menu on the left&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fo54ta2jhzoxw8as6b7uv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fo54ta2jhzoxw8as6b7uv.png" alt="DevOps" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select your region and then create a new toolchain&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8twn69plr9fh8xxrrnxd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8twn69plr9fh8xxrrnxd.png" alt="New Toolchain" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Scroll down to the bottom and select "Build your own toolchain"&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1nps7ofy16fohhpzutmd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1nps7ofy16fohhpzutmd.png" alt="Build your own toolchain" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Choose an appropriate name and select the correct region for your toolchain&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fyezb551djst7adfueaks.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fyezb551djst7adfueaks.png" alt="Name Toolchain" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cool, you now have the foundation - add a new tool to your toolchain&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpk2fts0k3h00m3qj5fn4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpk2fts0k3h00m3qj5fn4.png" alt="Add Tool" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We want to have GitHub integration so search for "GitHub" and select the GitHub tool&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8ma97rxcm7118a1y3ab6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8ma97rxcm7118a1y3ab6.png" alt="Add GitHub tool" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Set up the GitHub tool to have the correct information for your project repository, as an example, mine is&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzvxtenffem5vvcftsv4n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzvxtenffem5vvcftsv4n.png" alt="Setup GitHub tool" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should now see that the GitHub tool on the toolchain overview has ticks and the word "configured". This will give it access to the repository information (you may be asked to confirm this on GitHub)&lt;/p&gt;

&lt;p&gt;Next, you need to add a pipeline. On the toolchain overview, just like you did with the GitHub tool, select "Add tool" and search for "pipeline". Select "Delivery Pipeline"&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4ebgcxu86z9254sb6ee8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4ebgcxu86z9254sb6ee8.png" alt="Add pipeline tool" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Configure the pipeline by giving it a name and ensuring the pipeline type is "Classic" and not "TekTon"&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkmimzar6242s3rccssd2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkmimzar6242s3rccssd2.png" alt="Configure Pipeline" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you haven't used a pipeline in IBM Cloud before, you may see the following error. You just need to add a continuous delivery service which will enable the CI/CD&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwiu5pv5d0r97c9bi0gjc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwiu5pv5d0r97c9bi0gjc.png" alt="Pipeline Error" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Search for continuous delivery and select "Continuous Delivery" - You only need to do this once!&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftmxoe6mzeds3tb4ukhbw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftmxoe6mzeds3tb4ukhbw.png" alt="Search Continuous Delivery" width="800" height="145"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Setup the service. Make sure the region is set to the same as your toolchain, give it the same name as what you called your pipeline service. In this example, it is "CI-CD-Service". Once filled out, create it&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fel0vyx9mflobw925f59e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fel0vyx9mflobw925f59e.png" alt="Continuous Delivery Setup 1" width="800" height="417"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6oscirtx43wnilmzypa9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6oscirtx43wnilmzypa9.png" alt="Continuous Delivery Setup 2" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now head back to your toolchain and click on the Pipeline box itself. You will be taken to a blank page. In the top right select "Add Stage"&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkrfetfjgb3yfcepdt62u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkrfetfjgb3yfcepdt62u.png" alt="Add Stage" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Call it the "Test Stage" and this will build the code and then run the tests. Make sure the input type is the git repository for your project, the branch is set to "master" and you want this stage to run "When a pull request is opened or updated"&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F21jns3spo01yjnhj3d2c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F21jns3spo01yjnhj3d2c.png" alt="Test Stage Setup 1" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the "Input" has been set up, move along to the "Jobs" and create 2 jobs. 1 x Build and 1 x Test. There is no Golang buildpack in the toolchain so we need to use a docker image with the environment set up for us&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhmclqs0xw3ejlrttrsio.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhmclqs0xw3ejlrttrsio.png" alt="Test Stage Setup 2" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add the following script into the build script box on the "Build" stage and modify it to suit your project. I called my directory "gohttpserver" but you can change it to be the name of your repository/project. This script just moved the code from a temporary directory on the virtual machine into the directory tree much like you would have locally on your machine. It then builds a binary to test the code compiles&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash
pwd
ls -la
cd $HOME
mkdir -p go/src/github.com
mkdir -p go/pkg
mkdir -p go/bin
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin
cd $HOME/go/src/github.com
cp -ar /home/pipeline/* /root/go/src/github.com
mv ./* gohttpserver
cd gohttpserver
go build -o serverbinary
chmod -v +x serverbinary
pwd
ls -la
echo code compiled successfully
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Move onto the "Test" stage and do the same. Copy the script from your "Build" stage and modify the end of it to look something 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;#!/bin/bash
pwd
ls -la
cd $HOME
mkdir -p go/src/github.com
mkdir -p go/pkg
mkdir -p go/bin
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin
cd $HOME/go/src/github.com
cp -ar /home/pipeline/* /root/go/src/github.com
mv ./* gohttpserver
cd gohttpserver
go test ./...
echo test run successful
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is just running the tests within the repository and not building a binary&lt;/p&gt;

&lt;p&gt;That is the Build/Test stage complete, now we need to create the deploy stage. This stage will run when the pull request is merged into the main/master branch&lt;/p&gt;

&lt;p&gt;Go back to the stages overview and clone the first stage we created by clicking the cog on the stage and selecting "Clone stage"&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fifwqnsju7vnbhykc6aw0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fifwqnsju7vnbhykc6aw0.png" alt="Clone Stage" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click the cog on the newly cloned stage and click "configure". Rename it to "Deploy" and we want this stage to be triggered by a new commit into the master/main branch and not on a new pull request. On the "Input" tab, check the box "When a commit is pushed"&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fi764ib2a9as1lf5k5xaq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fi764ib2a9as1lf5k5xaq.png" alt="Deploy Stage Trigger" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the "Jobs" section, add a new "Deploy" job and fill out the details for your project. You want to make sure the deployer type is Cloud Foundry (you can choose Kubernetes if you wish but the setup will be different). You will also need to create a new API key for the integration to work (shown below)&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpp69kufzetbi4oaqca6i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpp69kufzetbi4oaqca6i.png" alt="Deploy Setup 1" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Make sure the region selected is the same as your toolchain and the application name is the same as your pipeline. The script is very simple and should be pre-populated for you. Once completed, save and exit&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3u8oyt40ribsmecwjl40.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3u8oyt40ribsmecwjl40.png" alt="Deploy Setup 2" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your toolchain is now set up!&lt;/p&gt;

&lt;p&gt;Time for a code change...&lt;br&gt;
First, within your project, checkout a new local feature branch using the following command in a terminal&lt;br&gt;
&lt;code&gt;git checkout -b test-new-toolchain&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Next, change the test file &lt;code&gt;main_test.go&lt;/code&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2pjqynwgcgz82y73jv8n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2pjqynwgcgz82y73jv8n.png" alt="Test Code Change" width="800" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And then change the corresponding code in &lt;code&gt;main.go&lt;/code&gt; and push the code up to the new remote branch using the commands seen below&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fy2f4vepjeq4dnvxww6ik.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fy2f4vepjeq4dnvxww6ik.png" alt="Main Code Change" width="800" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you can open a pull request in GitHub. Ensure the pull request is from the new branch you have just created, give it a meaningful title and description. Then click "Create pull request"&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh0rnwj4xokcch438gjcg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh0rnwj4xokcch438gjcg.png" alt="Create Pull Request" width="800" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once open, you will see the IBM Cloud toolchain integration. If you check the toolchain stages you will see it running the first stage you called "Test Stage"&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzt9biguxx7gxf5ktog9x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzt9biguxx7gxf5ktog9x.png" alt="Open Pull Request" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the test stage has finished, you will be able to merge the pull request. Go ahead and merge it. Then check the toolchain and you will see&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcaomg3q7pjl3a4p3atk0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcaomg3q7pjl3a4p3atk0.png" alt="Stages Running" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the build stage has finished, click on the link "View logs and history". Scroll to the bottom and you will see the result of the build and where it is deployed in Cloud Foundry. Navigate to the route in a browser and you will see your app running&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8mu0ev0bs0v53yczyc4e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8mu0ev0bs0v53yczyc4e.png" alt="Deployed Logs" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;If you check the merged pull request, you will see a message of successful deployment and a tag from the toolchain&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs3j1c66votwwxu4ad0o1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs3j1c66votwwxu4ad0o1.png" alt="Merged Pull Request" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You've now got a CI/CD IBM Cloud Toolchain set up.. how easy was that?!&lt;/p&gt;

&lt;p&gt;Although this blog uses a Docker image for the Golang environment, many other projects can be built using the readily available buildpacks in IBM Cloud (a list of these can be found in the stage configurator)&lt;/p&gt;

&lt;p&gt;If you have any questions or want to see more content like this, feel free to reach out!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/liamchampton" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/liamchampton" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.instagram.com/liamhampton/" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt;&lt;br&gt;
&lt;a href="//www.linkedin.com/in/liam-conroy-hampton"&gt;LinkedIn&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>devops</category>
      <category>go</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
