{"id":1752,"date":"2023-11-27T18:21:14","date_gmt":"2023-11-27T18:21:14","guid":{"rendered":"https:\/\/www.aviator.co\/blog\/?p=1752"},"modified":"2025-09-25T13:57:48","modified_gmt":"2025-09-25T13:57:48","slug":"ci-cd-google-app-engine","status":"publish","type":"post","link":"https:\/\/www.aviator.co\/blog\/ci-cd-google-app-engine\/","title":{"rendered":"Building a CI\/CD pipeline for a Google App Engine site using CircleCI"},"content":{"rendered":"\n<figure class=\"wp-block-image aligncenter size-full\"><img fetchpriority=\"high\" decoding=\"async\" width=\"993\" height=\"347\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2023\/11\/App-Engine.png\" alt=\"\" class=\"wp-image-1756\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2023\/11\/App-Engine.png 993w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2023\/11\/App-Engine-300x105.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2023\/11\/App-Engine-768x268.png 768w\" sizes=\"(max-width: 993px) 100vw, 993px\" \/><\/figure>\n\n\n\n<p>In this article, we will build a CI\/CD pipeline for a Google App Engine Site using CircleCI.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/docs.aviator.co\/mergequeue\" target=\"_blank\" rel=\" noreferrer noopener\"><img decoding=\"async\" width=\"1024\" height=\"264\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/04\/aviator-mergequeue-blog-documentation-cta-photo-min-1-1024x264.png\" alt=\"MergeQueue CTA\" class=\"wp-image-4921\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/04\/aviator-mergequeue-blog-documentation-cta-photo-min-1-1024x264.png 1024w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/04\/aviator-mergequeue-blog-documentation-cta-photo-min-1-300x77.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/04\/aviator-mergequeue-blog-documentation-cta-photo-min-1-768x198.png 768w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/04\/aviator-mergequeue-blog-documentation-cta-photo-min-1-1536x396.png 1536w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/04\/aviator-mergequeue-blog-documentation-cta-photo-min-1.png 1940w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisite<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Python installed on your system<\/li>\n\n\n\n<li>Google Cloud CLI installed<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">What we are building<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Documentation site and connect it to GCP (Google Cloud Platform)<\/li>\n\n\n\n<li>Using CircleCI for automation<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">What is CircleCI?<\/h2>\n\n\n\n<p><a href=\"https:\/\/circleci.com\/\">CircleCI<\/a> is a popular choice for software engineers, particularly DevOps engineers when working on <a href=\"https:\/\/www.aviator.co\/blog\/automating-integration-tests\/\">automation<\/a> and overall CI\/CD integrations. The CI\/CD platform helps software teams automate the process of building, testing, and deploying code. As a cloud-based platform, CircleCI allows you to seamlessly integrate with any version control system you choose, such as GitHub, Bitbucket, or GitLab. However, we will be working with GitHub on this article.<\/p>\n\n\n\n<p>One cool thing about CircleCI is that it lets developers define pipelines that automate the process of building, testing, and deploying code. Pipelines are composed of <a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/devops\/pipelines\/process\/phases?view=azure-devops&amp;tabs=yaml\">jobs<\/a>, which are individual steps in the CI\/CD process. Jobs can be configured to run on various platforms, including Linux, macOS, and Windows.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why Circle CI?<\/h2>\n\n\n\n<p>CircleCI is a friendly tool for teams of all sizes, ranging from small startups to large enterprises. No wonder the tool is usually \u201ctop of the ladder\u201d during CI\/CD integrations. It is a powerful tool that can help teams improve the quality and speed of their software development process.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li> <strong style=\"font-size: revert; background-color: transparent; color: var(--theme-text-color); font-family: var(--fontFamily); font-style: var(--fontStyle, inherit); letter-spacing: var(--letterSpacing); text-transform: var(--textTransform);\">Improved code quality:<\/strong><span style=\"font-size: revert; background-color: transparent; color: var(--theme-text-color); font-family: var(--fontFamily); font-style: var(--fontStyle, inherit); font-weight: var(--fontWeight); letter-spacing: var(--letterSpacing); text-transform: var(--textTransform);\"> CircleCI can help enhance code quality by automating the testing process.<\/span> <\/li>\n\n\n\n<li> <strong style=\"font-size: revert; background-color: transparent; color: var(--theme-text-color); font-family: var(--fontFamily); font-style: var(--fontStyle, inherit); letter-spacing: var(--letterSpacing); text-transform: var(--textTransform);\">Reduced deployment time:<\/strong><span style=\"font-size: revert; background-color: transparent; color: var(--theme-text-color); font-family: var(--fontFamily); font-style: var(--fontStyle, inherit); font-weight: var(--fontWeight); letter-spacing: var(--letterSpacing); text-transform: var(--textTransform);\"> CircleCI can help reduce the time it takes to deploy code by automating the process of building and deploying.<\/span> <\/li>\n\n\n\n<li> <strong style=\"font-size: revert; color: var(--theme-text-color); font-family: var(--fontFamily); font-style: var(--fontStyle, inherit); letter-spacing: var(--letterSpacing); text-transform: var(--textTransform);\">Increased confidence in releases:<\/strong><span style=\"font-size: revert; background-color: transparent; color: var(--theme-text-color); font-family: var(--fontFamily); font-style: var(--fontStyle, inherit); font-weight: var(--fontWeight); letter-spacing: var(--letterSpacing); text-transform: var(--textTransform);\"> CircleCI can help increase confidence in releases by ensuring that code is thoroughly tested before deployment.<\/span> <\/li>\n\n\n\n<li><strong>Improved team communication:<\/strong> CircleCI can help to improve team communication by providing a central location for monitoring the progress of builds and tests.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Relevant CircleCI features<\/h2>\n\n\n\n<p>Some of the core features of CircleCI include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li> <strong style=\"font-size: revert; background-color: transparent; color: var(--theme-text-color); font-family: var(--fontFamily); font-style: var(--fontStyle, inherit); letter-spacing: var(--letterSpacing); text-transform: var(--textTransform);\">Parallelism:<\/strong><span style=\"font-size: revert; background-color: transparent; color: var(--theme-text-color); font-family: var(--fontFamily); font-style: var(--fontStyle, inherit); font-weight: var(--fontWeight); letter-spacing: var(--letterSpacing); text-transform: var(--textTransform);\"> Jobs can be run in parallel to improve the speed of the CI\/CD process.<\/span> <\/li>\n\n\n\n<li> <strong style=\"font-size: revert; background-color: transparent; color: var(--theme-text-color); font-family: var(--fontFamily); font-style: var(--fontStyle, inherit); letter-spacing: var(--letterSpacing); text-transform: var(--textTransform);\">Caching:<\/strong><span style=\"font-size: revert; background-color: transparent; color: var(--theme-text-color); font-family: var(--fontFamily); font-style: var(--fontStyle, inherit); font-weight: var(--fontWeight); letter-spacing: var(--letterSpacing); text-transform: var(--textTransform);\"> CircleCI can cache build artifacts and test results to improve the speed of subsequent builds.<\/span> <\/li>\n\n\n\n<li><strong style=\"font-size: revert; background-color: transparent; color: var(--theme-text-color); font-family: var(--fontFamily); font-style: var(--fontStyle, inherit); letter-spacing: var(--letterSpacing); text-transform: var(--textTransform);\">Notifications:<\/strong><span style=\"font-size: revert; background-color: transparent; color: var(--theme-text-color); font-family: var(--fontFamily); font-style: var(--fontStyle, inherit); font-weight: var(--fontWeight); letter-spacing: var(--letterSpacing); text-transform: var(--textTransform);\"> CircleCI can notify team members when builds fail or pass.<\/span> <\/li>\n\n\n\n<li><strong>Monitoring:<\/strong> CircleCI provides a dashboard that allows teams to monitor the progress of their builds and tests.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Getting started<\/h2>\n\n\n\n<p>To get started, we first need to create a free GitHub repo (I assume you already know how to do that). The next step is to clone the empty repo. After this, let&#8217;s create a Python virtual environment by running the following command on your terminal:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pipenv shell<\/code><\/pre>\n\n\n\n<p>This is what it should look like after a successful installation:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/paper-attachments.dropboxusercontent.com\/s_762DC8729D6070F874B9A6C8613F9867EBE8E5E337A9107440BC3B666C3AB306_1700597968958_Screenshot+2023-11-21+211806.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>Next is to run the command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pip install sphinx<\/code><\/pre>\n\n\n\n<p><a href=\"https:\/\/www.sphinx-doc.org\/en\/master\/\">Sphinx<\/a> is a popular documentation generator written in Python that is widely used for creating high-quality documentation for Python projects. It is known for its ease of use, comprehensive features, and extensive support for various output formats.<\/p>\n\n\n\n<p>The next step is to get a Sphinx quick start. To do this, head over to the <a href=\"https:\/\/www.sphinx-doc.org\/en\/master\/usage\/quickstart.html\">get started<\/a> section of Sphinx\u2019s official site and run this command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sphinx-quickstart<\/code><\/pre>\n\n\n\n<p>Once you run the command, you get asked a series of questions, exactly the ones in the image below:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/paper-attachments.dropboxusercontent.com\/s_762DC8729D6070F874B9A6C8613F9867EBE8E5E337A9107440BC3B666C3AB306_1700599745595_Screenshot+2023-11-21+214746.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>Respond to these questions until the whole process is complete.<\/p>\n\n\n\n<p>This whole process creates a build and source directory. We are also going to install Sphinx make files by running this command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>make html<\/code><\/pre>\n\n\n\n<p>After running the command, your project should look like this in your code editor:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/paper-attachments.dropboxusercontent.com\/s_762DC8729D6070F874B9A6C8613F9867EBE8E5E337A9107440BC3B666C3AB306_1700600224195_Screenshot+2023-11-21+215541.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>Within the <code>build<\/code> directory, we have our website files, which look this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\ud83d\udce6build\n \u2523 \ud83d\udcc2doctrees\n \u2503 \u2523 \ud83d\udcdcenvironment.pickle\n \u2503 \u2517 \ud83d\udcdcindex.doctree\n \u2517 \ud83d\udcc2html\n \u2503 \u2523 \ud83d\udcc2_sources\n \u2503 \u2503 \u2517 \ud83d\udcdcindex.rst.txt\n \u2503 \u2523 \ud83d\udcc2_static\n \u2503 \u2503 \u2523 \ud83d\udcdcalabaster.css\n \u2503 \u2503 \u2523 \ud83d\udcdcbasic.css\n \u2503 \u2503 \u2523 \ud83d\udcdccustom.css\n \u2503 \u2503 \u2523 \ud83d\udcdcdoctools.js\n \u2503 \u2503 \u2523 \ud83d\udcdcdocumentation_options.js\n \u2503 \u2503 \u2523 \ud83d\udcdcfile.png\n \u2503 \u2503 \u2523 \ud83d\udcdclanguage_data.js\n \u2503 \u2503 \u2523 \ud83d\udcdcminus.png\n \u2503 \u2503 \u2523 \ud83d\udcdcplus.png\n \u2503 \u2503 \u2523 \ud83d\udcdcpygments.css\n \u2503 \u2503 \u2523 \ud83d\udcdcsearchtools.js\n \u2503 \u2503 \u2517 \ud83d\udcdcsphinx_highlight.js\n \u2503 \u2523 \ud83d\udcdc.buildinfo\n \u2503 \u2523 \ud83d\udcdcgenindex.html\n \u2503 \u2523 \ud83d\udcdcindex.html\n \u2503 \u2523 \ud83d\udcdcobjects.inv\n \u2503 \u2523 \ud83d\udcdcsearch.html\n \u2503 \u2517 \ud83d\udcdcsearchindex.js<\/code><\/pre>\n\n\n\n<p>When we run our project on <code>localhost:8000<\/code>, this is what it looks like on the browser:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/paper-attachments.dropboxusercontent.com\/s_762DC8729D6070F874B9A6C8613F9867EBE8E5E337A9107440BC3B666C3AB306_1700602624194_Screenshot+2023-11-21+223633.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>Congratulations, we have our documentation site live!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Creating a GCP project<\/h2>\n\n\n\n<p>In this section, we will create a brand new <a href=\"https:\/\/cloud.google.com\/gcp?utm_source=google&amp;utm_medium=cpc&amp;utm_campaign=emea-ng-all-en-bkws-all-all-trial-e-gcp-1011340&amp;utm_content=text-ad-none-any-DEV_c-CRE_501794636587-ADGP_Hybrid+%7C+BKWS+-+EXA+%7C+Txt+~+GCP+~+General%23v2-KWID_43700061569959221-aud-1641092902540:kwd-26415313501-userloc_1010294&amp;utm_term=KW_google+cloud+platform-NET_g-PLAC_&amp;&amp;gad_source=1&amp;gclid=CjwKCAiAx_GqBhBQEiwAlDNAZmnpZ1smTjDIwh0PFBZ6hT-NNobPRD5uYG-SDpNd84A6eiw8ZiDMeRoCDkAQAvD_BwE&amp;gclsrc=aw.ds&amp;hl=en\">GCP<\/a> project to figure out which settings need to be tweaked or updated from the base. The next thing is to create our app engine <code>app.yaml<\/code>. Google provides a <a href=\"https:\/\/cloud.google.com\/appengine\/docs\/legacy\/standard\/python\/getting-started\/hosting-a-static-website\">walkthrough<\/a> on how to host a static website using GAE. Here, we can copy this YAML file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>runtime: python27\napi_version: 1\nthreadsafe: true\n\nhandlers:\n- url: \/\n  static_files: www\/index.html\n  upload: www\/index.html\n\n- url: \/(.*)\n  static_files: www\/1\n  upload: www\/(.*)<\/code><\/pre>\n\n\n\n<p>Create an <code>app.yaml<\/code> file on your editor and paste this code. We then have to edit the YAML file to point it to the proper location where the website files live. To point your Gcloud command line install to this project, use this command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gcloud init --project=&lt;\"project ID\"&gt;<\/code><\/pre>\n\n\n\n<p>Here, you will prompted to log in to Google Cloud like this:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/paper-attachments.dropboxusercontent.com\/s_762DC8729D6070F874B9A6C8613F9867EBE8E5E337A9107440BC3B666C3AB306_1700650957553_Screenshot+2023-11-22+120153.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>Follow the link provided to get your authorization code.<\/p>\n\n\n\n<p>On the GCP dashboard, navigate to \u201cApp Engine\u201d and run the command shown there on your terminal:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>glcloud app deploy<\/code><\/pre>\n\n\n\n<p>You will get a prompt asking you to choose the location you would like your app to be deployed:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/paper-attachments.dropboxusercontent.com\/s_762DC8729D6070F874B9A6C8613F9867EBE8E5E337A9107440BC3B666C3AB306_1700654477879_Screenshot+2023-11-22+130059.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>Choose anyone! and your app will successfully deploy. It&#8217;s time to push our code to Github! Alternatively, you can clone my GitHub repo <a href=\"https:\/\/github.com\/ChisomUma\/Google-app-engine-CircleCI\">here<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Link Github repo to CircleCI<\/h2>\n\n\n\n<p>The first thing you need to do is create a <a href=\"https:\/\/circleci.com\/\">CircleCI<\/a> account and link your Github to it. The process is pretty straightforward. Our dashboard should look like this after creating and connecting our project to CircleCI.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/paper-attachments.dropboxusercontent.com\/s_762DC8729D6070F874B9A6C8613F9867EBE8E5E337A9107440BC3B666C3AB306_1700668023418_Screenshot+2023-11-22+164548.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>Next, in our code editor, we will create a folder named <code>.circleci<\/code> and a <code>config.yaml<\/code> file inside it which contains a code that works like this: first, it defines a workflow, then, the workflow will say; each time we push to the main branch, run this set of jobs. We will also define that job, which will contain the logic of where we build our documentation site and deploy it to the Google App engine.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>workflows:\n  version: 2\n  build_and_deploy:\n    jobs:\n      - build_and_deploy:\n        filters:\n          branches:\n            only:\n              - main<\/code><\/pre>\n\n\n\n<p>CircleCI will only run this workflow when we push to the main branch. Now, to define the job:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>jobs:\n  build_and_deploy:\n    docker:\n      - image: busybox\n    steps:\n      - run:\n          name: hello world\n          command: |\n            echo \"Hello world\"<\/code><\/pre>\n\n\n\n<p>You can check our formatting with CircleCI. To do this, first install CircleCI CLI and run this command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>circleci config validate<\/code><\/pre>\n\n\n\n<p>Response:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/paper-attachments.dropboxusercontent.com\/s_762DC8729D6070F874B9A6C8613F9867EBE8E5E337A9107440BC3B666C3AB306_1700671583544_Screenshot+2023-11-22+174555.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>In our CircleCI, you can see the tests, processes, and workflows whenever we push to the main branch on GitHub:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/paper-attachments.dropboxusercontent.com\/s_762DC8729D6070F874B9A6C8613F9867EBE8E5E337A9107440BC3B666C3AB306_1700672537776_Screenshot+2023-11-22+180013.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>Awesome! We have successfully created a CI\/CD pipeline. Now, whenever we make changes to our code base or documentation, we can just push to the main, and CircleCI will pick up that change (as demonstrated in the image above) and the job or workflow and make deployments a few minutes later.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>This article provided a step-by-step guide on building a CI\/CD pipeline for a Google App Engine site using CircleCI. We covered setting up a Python environment, using Sphinx for documentation, and integrating the project with Google Cloud Platform.<\/p>\n\n\n\n<p>The process demonstrated the benefits of automating deployments via CircleCI, including enhanced code quality, reduced deployment time, and improved team communication. This guide highlights the efficiency and effectiveness of CircleCI in streamlining development processes, making it an invaluable tool for modern software development teams.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/www.aviator.co\/\" target=\"_blank\" rel=\"noreferrer noopener\">Aviator<\/a>: Automate your cumbersome processes<\/h2>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/www.aviator.co\/\" target=\"_blank\" rel=\"noreferrer noopener\"><img decoding=\"async\" width=\"1024\" height=\"727\" src=\"https:\/\/blog.aviator.co\/wp-content\/uploads\/2022\/08\/blog-cta-1024x727.png\" alt=\"\" class=\"wp-image-57\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/08\/blog-cta-1024x727.png 1024w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/08\/blog-cta-300x213.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/08\/blog-cta-768x545.png 768w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/08\/blog-cta-1536x1090.png 1536w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/08\/blog-cta-2048x1454.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Aviator automates tedious developer workflows by managing git Pull Requests (PRs) and continuous integration test (CI) runs to help your team avoid broken builds, streamline cumbersome merge processes, manage cross-PR dependencies, and handle flaky tests while maintaining their security compliance.<\/p>\n\n\n\n<p>There are 4 key components to Aviator:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>MergeQueue<\/strong>&nbsp;\u2013 an automated queue that manages the merging workflow for your GitHub repository to help protect important branches from broken builds. The Aviator bot uses GitHub Labels to identify Pull Requests (PRs) that are ready to be merged, validates CI checks, processes semantic conflicts, and merges the PRs automatically.<\/li>\n\n\n\n<li><strong>ChangeSets<\/strong>&nbsp;\u2013 workflows to synchronize validating and merging multiple PRs within the same repository or multiple repositories. Useful when your team often sees groups of related PRs that need to be merged together, or otherwise treated as a single broader unit of change.<\/li>\n\n\n\n<li><strong>TestDeck<\/strong>&nbsp;\u2013 a tool to automatically detect, take action on, and process results from flaky tests in your CI infrastructure.<\/li>\n\n\n\n<li><strong>Stacked PRs CLI<\/strong>&nbsp;\u2013 a command line tool that helps developers manage cross-PR dependencies. This tool also automates syncing and merging of stacked PRs. Useful when your team wants to promote a culture of smaller, incremental PRs instead of large changes, or when your workflows involve keeping multiple, dependent PRs in sync.<\/li>\n<\/ol>\n\n\n\n<p><a href=\"https:\/\/www.aviator.co\/\" target=\"_blank\" rel=\"noopener\" title=\"\">Try it for free.<\/a><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article, we will build a CI\/CD pipeline for a Google App Engine Site using CircleCI.<\/p>\n","protected":false},"author":24,"featured_media":1760,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[58],"tags":[],"class_list":["post-1752","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ci-cd-deployment"],"blocksy_meta":{"styles_descriptor":{"styles":{"desktop":"","tablet":"","mobile":""},"google_fonts":[],"version":6}},"acf":[],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2023\/11\/app-engine.jpeg","post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/posts\/1752","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/users\/24"}],"replies":[{"embeddable":true,"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/comments?post=1752"}],"version-history":[{"count":11,"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/posts\/1752\/revisions"}],"predecessor-version":[{"id":4965,"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/posts\/1752\/revisions\/4965"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/media\/1760"}],"wp:attachment":[{"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/media?parent=1752"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/categories?post=1752"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/tags?post=1752"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}