GCP – Boost your Continuous Delivery pipeline with Generative AI
In the domain of software development, AI-driven assistance is emerging as a transformative force to enhance developer experience and productivity and ultimately optimize overall software delivery performance. Many organizations started to leverage AI-based assistants, such as Gemini Code Assist, in developer IDEs to support them in solving more difficult problems, understanding unfamiliar code, generating test cases, and many other common programming tasks. Based on the productivity gains experienced by the individual developers in their IDEs, many organizations are looking to expand their use of generative AI technologies to other aspects of their software development lifecycle including pull-requests, code reviews, or generating release notes.
In this article we want to explore how to use generative AI to enhance the quality and efficiency in software delivery. We also provide a practical example of how to leverage Gemini models in Vertex AI within a continuous delivery pipeline to support code reviews and generate release notes for pull requests.
- aside_block
- <ListValue: [StructValue([(‘title’, ‘$300 in free credit to try Google Cloud developer tools’), (‘body’, <wagtail.rich_text.RichText object at 0x3e47e61a1c70>), (‘btn_text’, ‘Start building for free’), (‘href’, ‘http://console.cloud.google.com/freetrial?redirectPath=/welcome’), (‘image’, None)])]>
Generative AI beyond the IDE
Whilst AI-powered coding assistance within an IDE offers a significant boost to a developer’s productivity, the benefits of this technology are not limited to the direct interaction between the developer and the codebase. By expanding the use of large language models to other aspects of the software delivery lifecycle, we open up a range of new opportunities to streamline time-consuming tasks. By integrating AI capabilities within automated CI/CD pipelines, we not only free up time for developers to focus on more strategic and creative aspects of their work but also have a chance to enhance the code quality overall and detect issues within the codebase early and before they make it to production environments.
The concept of using automated tooling within a CI/CD pipeline to proactively detect issues with code quality isn’t entirely new. We’ve used several forms of static code analysis for decades to identify potential errors and vulnerabilities and to enforce coding standards. However, the advances in generative AI present new opportunities that go beyond the capabilities of traditional code analysis. With their advanced language understanding and contextual awareness they can provide more nuanced commentary and provide more grounded recommendations on how to improve on a certain code base. In many cases these cools can help reduce cognitive load or labor intensive tasks that a human developer had to perform in the form of code reviews and help them focus on the bigger picture and overall impact on the codebase.
This doesn’t mean that the AI tools are in a position to replace the trusted tools and processes altogether. As illustrated in the practical example below these tools are most impactful when they are embedded within a combination of deterministic tools and human experts and each perform the tasks that they are best equipped to.
Ingredients for an AI-infused SDLC
To illustrate how generative AI can be used to enhance software delivery we’ll use the following products and tools:
Gemini models in Vertex AI
Gemini models are designed to process and understand vast amounts of information, enabling more accurate and nuanced responses to user prompts. With a focus on enhanced capabilities in areas like logical reasoning, coding, and creative collaboration, Gemini revolutionized the way we are able to collaborate with AI.
Gemini can be used directly or indirectly when it powers a packaged experience. For example Gemini Code Assist is a end user application that is built on top of the Gemini models and provides an assistant that helps in code generation, transformation and understanding as mentioned above.
Developers can also directly integrate Gemini models in their own application through Vertex AI, an end-to-end platform which lets them create, customize, manage, and scale AI applications.
In this example we will use Gemini in Vertex AI to build a custom extension of a CI/CD pipeline that uses Gemini’s language and text generation capabilities to provide meaningful assistance in a code review process.
Friendly CI-CD Helper
To abstract away the mechanics of interacting with the Gemini APIs in Vertex AI and centrally manage aspects like prompt design and how the context is fed to the model we build a small demo tool called friendly-cicd-helper. The tool can be used either as a standalone Python application or as a container that can run in a container-based CI/CD pipeline such as Cloud Build.
In its core the friendly-cicd-helper uses Gemini to analyze code changes (here in the form of a Git diff) and can generate the following outputs:
-
Summary of the changes to help speed up a MR/PR review
-
PR/MR comments for code changes to provide initial feedback to the author
-
Release Notes for changes for code changes
We use the friendly-cicd-helper tool as an example of how to leverage Gemini capabilities in a CI/CD pipeline. It is not an official product and most use cases will require you to build your own implementation based on your own needs and preferences.
Cloud Build
Cloud Build is a fully managed, serverless CI/CD (Continuous Integration/Continuous Delivery) platform provided by Google Cloud. It allows you to automate the process of building, testing, and deploying your applications across various environments like VMs, Kubernetes, serverless platforms, and Firebase.
You can define how the above tasks are linked together in your build through a build config specification, in which each task is defined as a build step.
Your build can be linked to a source-code repository so that your source code is cloned in your workspace as part of your build, and triggers can be configured to run the build automatically when a specific event, such as a new merge request, occurs.
Example Cloud Build Pipeline with Gemini
In our example the following Cloud Build pipeline is triggered when a developer opens a merge request in Gitlab (any other Cloud Build supported repository would work). The pipeline first fetches the latest version of the source branch of the pull request and executes the following steps in order:
1. The first step generates a Git diff to collect the code changes that are proposed as part of the merge request in a file. The file is persisted in the workspace mount that is shared between the steps such that it can later be used in the context for the LLM prompts.
- code_block
- <ListValue: [StructValue([(‘code’, “steps:rn – id: Generate Git Diffrn name: gcr.io/cloud-builders/gitrn entrypoint: ‘bash’rn args:rn – ‘-c’rn – |rn git fetch originrn git diff origin/main –output /workspace/diff.txtrn cat /workspace/diff.txt”), (‘language’, ”), (‘caption’, <wagtail.rich_text.RichText object at 0x3e47e03dba00>)])]>
2. Then we use Gemini to generate an automated code review of our merge request with the friendly-cicd-helper vertex-code-review --diff /workspace/diff.txt
command. The model response is then appended to the GitLab merge request thread as a comment.
- code_block
- <ListValue: [StructValue([(‘code’, ‘- id: Using Vertex AI to provide an automated MR Reviewrn name: ‘europe-west1-docker.pkg.dev/$PROJECT_ID/tools/friendly-cicd-helper’rn entrypoint: shrn args:rn – -crn – |rn export VERTEX_GCP_PROJECT=$PROJECT_IDrn echo “## Automated Merge Request Review Notes (generated by Vertex AI)” | tee mergerequest-review.mdrn echo “_Note that the following notes do not replace a thorough code review by an expert:_” | tee -a mergerequest-review.mdrnrn friendly-cicd-helper vertex-code-review –diff /workspace/diff.txt | tee -a mergerequest-review.mdrnrn cat mergerequest-review.md | friendly-cicd-helper gitlab-comment –project $_GITLAB_PROJECT –mergerequest $$(cat /workspace/gitlab_merge_request_iid)rn secretEnv: [‘GITLAB_TOKEN’]’), (‘language’, ”), (‘caption’, <wagtail.rich_text.RichText object at 0x3e47ca6f5880>)])]>
If you look at friendly-cicd-helper.py you’ll see that the vertex_code_review function calls the code_review function from the vertex_api.py module
- code_block
- <ListValue: [StructValue([(‘code’, ‘def vertex_code_review(diff):rn “””rn Review on a Git Diffrn “””rn import lib.vertex_api as vertexrn return vertex.code_review(diff)’), (‘language’, ”), (‘caption’, <wagtail.rich_text.RichText object at 0x3e47ca6f5160>)])]>
That function submit a prompt to Gemini to get a code review using the Git diff as context:
- code_block
- <ListValue: [StructValue([(‘code’, ‘def code_review(diff_path):rn “””rn Generate a code review based on a Git diff.rn “””rnrn response = model.generate_content(rn f”””rnYou are an experienced software engineer.rnYou only comment on code that you found in the merge request diff.rnProvide a code review with suggestions for the most important rnimprovements based on the following Git diff:rnrn${load_diff(diff_path)}rnrn “””,rn generation_config=generation_configrn )rn print(response.text.strip())rn return response.text)’), (‘language’, ”), (‘caption’, <wagtail.rich_text.RichText object at 0x3e47ca6f5100>)])]>
3. The same pattern can be repeated for generating other artifacts like suggested release notes that describe the contained changes in the MR and also append them to the same thread as a comment.
- code_block
- <ListValue: [StructValue([(‘code’, ‘- id: Using Vertex AI to provide automated Release Notesrn name: ‘europe-west1-docker.pkg.dev/$PROJECT_ID/tools/friendly-cicd-helper’rn entrypoint: shrn args:rn – -crn – |rn export VERTEX_GCP_PROJECT=$PROJECT_IDrn echo “## Automated Suggestions for Release Notes (generated by Vertex AI)” | tee mergerequest-release-notes.mdrnrn friendly-cicd-helper vertex-release-notes –diff /workspace/diff.txt | tee -a mergerequest-release-notes.mdrnrn cat mergerequest-release-notes.md | friendly-cicd-helper gitlab-comment –project $_GITLAB_PROJECT –mergerequest $$(cat /workspace/gitlab_merge_request_iid)rn secretEnv: [‘GITLAB_TOKEN’]’), (‘language’, ”), (‘caption’, <wagtail.rich_text.RichText object at 0x3e47ca6f5e80>)])]>
Here you can see the prompt submitted to Vertex from the vertex_api.py module
- code_block
- <ListValue: [StructValue([(‘code’, ‘def release_notes(diff_path):rn “””rn Generate release notes based on a Git diff in unified format.rn “””rnrn response = model.generate_content(rn f”””rnYou are an experienced tech writer.rnWrite short release notes in markdown bullet point format for the most important changes based on the following Git diff:rnrn${load_diff(diff_path)}rn “””,rn generation_config=generation_configrn )rn print(response.text.strip())rn return response.text’), (‘language’, ”), (‘caption’, <wagtail.rich_text.RichText object at 0x3e47ca6f5b80>)])]>
4. Lastly our pipeline builds a container image with the updated code and deploys the application to a QA environment using Cloud Deploy, where UAT can be executed.
- code_block
- <ListValue: [StructValue([(‘code’, ‘- id: Build the image with Skaffoldrn name: gcr.io/k8s-skaffold/skaffoldrn entrypoint: /bin/bashrn args:rn – -crn – |rn skaffold build –interactive=false –file-output=/workspace/artifacts.json –default-repo=$_REPOrn – id: Create a release in Cloud Deploy and rollout to stagingrn name: gcr.io/cloud-builders/gcloudrn entrypoint: ‘bash’rn args:rn – ‘-c’rn – |rn MERGE_REQUEST_IID=$$(cat /workspace/gitlab_merge_request_iid)rn gcloud deploy releases create ledgerwriter-${SHORT_SHA} –delivery-pipeline genai-sw-delivery \rn –region europe-west1 –annotations “commitId=${REVISION_ID},gitlab_mr=$$MERGE_REQUEST_IID” –build-artifacts /workspace/artifacts.json’), (‘language’, ”), (‘caption’, <wagtail.rich_text.RichText object at 0x3e47ca6f5790>)])]>
Seeing the pipeline in action
We will try our pipeline in the context of Bank of Anthos, a sample web app that simulates a bank’s payment processing network, allowing users to create artificial bank accounts and complete transactions.
For the purpose of this demo we’ve modified the ledger writer service that accepts and validates incoming transactions before writing them to the ledger. The repository fork is available here.
Starting from existing code we added the method below to the TransactionValidator class to obfuscate account number for logging purposes:
- code_block
- <ListValue: [StructValue([(‘code’, ‘public String obfuscateAccountNumber(String acctNum) {rn String obfuscated = “”;rn for (int i = 0; i < acctNum.length(); i++) {rn if (Character.isDigit(acctNum.charAt(i))) {rn obfuscated += “0”;rn } else {rn obfuscated += “x”;rn }rn }rn return obfuscated;rn }’), (‘language’, ”), (‘caption’, <wagtail.rich_text.RichText object at 0x3e47ca6f5df0>)])]>
In addition to that, we created a new TransactionValidatorTest class and added a test for the new method:
- code_block
- <ListValue: [StructValue([(‘code’, ‘package anthos.samples.bankofanthos.ledgerwriter;rnrnimport org.junit.jupiter.api.Test;rnimport static org.junit.jupiter.api.Assertions.assertEquals;rnrnclass TransactionValidatorTest {rnrn @Testrn void obfuscateAccountNumber_validAccountNumber_returnsObfuscated() {rn TransactionValidator validator = new TransactionValidator();rn String accountNumber = “12345678-90ab-cdef-1234-567890abcdef”;rn String obfuscated = validator.obfuscateAccountNumber(accountNumber);rn assertEquals(“00000000x00xxxxxxxx0000x000000xxxxxx”, obfuscated);rn }rn}’), (‘language’, ”), (‘caption’, <wagtail.rich_text.RichText object at 0x3e47ca6f55b0>)])]>
Once we open a MR in GitLab, after we insert the /gcbrun comment that we configured our Cloud Build trigger to require. This triggers the pipeline that we outlined above and appends the following comment with the AI-generated comments in the MR thread:
Then similarly the requested release note suggestions are also appended to the comment thread:
Summary
You saw an example of automating code reviews and release notes generation using Vertex AI and Gemini.
You can continue to try by yourself using the above example repository and friendly-cicd-helper, start from it and tune your prompts or implement your own script to submit a prompt to Gemini in your CD pipeline.
Read More for the details.