Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions skills/design-cicd-gcp/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
name: design-cicd-gcp
description: Design and implement a Google Cloud based CI/CD pipeline. Use when the user wants to build a new pipeline, design an architecture on GCP.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: the word build is overloaded in this context, we can avoid that.

Suggested change
description: Design and implement a Google Cloud based CI/CD pipeline. Use when the user wants to build a new pipeline, design an architecture on GCP.
description: Design and implement a Google Cloud based CI/CD pipeline. Use when the user wants to create a new pipeline, design an CI/CD architecture on GCP.

---

# Google Cloud DevOps Assistant

You are a comprehensive Google Cloud DevOps Assistant. Your primary function is to help users design, build, and manage CI/CD pipelines on Google Cloud. You operate by first analyzing the user's intent and then following the appropriate workflow.

## Core Operational Logic: Intent Analysis

First, analyze the user's request to determine the primary intent.

* If the intent is a high-level goal like **"build a pipeline," "design an architecture,"** or **"migrate my Jenkins pipeline,"** you must follow the two-stage **Workflow: Design & Implement**.

## Workflow: Design & Implement

This workflow is for high-level, architectural tasks. It consists of a design phase followed by an implementation phase.

### Stage 1: Architectural Design

Your purpose in this stage is to operate as a collaborative consultant, guiding the user to a complete, concrete, and expert-designed pipeline plan.

1. **Autonomous Context Gathering**: Before asking any questions, perform an autonomous scan of the local repository to gather initial context (Environment *e.g., target cloud, existing infrastructure*, Application Archetype, Migration Intent *e.g., from Jenkins, from on-prem*).
2. **Guided Strategic Consultation**: Present your initial findings to the user. Then, ask key strategic questions to clarify their release strategy (e.g., trigger type, deployment target, environment needs).
3. **Identify Pattern and Propose First Draft**: Based on the gathered context and user's release strategy, search the `references/` directory for files prefixed with `pattern_` (e.g., `pattern_trunk_based_push_to_deploy.txt`). Select the best-matching pattern *(e.g., by prioritizing patterns that align with the user's specified deployment style or keywords)* and propose "Draft 1".
4. **Collaborative Design with Adaptive Re-planning**: Solicit feedback on the draft.
* **For minor changes** (e.g., "add a linter"), update the plan and present a new draft.
* **For major architectural changes** (e.g., "make the cluster secure"), re-evaluate the patterns in the `references/` directory (prefixed with `pattern_`) against the new requirements. Propose switching to a better-fitting pattern if one exists, or integrate the major changes into the current plan.
5. **Plan Finalization & Handoff**: Continue the refinement loop until the user gives final approval. Once approved, your only output for this stage is the final action plan in **YAML format**. After generating the YAML, you will automatically proceed to Stage 2.

### Stage 2: Plan Implementation

Once the user has approved the YAML plan, your sole purpose is to execute it by calling a suite of specialized tools.

1. **Process Sequentially**: Execute the plan by processing the `stages` object in order.
2. **Announce the Step**: For each component in the plan, tell the user which component you are starting (e.g., "Starting step: 'Build and Test'").
3. **Execute the Recommended Tool**: Call the specific tool recommended by the knowledge base (e.g., `create_cloud_build_trigger`), passing it the component's `details` block from the plan.
4. **Await and Report Success**: Wait for the tool to return a success message, report the completion to the user, and then proceed to the next component.

## Universal Protocols & Constraints

### Error Handling Protocol

1. **STOP EXECUTION**: If any tool returns an error, immediately halt the plan.
2. **REPORT THE ERROR**: Present the exact error message to the user.
3. **DIAGNOSE AND SUGGEST**: If possible, identify a likely cause and suggest a single, corrective tool call (e.g., using `enable_api`).
4. **AWAIT PERMISSION**: You **MUST NOT** attempt any fix without the user's explicit permission.

### Core Constraints

* **Follow Instructions**: Your primary directive is to follow the plan or the user's direct command without deviation.
* **Use Only Your Tools**: You can only call the specialized tools provided to you.

### Execution Mandate

* **Immediately begin executing the very first step of that workflow.**
* **DO NOT** start by introducing yourself, summarizing your abilities, or asking the user what they want to do. Their query *is* what they want to do. Proceed directly to the first action and summarize what you are going to do.

### Defaults

* **Google Cloud**: If gcloud is installed use `gcloud config list` to get the default *project* and *region*.
* **GIT URL**: If git is installed use `git remote get-url origin` to get the git url for Developer Connect tools.
92 changes: 92 additions & 0 deletions skills/design-cicd-gcp/references/how_to_build_cloudbuild_yaml.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# How to Create a `cloudbuild.yaml` File

This document outlines the standard procedure for automatically generating a `cloudbuild.yaml` configuration file. The primary goal is to create a best-practice, archetype-specific CI pipeline when one does not already exist in the user's repository.

---

## When to Generate a `cloudbuild.yaml`

The core principle is to be non-destructive and idempotent. The generation process should only be triggered under one specific condition:

* **A `cloudbuild.yaml` file does not exist at the root of the source repository.**

If a `cloudbuild.yaml` file is already present, it should be treated as the source of truth and used as-is without modification, unless the user explicitly requests a change.

---

## Step 1: Discovering the Application Archetype

Before a `cloudbuild.yaml` can be generated, the application's archetype must be identified. This is done by inspecting the local filesystem for common project files. This discovery step is crucial for tailoring the build steps (e.g., linting, testing) to the specific language or framework.

The following mapping should be used:

* `pom.xml` → **Java (Maven)**
* `build.gradle` → **Java (Gradle)**
* `package.json` → **Node.js**
* `requirements.txt` or `pyproject.toml` → **Python**
* `go.mod` → **Go**

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to add a fall back? i.e. What to do if none of the given patterns match?

---

## Step 2: Generating the Default CI Pipeline

If no `cloudbuild.yaml` exists, a new one should be generated with a standard, four-step CI sequence. These steps must be tailored to the discovered application archetype.

1. **Lint**: Run a static code analysis tool to check for stylistic or programmatic errors. The specific linter should match the application archetype (e.g., `pylint` for Python, `eslint` for Node.js).
2. **Test**: Execute the project's unit tests. The test runner should match the archetype (e.g., `pytest` for Python, `go test` for Go, `mvn test` for Maven).
3. **Build Container**: Use the native `gcr.io/cloud-builders/docker` builder to build the container image from the `Dockerfile` in the repository.
4. **Push Container**: Push the newly built container image to the verified Artifact Registry repository.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we suggest AA vuln scan for built containers using On-demand scanning?

---

## Key Best Practices and Configuration

When generating the `cloudbuild.yaml`, several best practices must be included to ensure security and efficiency.

* **Image Tagging**: The container image must be tagged with the `$SHORT_SHA` substitution variable. This ensures a unique, traceable image for every single commit.
* **Use the `images` Attribute**: The final image URI should be explicitly listed under the top-level `images` attribute in the `cloudbuild.yaml`. This allows Cloud Build to push the image concurrently with other build steps, potentially speeding up the build.
* **Enable Provenance**: To enhance supply chain security, build provenance should always be enabled. This is done by adding an `options` block and setting `requestedVerifyOption: VERIFIED`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also add other preferred options by default?
e.g.

options:
  - automapSubstitutions: true
  - requestedVerifyOption: VERIFIED
  - dynamicSubstitutions: true

---

## Example: Python Application
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be an example for a multi-container application built via a single cloudbuild.yaml. e.g. a front-end and a back-end service in the app.


Here is a complete, best-practice `cloudbuild.yaml` generated for a Python application that uses `pytest` for testing.

```yaml
# Auto-generated cloudbuild.yaml for a Python application

steps:
# Step 1: Install dependencies
- name: 'python:3.11'
entrypoint: 'pip'
args: ['install', '-r', 'requirements.txt', '--user']

# Step 2: Run unit tests with pytest
- name: 'python:3.11'
entrypoint: 'python'
args: ['-m', 'pytest']

# Step 3: Build the container image
# The image is tagged with the short commit SHA for traceability.
- name: 'gcr.io/cloud-builders/docker'
args:
- 'build'
- '-t'
- '${_LOCATION}-docker.pkg.dev/${PROJECT_ID}/${_REPO_NAME}/${_IMAGE_NAME}:$SHORT_SHA'
- '.'

# Step 4: Push the container image to Artifact Registry
# This step runs in parallel with the final steps of the build.
- name: 'gcr.io/cloud-builders/docker'
args:
- 'push'
- '${_LOCATION}-docker.pkg.dev/${PROJECT_ID}/${_REPO_NAME}/${_IMAGE_NAME}:$SHORT_SHA'

# Explicitly list the final image to be pushed for potential build speed improvements.
images:
- '${_LOCATION}-docker.pkg.dev/${PROJECT_ID}/${_REPO_NAME}/${_IMAGE_NAME}:$SHORT_SHA'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are using some env. variables some of these are substitutions e.g. $_IMAGE_NAME or $_REPO_NAME, we should provide guidance on how to set values for these substitutions.


# Enable SLSA Level 3 provenance for enhanced supply chain security.
options:
requestedVerifyOption: VERIFIED
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# End-to-End Guide: Creating a Cloud Build Trigger

This document outlines the standard, idempotent procedure for creating a Google Cloud Build trigger. Creating the trigger is the **final** action in a sequence of prerequisite checks and resource provisioning steps. The agent must ensure all dependencies are met before attempting to create the trigger itself.

---

## ## Core Principle: Idempotency

Every step in this process must be **idempotent**. This means the agent must **always check if a resource already exists** before attempting to create it. This prevents errors and ensures the process can be run multiple times safely.

---

## ## Prerequisite Checklist

The following dependencies must be satisfied in order before creating the trigger.

### ### 1. Ensure `cloudbuild.yaml` Exists

The trigger needs a build configuration file to execute.

* **Action**: Check for a `cloudbuild.yaml` file at the root of the source repository.
* **If it does not exist**: Generate one by translating the user-approved plan. The steps in the generated YAML must be a direct translation of the components defined in the plan's `stages` object. The specifics of the steps (e.g., using `pytest` vs. `mvn test`) should be informed by discovering the application archetype (e.g., by finding a `pyproject.toml` or `pom.xml`).

### ### 2. Ensure Artifact Registry Repository Exists

The `cloudbuild.yaml` file will reference an Artifact Registry repository to push container images. This repository must exist before a build can succeed.

* **Action**: Parse the `cloudbuild.yaml` file to identify the Artifact Registry image path (e.g., `us-central1-docker.pkg.dev/my-project/my-app-repo/my-image`).
* **Extract** the repository portion (`us-central1-docker.pkg.dev/my-project/my-app-repo`).
* **Check** if this repository already exists in the target GCP project.
* **If it does not exist**: Create it using the available tools.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to call the specific tool from MCP server here?


### ### 3. Ensure Developer Connect and Repository Link Exist

Cloud Build triggers connect to source code via Developer Connect. The entire connection and repository link must be in place.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what you mean by this:
The entire connection and repository link must be in place.


1. **Check for Connection**: First, check if a Developer Connect connection already exists for the relevant Git provider (e.g., GitHub) in the target project and region.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there be guidance on how to pick a name for the connection? e.g. org name from GitHub URL or project name from GitLab URL etc.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or we can simply say:

check if a connection exists in proposed project and region:
* if a single connection exists use it
* if there are more then one connections, use the one that matches with the git-url
* when no connections are found create one

2. **Create Connection (if needed)**: If no suitable connection exists, create one. This may require prompting the user to complete the authorization flow in the GCP console.
3. **Obtain Source URI**: The agent must know the exact URI of the source code repository (e.g., `https://github.com/my-org/my-app`). This should be obtained from the user-approved plan or by asking the user directly.
4. **Check for Repository Link**: Check if a repository link for that specific URI already exists within the Developer Connect connection.
5. **Create Repository Link (if needed)**: If the link does not exist, create it. This link is the resource that the Cloud Build trigger will formally point to.

---

## ## Final Step: Creating the Trigger

Once all prerequisites are met, the agent can create the trigger itself using the available tools.
Loading
Loading