{"id":60877,"date":"2024-03-21T12:42:16","date_gmt":"2024-03-21T07:12:16","guid":{"rendered":"https:\/\/www.tothenew.com\/blog\/?p=60877"},"modified":"2024-03-21T12:42:16","modified_gmt":"2024-03-21T07:12:16","slug":"adding-approval-workflow-to-your-github-action","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/adding-approval-workflow-to-your-github-action\/","title":{"rendered":"Adding approval workflow to your GitHub Action"},"content":{"rendered":"<h2><b>Introduction<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">GitHub Actions has become an integral part of modern software development, streamlining continuous integration and delivery processes. However, users have longed for a straightforward approval flow, similar to Azure Pipelines. It offers a simplified way to incorporate approval steps into CI\/CD pipelines. This update opens doors for users to enhance workflow control.<\/span><\/p>\n<h2><b>Objective<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">The objective is to inform and guide GitHub Actions to users through the newly introduced &#8220;reviewers&#8221; feature, which enables the creation of approval flows within their CI\/CD pipelines.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The focus is on providing a practical and accessible guide for users to quickly adopt and implement this feature in their workflows.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The aim is to empower users with the knowledge and tools to enhance their continuous integration and delivery practices using GitHub Actions.<\/span><\/p>\n<h2><b>Setting things up<\/b><\/h2>\n<ol>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">An Azure Account \u2014 You can get a free Azure account as well and do exactly this without any obligation.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Set up an Azure App Service resource \u2014 I\u2019m using App Service Linux and just created it using basically all the defaults.\u00a0<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Download the publish profile and save those somewhere for now as we\u2019ll refer back to them in the next step.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">In your App Service go to the Deployment Centre and select github action. Then select the options accordingly.<\/span><\/li>\n<\/ol>\n<p><span style=\"font-weight: 400;\">That\u2019s it!\u00a0 With those basics set up I can get started with the next steps of building out the workflow.\u00a0 I should note that the steps I outlined here are free for GitHub public repositories.\u00a0 For private repositories you need to be a GitHub Enterprise Server customer.\u00a0 Since my sample is public I\u2019m ready to go!<\/span><\/p>\n<h2><b>Environments<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">The first concept is Environments. These are basically a separate segmented definition of your repo that you can associate secrets and protection rules with. This is the key to the approval workflow as one of the protection rules is reviewers required (aka approvers).\u00a0 The first thing we\u2019ll do is set up two environments: staging and production.\u00a0 Go to your repository settings and you\u2019ll see a new section called Environments in the navigation.\u00a0<\/span><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-60870 size-large\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2024\/03\/Screenshot-from-2024-03-19-15-06-33-1024x304.png\" alt=\"\" width=\"625\" height=\"186\" \/><\/p>\n<p><span style=\"font-weight: 400;\">T<\/span><span style=\"font-weight: 400;\">o create an environment, click the New Environment button and give it a name. I created one called production and one called APPROVAL. In each of these you can do things independently like secrets and reviewers. Either way\u00a0 click the Required reviewers checkbox and add yourself at least and save protection rules.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Add Required reviewers. You can add the users for reviewers and these users are those who are collaborators.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Now we\u2019ll add some secrets. With Environments, you can have independent secrets for each environment. Remember those profiles you downloaded earlier, now you\u2019ll need them. In the production environment create a new secret named PUBLISH_PROFILE and paste in the contents of the publish profile. This allows our workflow to use environment-specific secret settings when they are called naming as we\u2019ll be marking the environment in the workflow and it will pick up secrets from that environment only (or the repo if not found there \u2013 you can have a hierarchy of secrets effectively).<\/span><\/p>\n<h2><b>Send a Google Chat Notification from a GitHub Action<\/b><\/h2>\n<h2><span style=\"font-weight: 400;\">To receive notifications when you want to build and deploy on prod to approve it.<\/span><\/h2>\n<ol>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Configure WebHook in a Google Chat Room to receive notifications \u00a0\u2192 <\/span>Direct message or spaces (select any one) \u2192 App &amp; Integrations \u2192 Add webhooks. Then copy the webhook link.<\/li>\n<li>Select the Github Repository.<\/li>\n<li><span style=\"font-weight: 400;\">Configure secrets needed for the GitHub action. We maintain the webhook URL (created in step 1)as a repository secret.<\/span><\/li>\n<\/ol>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Navigate to\u00a0 <\/span><span style=\"font-weight: 400;\">Settings \u2192 Secrets<\/span><span style=\"font-weight: 400;\"> and click on <\/span><span style=\"font-weight: 400;\">New repository secret<\/span><span style=\"font-weight: 400;\"> .<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Add a name to the secret (I have used it as PROAPPROVAL) and paste the webhook URL in that value section.\u00a0<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">NOTE: If you need to receive notifications into the same thread of the chat add the query param threadKey=&lt;some-value&gt; at the end of the URL.<\/span><\/li>\n<\/ul>\n<h2><b>Configure the GitHub Action<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">Create a yaml file in &lt;repository&gt;\/.github\/workflows path.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">NOTE : .yml extension is mandatory<\/span><\/p>\n<pre><span style=\"font-weight: 400;\">name<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">Deploy to Azure App Service<\/span>\r\n<span style=\"font-weight: 400;\">on<\/span><span style=\"font-weight: 400;\">:<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0<\/span><span style=\"font-weight: 400;\">push<\/span><span style=\"font-weight: 400;\">:<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">branches<\/span><span style=\"font-weight: 400;\">:<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0- <\/span><span style=\"font-weight: 400;\">app-service-deployment<\/span>\r\n<span style=\"font-weight: 400;\">jobs<\/span><span style=\"font-weight: 400;\">:<\/span>\r\n<span style=\"font-weight: 400;\">#for DEV environment<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0<\/span><span style=\"font-weight: 400;\">build-and-deploy-dev<\/span><span style=\"font-weight: 400;\">:<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">if<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">github.event.ref == 'refs\/heads\/main'<\/span><span style=\"font-weight: 400;\"> \u00a0<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">runs-on<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">ubuntu-latest<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">steps<\/span><span style=\"font-weight: 400;\">:<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0- <\/span><span style=\"font-weight: 400;\">name<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">Checkout Source<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">uses<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">actions\/checkout@v3<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0- <\/span><span style=\"font-weight: 400;\">name<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">Setup Node.js version<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">uses<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">actions\/setup-node@v4<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">with<\/span><span style=\"font-weight: 400;\">:<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">node-version<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">'18.x'<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0- <\/span><span style=\"font-weight: 400;\">name<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">Install Dependencies<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">run<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">npm install<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0- <\/span><span style=\"font-weight: 400;\">name<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">Deploy to Azure App Service (Dev)<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">uses<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">azure\/webapps-deploy@v2<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">with<\/span><span style=\"font-weight: 400;\">:<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">app-name<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">githubaction-dev<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">publish-profile<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">${{ secrets.DEV }}<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">package<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\"> \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\r\n<span style=\"font-weight: 400;\">#for non-prod environment<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0<\/span><span style=\"font-weight: 400;\">build-and-deploy-non-prod<\/span><span style=\"font-weight: 400;\">:<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">if<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">github.event.ref == 'refs\/heads\/main'<\/span><span style=\"font-weight: 400;\"> \u00a0<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">runs-on<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">ubuntu-latest<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">steps<\/span><span style=\"font-weight: 400;\">:<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0- <\/span><span style=\"font-weight: 400;\">name<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">Checkout Source<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">uses<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">actions\/checkout@v3<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0- <\/span><span style=\"font-weight: 400;\">name<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">Setup Node.js version<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">uses<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">actions\/setup-node@v4<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">with<\/span><span style=\"font-weight: 400;\">:<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">node-version<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">'18.x'<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0- <\/span><span style=\"font-weight: 400;\">name<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">Install Dependencies<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">run<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">npm install<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0- <\/span><span style=\"font-weight: 400;\">name<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">Deploy to Azure App Service (NON-PROD)<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">uses<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">azure\/webapps-deploy@v2<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">with<\/span><span style=\"font-weight: 400;\">:<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">app-name<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">githubaction-testing<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">publish-profile<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">${{ secrets.NONPROD }}<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">package<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">.<\/span>\r\n<span style=\"font-weight: 400;\">#for prod environment <\/span>\r\n<span style=\"font-weight: 400;\">\u00a0<\/span><span style=\"font-weight: 400;\">build-and-deploy-prod<\/span><span style=\"font-weight: 400;\">:<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">runs-on<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">ubuntu-latest<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">needs<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">notification<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">environment<\/span><span style=\"font-weight: 400;\">:<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">name<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">prodution<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">url<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">'githubaction-testing.azurewebsites.net'<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">outputs<\/span><span style=\"font-weight: 400;\">:<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">time<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">${{ steps.set-time.outputs.time }}<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">steps<\/span><span style=\"font-weight: 400;\">:<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0- <\/span><span style=\"font-weight: 400;\">name<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">Checkout Source<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">uses<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">actions\/checkout@v3<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0- <\/span><span style=\"font-weight: 400;\">name<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">Setup Node.js version<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">uses<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">actions\/setup-node@v4<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">with<\/span><span style=\"font-weight: 400;\">:<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">node-version<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">'18.x'<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0- <\/span><span style=\"font-weight: 400;\">name<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">Install Dependencies<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">run<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">npm install<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0- <\/span><span style=\"font-weight: 400;\">name<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">Deploy to Azure App Service (Prod)<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">uses<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">azure\/webapps-deploy@v2<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">with<\/span><span style=\"font-weight: 400;\">:<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">app-name<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">githubaction-testing<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">publish-profile<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">${{ secrets.TEST }}<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">package<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">.<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0<\/span><span style=\"font-weight: 400;\">notification<\/span><span style=\"font-weight: 400;\">:<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">runs-on<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">ubuntu-latest<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">steps<\/span><span style=\"font-weight: 400;\">:<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0- <\/span><span style=\"font-weight: 400;\">name<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">Notify on Google Chat<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">run<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">|<\/span>\r\n<span style=\"font-weight: 400;\"> \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GOOGLE_CHAT_ROOM=\"xYO8qkAAAAE\"<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0MESSAGE=\"Deployment approval request. Click [here](https:\/\/github.com\/${{ github.repository }}\/actions\/runs\/${{ github.run_id }}) to approve.\"<\/span>\r\n\r\n<span style=\"font-weight: 400;\"> \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0curl -X POST -H 'Content-Type: application\/json' \\<\/span>\r\n<span style=\"font-weight: 400;\"> \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0-d '{<\/span>\r\n<span style=\"font-weight: 400;\"> \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"text\": \"'\"$MESSAGE\"'\"<\/span>\r\n<span style=\"font-weight: 400;\"> \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}' \"${{ secrets.PROAPPROVAL }}\"<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0<\/span><span style=\"font-weight: 400;\">notify-after-deploy<\/span><span style=\"font-weight: 400;\">:<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">runs-on<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">ubuntu-latest<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">needs<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">build-and-deploy-prod<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">steps<\/span><span style=\"font-weight: 400;\">:<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0- <\/span><span style=\"font-weight: 400;\">name<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">Notify on Google Chat after deploy<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">if<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">success()<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">run<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">|<\/span>\r\n<span style=\"font-weight: 400;\"> \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GOOGLE_CHAT_ROOM=\"xYO8qkAAAAE\"<\/span>\r\n<span style=\"font-weight: 400;\"> \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0MESSAGE=\"Deployment and approval request is done.\"<\/span>\r\n<span style=\"font-weight: 400;\"> \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0curl -X POST -H 'Content-Type: application\/json' \\<\/span>\r\n<span style=\"font-weight: 400;\"> \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0-d '{<\/span>\r\n<span style=\"font-weight: 400;\"> \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"text\": \"'\"$MESSAGE\"'\"<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}' \"${{ secrets.PROAPPROVAL }}\"<\/span><\/pre>\n<p><span style=\"font-weight: 400;\">When the protection rules are hit, a few things happen. Namely the run stops and waits, but the reviewers are notified. The notification happens in standard GitHub notification means. I have email notifications and so I got an email like this:<\/span><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-60872 size-full\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2024\/03\/Screenshot-from-2024-03-19-11-23-44-1.png\" alt=\"\" width=\"776\" height=\"509\" \/><\/p>\n<p><span style=\"font-weight: 400;\">I can then click through and approve the workflow step and add comments:<\/span><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-60873 size-large\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2024\/03\/Screenshot-from-2024-03-19-11-24-15-1024x475.png\" alt=\"\" width=\"625\" height=\"290\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Once that step is approved, the job runs.<\/span><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-60874 size-full\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2024\/03\/Screenshot-from-2024-03-19-11-27-12.png\" alt=\"\" width=\"976\" height=\"438\" \/><\/p>\n<h2><b>Conclusion<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">In conclusion, the addition of new features of approval workflows in GitHub Actions is a significant enhancement, simplifying the integration of approval steps into CI\/CD pipelines. This feature empowers users to enhance workflow control, ensuring smoother and more secure deployments. With streamlined notification and approval processes, GitHub Actions further strengthens continuous integration and delivery practices.<\/span><\/p>\n<h1><b>Reference<\/b><\/h1>\n<ul>\n<li style=\"font-weight: 400;\"><a href=\"https:\/\/docs.github.com\/en\/actions\/using-workflows\/workflow-syntax-for-github-actions#run-name\"><span style=\"font-weight: 400;\">https:\/\/docs.github.com\/en\/actions\/using-workflows\/workflow-syntax-for-github-actions#run-name<\/span><\/a><\/li>\n<li style=\"font-weight: 400;\"><a href=\"https:\/\/docs.github.com\/en\/actions\/managing-workflow-runs\/reviewing-deployments#bypassing-environment-protection-rules\"><span style=\"font-weight: 400;\">https:\/\/docs.github.com\/en\/actions\/managing-workflow-runs\/reviewing-deployments#bypassing-environment-protection-rules<\/span><\/a><\/li>\n<li style=\"font-weight: 400;\"><a href=\"https:\/\/github.com\/marketplace\/actions\/google-chat-notification\"><span style=\"font-weight: 400;\">https:\/\/github.com\/marketplace\/actions\/google-chat-notification<\/span><\/a><\/li>\n<li style=\"font-weight: 400;\"><a href=\"https:\/\/docs.github.com\/en\/actions\/using-workflows\/events-that-trigger-workflows#issues\"><span style=\"font-weight: 400;\">https:\/\/docs.github.com\/en\/actions\/using-workflows\/events-that-trigger-workflows#issues<\/span><\/a><\/li>\n<\/ul>\n<div class=\"ap-custom-wrapper\"><\/div><!--ap-custom-wrapper-->","protected":false},"excerpt":{"rendered":"<p>Introduction GitHub Actions has become an integral part of modern software development, streamlining continuous integration and delivery processes. However, users have longed for a straightforward approval flow, similar to Azure Pipelines. It offers a simplified way to incorporate approval steps into CI\/CD pipelines. This update opens doors for users to enhance workflow control. Objective The [&hellip;]<\/p>\n","protected":false},"author":1744,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":1927},"categories":[1174,4308,2348],"tags":[1892,503],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/60877"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/1744"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=60877"}],"version-history":[{"count":4,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/60877\/revisions"}],"predecessor-version":[{"id":60901,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/60877\/revisions\/60901"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=60877"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=60877"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=60877"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}