<?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: omar shabab</title>
    <description>The latest articles on DEV Community by omar shabab (@omar16100).</description>
    <link>https://dev.to/omar16100</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%2F127290%2Fd8c56cd6-13aa-428e-9239-f1c12c36e437.jpg</url>
      <title>DEV Community: omar shabab</title>
      <link>https://dev.to/omar16100</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/omar16100"/>
    <language>en</language>
    <item>
      <title>Trigger Bitbucket Pipeline Only If Certain Files Are Changed (With Google Cloud Functions)</title>
      <dc:creator>omar shabab</dc:creator>
      <pubDate>Wed, 20 May 2020 10:24:24 +0000</pubDate>
      <link>https://dev.to/omar16100/trigger-bitbucket-pipeline-only-if-certain-files-are-changed-with-google-cloud-functions-1abc</link>
      <guid>https://dev.to/omar16100/trigger-bitbucket-pipeline-only-if-certain-files-are-changed-with-google-cloud-functions-1abc</guid>
      <description>&lt;p&gt;First appeared in &lt;a href="https://omar.ai/posts/bitbucket_pipelines_custom_trigger/" rel="noopener noreferrer"&gt;omar.ai&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;&lt;sup&gt;Overview of what you will do.&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;Having DevOps practices can make you really productive as a developer. It is a culture in an organization and there are countless tools we can use to implement such solutions.&lt;/p&gt;

&lt;p&gt;In this article we will implement a Bitbucket CI/CD pipeline.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Assumption : you have some familiarity with DevOps, CI/CD, Cloud Functions, Bitbucket and docker. If not, you may visit the references.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Scenerio
&lt;/h2&gt;

&lt;p&gt;You have multiple cloud functions in a repository and want an individual build-test-deployment option for each function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ft11g0smbdavg0xeqmo41.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ft11g0smbdavg0xeqmo41.png" alt="Screenshot of bitbucket repository"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note : these example functions are extended from the sample provided in GCP documentation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Let's say you have two functions which prints
&lt;/h3&gt;

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

Hello World!


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

&lt;/div&gt;

&lt;p&gt;and&lt;/p&gt;

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

Hello Mars!


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

&lt;/div&gt;

&lt;p&gt;These functions are hosted in Bitbucket and initially you can deploy them from your local environment :&lt;/p&gt;

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

gcloud functions deploy hello_world &lt;span class="nt"&gt;--allow-unauthenticated&lt;/span&gt; &lt;span class="nt"&gt;--runtime&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;python37 &lt;span class="nt"&gt;--memory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;128MB &lt;span class="nt"&gt;--source&lt;/span&gt; hello_word/ &lt;span class="nt"&gt;--timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;300 &lt;span class="nt"&gt;--trigger-http&lt;/span&gt; &lt;span class="nt"&gt;--entry-point&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;hello_world


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

&lt;/div&gt;

&lt;p&gt;But this is not the ideal process. Solution is to use version control and automated build, test and deployment.&lt;/p&gt;

&lt;p&gt;Below is a new feature for Bitbucket pipelines at the time of writing which triggers the pipeline when certain files are changed :&lt;/p&gt;

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

condition:
    changesets:
        includePaths:
          - &lt;span class="s2"&gt;"path/*"&lt;/span&gt;



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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Hands-on
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Steps
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create a service account in GCP&lt;/li&gt;
&lt;li&gt;Export the service account credentials to Bitbucket and configure the bitbucket parameters&lt;/li&gt;
&lt;li&gt;Setup Bitbucket pipelines&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  From GCP console
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;IAM &amp;amp; Admin -&amp;gt; Service Accounts -&amp;gt; Create Service Account&lt;/li&gt;
&lt;li&gt;Choose an appropriate name and click create&lt;/li&gt;
&lt;li&gt;Select 'Service Account User' role&lt;/li&gt;
&lt;li&gt;Click 'Create Key' and save the .json file. Finally, press 'Done' to proceed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your service account is created and you need to provide some permissions for the Bitbucket pipelines to work properly.&lt;/p&gt;
&lt;h3&gt;
  
  
  From IAM &amp;amp; Admin
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Go to 'Roles'&lt;/li&gt;
&lt;li&gt;Select 'Create Role'&lt;/li&gt;
&lt;li&gt;Give suitable names 'Title' and 'ID'&lt;/li&gt;
&lt;li&gt;In 'Add Permissions' add 'Cloud Functions Admin' &amp;amp; 'Service Account User'&lt;/li&gt;
&lt;li&gt;Click 'Create' and your custom role is created which needs to be attached to the service account&lt;/li&gt;
&lt;li&gt;Go to 'IAM' and select your service account which was created earlier&lt;/li&gt;
&lt;li&gt;Click inheritence and add the role to it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next up is configuring Bitbucket pipelines.&lt;/p&gt;

&lt;p&gt;You will have to set up the environment variables first. We have to do this because hard-coding credentials is a bad practice.&lt;/p&gt;

&lt;p&gt;Try to make the variables as verbose as possible, it helps when you have multi-environment variables. e.g. think if you had 10 functions from 10 different projects.&lt;/p&gt;

&lt;p&gt;The following variables should be added.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

GCP_PROJECT_PROJECT_ID
GCP_PROJECT_PRIVATE_KEY_ID
GCP_PROJECT_PRIVATE_KEY
GCP_PROJECT_EMAIL
GCP_PROJECT_CLIENT_ID
GCP_PROJECT_CERT_URL
GCP_PROJECT_REGION


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

&lt;/div&gt;

&lt;p&gt;Substitute the 'PROJECT' with your 'project name'.&lt;/p&gt;

&lt;p&gt;As this is a how-to guide, I will not be using multi-environment variables. The default naming is not changed.&lt;/p&gt;

&lt;h3&gt;
  
  
  In Bitbucket repository
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Go to 'Repository Settings' -&amp;gt; 'Repository variables'&lt;/li&gt;
&lt;li&gt;If enabling pipelines is required, follow the steps&lt;/li&gt;
&lt;li&gt;Commit the default pipeline provided which you are going to change soon&lt;/li&gt;
&lt;li&gt;Add the above mentioned names. The values are from the service account credential file and the region is the one you are using&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Create a file named "sa-PROJECT.dist.json". Where 'sa' stands for 'service account' and 'PROJECT' for 'projet name'.&lt;/p&gt;

&lt;p&gt;Contents of the file is a copy of your credentials from the service account but with the environment variables.&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;"type"&lt;/span&gt;: &lt;span class="s2"&gt;"service_account"&lt;/span&gt;,
&lt;span class="s2"&gt;"project_id"&lt;/span&gt;: &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$GCP_PROJECT_PROJECT_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;,
&lt;span class="s2"&gt;"private_key_id"&lt;/span&gt;: &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$GCP_PROJECT_PRIVATE_KEY_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;,
&lt;span class="s2"&gt;"private_key"&lt;/span&gt;: &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$GCP_PROJECT_PRIVATE_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;,
&lt;span class="s2"&gt;"client_email"&lt;/span&gt;: &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$GCP_PROJECT_EMAIL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;,
&lt;span class="s2"&gt;"client_id"&lt;/span&gt;: &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$GCP_PROJECT_CLIENT_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;,
&lt;span class="s2"&gt;"auth_uri"&lt;/span&gt;: &lt;span class="s2"&gt;"https://accounts.google.com/o/oauth2/auth"&lt;/span&gt;,
&lt;span class="s2"&gt;"token_uri"&lt;/span&gt;: &lt;span class="s2"&gt;"https://oauth2.googleapis.com/token"&lt;/span&gt;,
&lt;span class="s2"&gt;"auth_provider_x509_cert_url"&lt;/span&gt;: &lt;span class="s2"&gt;"https://www.googleapis.com/oauth2/v1/certs"&lt;/span&gt;,
&lt;span class="s2"&gt;"client_x509_cert_url"&lt;/span&gt;: &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$GCP_PROJECT_CERT_URL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  Now you will work with the bitbucket-pipelines.yml file
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://bitbucket-pipelines.prod.public.atl-paas.net/validator" rel="noopener noreferrer"&gt;They have a sweet tool to validate your pipelines.&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;bitbucket-pipelines.yml :&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

pipelines:
  branches:
    master:
      - step:
          name: Deploy hello_world
&lt;span class="c"&gt;#          deployment: test/ staging/ production&lt;/span&gt;
          image: google/cloud-sdk:234.0.0
          script:
              - apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; gettext-base
              - envsubst &amp;lt; sa-PROJECT.dist.json &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; service-account.json
              - gcloud auth activate-service-account &lt;span class="nt"&gt;--key-file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;service-account.json
              - gcloud functions deploy hello_world &lt;span class="nt"&gt;--runtime&lt;/span&gt; python37 &lt;span class="nt"&gt;--trigger-http&lt;/span&gt; &lt;span class="nt"&gt;--project&lt;/span&gt; &lt;span class="nv"&gt;$GCP_PROJECT_PROJECT_ID&lt;/span&gt; &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="nv"&gt;$GCP_PROJECT_REGION&lt;/span&gt; &lt;span class="nt"&gt;--source&lt;/span&gt; hello_world/
          condition:
              changesets:
                 includePaths:
                   - &lt;span class="s2"&gt;"hello_world/*"&lt;/span&gt;
      - step:
          name: Deploy hello_mars
&lt;span class="c"&gt;#          deployment: test/ staging/ production&lt;/span&gt;
          image: google/cloud-sdk:234.0.0
          script:
              - apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; gettext-base
              - envsubst &amp;lt; sa-PROJECT.dist.json &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; service-account.json
              - gcloud auth activate-service-account &lt;span class="nt"&gt;--key-file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;service-account.json
              - gcloud functions deploy hello_mars &lt;span class="nt"&gt;--runtime&lt;/span&gt; python37 &lt;span class="nt"&gt;--trigger-http&lt;/span&gt; &lt;span class="nt"&gt;--project&lt;/span&gt; &lt;span class="nv"&gt;$GCP_PROJECT_PROJECT_ID&lt;/span&gt; &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="nv"&gt;$GCP_PROJECT_REGION&lt;/span&gt; &lt;span class="nt"&gt;--source&lt;/span&gt; hello_mars/
          condition:
              changesets:
                 includePaths:
                   - &lt;span class="s2"&gt;"hello_mars/*"&lt;/span&gt;



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

&lt;/div&gt;

&lt;p&gt;You can find the code at this &lt;a href="https://bitbucket.org/omar16100/bitbucket_pipelines_custom_trigger_cloud_functions/src/master/" rel="noopener noreferrer"&gt;Bitbucket repository&lt;/a&gt;. And you can use it as template.&lt;/p&gt;

&lt;p&gt;So now if you want to experiment you may modify 'hello_mars' only 'hello mars' will be deployed and vice versa.&lt;/p&gt;

&lt;p&gt;And you are done triggering bitbucket pipelines when certain files are changed!&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you have any feedback, you may comment below or tweet &lt;a href="https://twitter.com/omar161000" rel="noopener noreferrer"&gt;@omar161000&lt;/a&gt;.&lt;br&gt;
Connect with me on &lt;a href="https://www.linkedin.com/in/omar16100" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Thanks for reviewing the drafts :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.linkedin.com/in/sheikhhanif/" rel="noopener noreferrer"&gt;Sheikh Hanif&lt;/a&gt; and&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/tahmida-sumbula-6711081a0/" rel="noopener noreferrer"&gt;Tahmida Sumbula&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;First appeared in &lt;a href="https://omar.ai/posts/bitbucket_pipelines_custom_trigger/" rel="noopener noreferrer"&gt;omar.ai&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bitbucket.org/blog/an-introduction-to-bitbucket-pipelines" rel="noopener noreferrer"&gt;An introduction to Bitbucket Pipelines&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://confluence.atlassian.com/bitbucket/configure-bitbucket-pipelines-yml-792298910.html" rel="noopener noreferrer"&gt;Configure bitbucket-pipelines.yml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/functions/docs/how-to" rel="noopener noreferrer"&gt;Cloud Functions : How-to guides&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.primitivesense.com/case-studies/ci-with-testing-and-deploying-google-cloud-functions-within-bitbucket-pipelines/" rel="noopener noreferrer"&gt;Testing &amp;amp; deploying Google Cloud Functions in BitBucket Pipelines&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://confluence.atlassian.com/bitbucket/variables-in-pipelines-794502608.html" rel="noopener noreferrer"&gt;Varibles in pipelines&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Definitions
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/YAML" rel="noopener noreferrer"&gt;YAML&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;YAML Ain't Markup Language. It is commonly used for configuration files and in applications where data is being stored or transmitted. It uses both Python-style indentation to indicate nesting, and a more compact format that uses [] for lists and {} for maps[1] making YAML 1.2 a superset of JSON.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://en.wikipedia.org/wiki/Docker_(software)" rel="noopener noreferrer"&gt;Docker&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Is a form of delivering softwares in packages called containers. Containers are isolated from one another and bundle their own software, libraries and configuration files; they can communicate with each other through well-defined channels. All containers are run by a single operating system kernel and therefore use fewer resources than virtual machines. In this post, docker images have been used run all the commands in the yml file.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://en.wikipedia.org/wiki/DevOps" rel="noopener noreferrer"&gt;DevOps&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;DevOps is a set of practices that combines software development and information-technology operations which aims to shorten the systems development life cycle and provide continuous delivery with high software quality.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://en.wikipedia.org/wiki/CI/CD" rel="noopener noreferrer"&gt;CI/CD&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;generally refers to the combined practices of continuous integration and either continuous delivery and/or continuous deployment. &lt;a href="https://opensource.com/article/18/8/what-cicd" rel="noopener noreferrer"&gt;More detailed&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Pipelines

&lt;ul&gt;
&lt;li&gt;the steps that needs to be done to perform CI/CD&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://en.wikipedia.org/wiki/Bitbucket" rel="noopener noreferrer"&gt;Bitbucket&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Bitbucket is a web-based version control repository hosting service owned by Atlassian, for source code and development projects that use either Mercurial or Git revision control systems. Bitbucket offers both commercial plans and free accounts.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://en.wikipedia.org/wiki/Google_Cloud_Platform" rel="noopener noreferrer"&gt;Google Cloud Platform (GCP)&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Google Cloud Platform, offered by Google, is a suite of cloud computing services that runs on the same infrastructure that Google uses internally for its end-user products, such as Google Search, Gmail and YouTube.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://cloud.google.com/functions" rel="noopener noreferrer"&gt;Cloud functions&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Cloud Functions is Google Cloud’s event-driven serverless compute platform. Run your code locally or in the cloud without having to provision servers. Go from code to deploy with continuous delivery and monitoring tools. Cloud Functions scales up or down, so you pay only for compute resources you use. Easily create end-to-end complex development scenarios by connecting with existing Google Cloud or third-party services.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Go up.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>cicd</category>
      <category>gcp</category>
      <category>bitbucket</category>
    </item>
  </channel>
</rss>
