From 6ac94733346fad638747ed1c3369a0c35798e62b Mon Sep 17 00:00:00 2001 From: Twisha Bansal Date: Fri, 19 Jun 2026 12:11:44 +0530 Subject: [PATCH 1/4] ci: auto generate skills on toolbox version update Adds a Cloud Build pipeline and script to regenerate skills when toolbox_version.txt changes. Skill generation reads only the upstream prebuilt config, so no database connection is required. --- .ci/scripts/generate_skills.sh | 122 +++++++++++++++++++++++++++++++++ .ci/skills-gen.cloudbuild.yaml | 82 ++++++++++++++++++++++ 2 files changed, 204 insertions(+) create mode 100755 .ci/scripts/generate_skills.sh create mode 100644 .ci/skills-gen.cloudbuild.yaml diff --git a/.ci/scripts/generate_skills.sh b/.ci/scripts/generate_skills.sh new file mode 100755 index 0000000..8c86268 --- /dev/null +++ b/.ci/scripts/generate_skills.sh @@ -0,0 +1,122 @@ +#!/bin/bash +set -e + +# Ensure VERSION is passed from the environment +if [ -z "$VERSION" ]; then + echo "Error: VERSION environment variable is not set." + exit 1 +fi + +# SKILL CONFIGURATION +# Format: "toolset" "description" +# The skill name is automatically generated as "cloud-sql-postgres-" +SKILLS=( + "admin" + "Use these skills when you need to provision new Cloud SQL instances, create databases and users, clone existing environments, and monitor the progress of long-running operations." + + "lifecycle" + "Use these skills when you need to manage the lifecycle of your instances, including performing backups and restores, checking major version upgrade compatibility, and monitoring overall instance status." + + "data" + "Use these skills when you need to explore the database structure, discover schema objects like views or stored procedures, and execute custom SQL queries to interact with your data." + + "health" + "Use these skills when you need to audit database health, identify storage bloat, find invalid indexes, analyze table statistics, and manage maintenance configurations like autovacuum." + + "monitor" + "Use these skills when you need to troubleshoot performance bottlenecks, analyze query execution plans, identify resource-heavy processes, and monitor system-level PromQL metrics." + + "view-config" + "Use these skills when you need to discover and manage PostgreSQL extensions or fine-tune engine-level settings such as memory allocation and server configuration parameters." + + "replication" + "Use these skills when you need to monitor replication health, manage sync states between nodes, and audit database roles and security settings to ensure environment integrity." + + "vectorassist" + "Use these skills to set up and optimize production-ready vector workloads by simply expressing your intent and performance requirements" +) + +echo "VALIDATING TOOLSETS BEFORE GENERATION" + +# Dynamically build the SUPPORTED_TOOLSETS array from the SKILLS array. +# We use 'set --' to process the array in chunks without index arithmetic. +SUPPORTED_TOOLSETS=() +set -- "${SKILLS[@]}" +while [ $# -gt 0 ]; do + SUPPORTED_TOOLSETS+=("$1") + shift 2 +done + +echo "Currently Supported Toolsets: ${SUPPORTED_TOOLSETS[*]}" + +# Fetch the upstream source of truth YAML for this specific version +RAW_URL="https://raw.githubusercontent.com/googleapis/mcp-toolbox/v${VERSION}/internal/prebuiltconfigs/tools/cloud-sql-postgres.yaml" +echo "Fetching upstream config from: $RAW_URL" +UPSTREAM_YAML=$(curl -sL --fail "$RAW_URL" || { echo "Error: Could not fetch upstream YAML for v$VERSION"; exit 1; }) + +# Extract the list of toolsets +UPSTREAM_TOOLSETS=$(echo "$UPSTREAM_YAML" | awk '/^toolsets:/{flag=1; next} flag && /^ [a-zA-Z0-9_-]+:/{print $1}' | sed 's/://g') + +# Compare upstream toolsets against our supported list +MISSING_TOOLSETS=false + +for upstream_tool in $UPSTREAM_TOOLSETS; do + if [ -z "$upstream_tool" ] || [ "$upstream_tool" == "-" ]; then continue; fi + + if [[ ! " ${SUPPORTED_TOOLSETS[*]} " =~ " ${upstream_tool} " ]]; then + echo "ERROR: Upstream configuration contains a new toolset: '$upstream_tool'" + MISSING_TOOLSETS=true + fi +done + +if [ "$MISSING_TOOLSETS" = true ]; then + echo "PIPELINE FAILED: Missing Toolset Generators" + echo "The source of truth file has toolsets that your script does not support." + echo "Please update the SKILLS array in generate_skills.sh to include generators" + echo "for the missing toolsets above, then commit your changes to unblock this PR." + exit 1 +fi + +echo "Validation passed. All upstream toolsets are supported." + +echo "BEGINNING SKILL GENERATION" + +LICENSE_HEADER="// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the \"License\"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an \"AS IS\" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License." + +ADDITIONAL_NOTES="Note: The scripts automatically load the environment variables from various .env files. Do not ask the user to set vars unless skill executions fails due to env var absence." + +# Base Command Function +generate_skill() { + local TOOLSET="$1" + local SKILL_DESC="$2" + local SKILL_NAME="cloud-sql-postgres-$TOOLSET" + + echo "Generating skill: $SKILL_NAME..." + + npx "@toolbox-sdk/server@${VERSION}" --prebuilt cloud-sql-postgres skills-generate \ + --name "$SKILL_NAME" \ + --description "$SKILL_DESC" \ + --toolset="$TOOLSET" \ + --license-header "$LICENSE_HEADER" \ + --additional-notes="$ADDITIONAL_NOTES" +} + +set -- "${SKILLS[@]}" +while [ $# -gt 0 ]; do + generate_skill "$1" "$2" + shift 2 +done + +echo "All skills generated successfully!" diff --git a/.ci/skills-gen.cloudbuild.yaml b/.ci/skills-gen.cloudbuild.yaml new file mode 100644 index 0000000..441d5db --- /dev/null +++ b/.ci/skills-gen.cloudbuild.yaml @@ -0,0 +1,82 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +steps: + - id: "setup-ssh" + name: "gcr.io/cloud-builders/git" + entrypoint: "bash" + secretEnv: + - "GITHUB_TOKEN" + volumes: + - name: "ssh-keys" + path: /root/.ssh + args: + - -c + - | + # Write the secret key to the shared volume and secure it + printf "%s\n" "$$GITHUB_TOKEN" > /root/.ssh/id_ed25519 + chmod 400 /root/.ssh/id_ed25519 + + # Scan GitHub's server to prevent interactive prompts + ssh-keyscan -t rsa github.com > /root/.ssh/known_hosts + + - id: "generate-skills" + name: "node:20" + waitFor: ["setup-ssh"] + entrypoint: "bash" + args: + - -c + - | + export VERSION=$$(cat toolbox_version.txt | tr -d '\n') + echo "Detected toolbox version: $$VERSION" + + chmod +x ./.ci/scripts/generate_skills.sh + ./.ci/scripts/generate_skills.sh + + - id: "commit-and-push" + name: "gcr.io/cloud-builders/git" + waitFor: ["generate-skills"] + entrypoint: "bash" + volumes: + - name: "ssh-keys" + path: /root/.ssh + args: + - -c + - | + git config --global --add safe.directory '*' + + if [ -z "$$(git status --porcelain)" ]; then + echo "No new files generated. Exiting without committing." + exit 0 + fi + + echo "Changes detected. Preparing to commit..." + git config user.name "release-please[bot]" + git config user.email "55107282+release-please[bot]@users.noreply.github.com" + + git remote set-url origin git@github.com:gemini-cli-extensions/cloud-sql-postgresql.git + git add . + git commit -m "chore: auto-generate skills based on toolbox_version.txt update" + git push origin HEAD:$_HEAD_BRANCH + +availableSecrets: + secretManager: + - versionName: projects/$PROJECT_ID/secrets/github_token_cloud_sql_postgresql/versions/latest + env: "GITHUB_TOKEN" + +options: + logging: CLOUD_LOGGING_ONLY + automapSubstitutions: true + substitutionOption: "ALLOW_LOOSE" + dynamicSubstitutions: true From 94f08480c1bf88edb703b4d4b69e9596b25bded0 Mon Sep 17 00:00:00 2001 From: Twisha Bansal Date: Fri, 19 Jun 2026 12:18:08 +0530 Subject: [PATCH 2/4] ci: regenerate skills via GitHub Actions instead of Cloud Build Replaces the Cloud Build pipeline (which needed SSH keys and Secret Manager tokens) with a GitHub Actions workflow. On PRs that bump toolbox_version.txt, it regenerates skills and commits them back to the PR branch using the built-in GITHUB_TOKEN. Moves the generator script under .github/scripts/. --- .ci/skills-gen.cloudbuild.yaml | 82 --------------------- {.ci => .github}/scripts/generate_skills.sh | 0 .github/workflows/skills-generate.yml | 56 ++++++++++++++ 3 files changed, 56 insertions(+), 82 deletions(-) delete mode 100644 .ci/skills-gen.cloudbuild.yaml rename {.ci => .github}/scripts/generate_skills.sh (100%) create mode 100644 .github/workflows/skills-generate.yml diff --git a/.ci/skills-gen.cloudbuild.yaml b/.ci/skills-gen.cloudbuild.yaml deleted file mode 100644 index 441d5db..0000000 --- a/.ci/skills-gen.cloudbuild.yaml +++ /dev/null @@ -1,82 +0,0 @@ -# Copyright 2026 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -steps: - - id: "setup-ssh" - name: "gcr.io/cloud-builders/git" - entrypoint: "bash" - secretEnv: - - "GITHUB_TOKEN" - volumes: - - name: "ssh-keys" - path: /root/.ssh - args: - - -c - - | - # Write the secret key to the shared volume and secure it - printf "%s\n" "$$GITHUB_TOKEN" > /root/.ssh/id_ed25519 - chmod 400 /root/.ssh/id_ed25519 - - # Scan GitHub's server to prevent interactive prompts - ssh-keyscan -t rsa github.com > /root/.ssh/known_hosts - - - id: "generate-skills" - name: "node:20" - waitFor: ["setup-ssh"] - entrypoint: "bash" - args: - - -c - - | - export VERSION=$$(cat toolbox_version.txt | tr -d '\n') - echo "Detected toolbox version: $$VERSION" - - chmod +x ./.ci/scripts/generate_skills.sh - ./.ci/scripts/generate_skills.sh - - - id: "commit-and-push" - name: "gcr.io/cloud-builders/git" - waitFor: ["generate-skills"] - entrypoint: "bash" - volumes: - - name: "ssh-keys" - path: /root/.ssh - args: - - -c - - | - git config --global --add safe.directory '*' - - if [ -z "$$(git status --porcelain)" ]; then - echo "No new files generated. Exiting without committing." - exit 0 - fi - - echo "Changes detected. Preparing to commit..." - git config user.name "release-please[bot]" - git config user.email "55107282+release-please[bot]@users.noreply.github.com" - - git remote set-url origin git@github.com:gemini-cli-extensions/cloud-sql-postgresql.git - git add . - git commit -m "chore: auto-generate skills based on toolbox_version.txt update" - git push origin HEAD:$_HEAD_BRANCH - -availableSecrets: - secretManager: - - versionName: projects/$PROJECT_ID/secrets/github_token_cloud_sql_postgresql/versions/latest - env: "GITHUB_TOKEN" - -options: - logging: CLOUD_LOGGING_ONLY - automapSubstitutions: true - substitutionOption: "ALLOW_LOOSE" - dynamicSubstitutions: true diff --git a/.ci/scripts/generate_skills.sh b/.github/scripts/generate_skills.sh similarity index 100% rename from .ci/scripts/generate_skills.sh rename to .github/scripts/generate_skills.sh diff --git a/.github/workflows/skills-generate.yml b/.github/workflows/skills-generate.yml new file mode 100644 index 0000000..11d00f2 --- /dev/null +++ b/.github/workflows/skills-generate.yml @@ -0,0 +1,56 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Generate Skills + +on: + pull_request: + paths: + - "toolbox_version.txt" + +jobs: + generate-skills: + # Only run for same-repo PRs (e.g. renovate's toolbox bump), where the + # built-in GITHUB_TOKEN can push back to the PR branch. + if: github.event.pull_request.head.repo.full_name == github.repository + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Check out PR branch + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + ref: ${{ github.head_ref }} + + - name: Generate skills + run: | + VERSION="$(tr -d '\n' < toolbox_version.txt)" + echo "Detected toolbox version: $VERSION" + export VERSION + chmod +x ./.github/scripts/generate_skills.sh + ./.github/scripts/generate_skills.sh + + - name: Commit and push regenerated skills + run: | + if [ -z "$(git status --porcelain)" ]; then + echo "No skill changes generated. Nothing to commit." + exit 0 + fi + + echo "Changes detected. Committing regenerated skills..." + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add . + git commit -m "chore: auto-generate skills for toolbox v$(tr -d '\n' < toolbox_version.txt)" + git push From fcfacc491e5b45f6fec4d402baa77f48629725c8 Mon Sep 17 00:00:00 2001 From: Twisha Bansal Date: Fri, 19 Jun 2026 12:29:25 +0530 Subject: [PATCH 3/4] fix: parse new kind: toolset config format for validation The upstream prebuilt config moved from a top-level toolsets: block to per-toolset YAML documents (kind: toolset / name:) in toolbox v1.2.0. The old awk parser found zero toolsets on v1.2.0+, so the validation passed vacuously. Parse the new format so unsupported upstream toolsets are detected. --- .github/scripts/generate_skills.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/scripts/generate_skills.sh b/.github/scripts/generate_skills.sh index 8c86268..8b17916 100755 --- a/.github/scripts/generate_skills.sh +++ b/.github/scripts/generate_skills.sh @@ -54,8 +54,10 @@ RAW_URL="https://raw.githubusercontent.com/googleapis/mcp-toolbox/v${VERSION}/in echo "Fetching upstream config from: $RAW_URL" UPSTREAM_YAML=$(curl -sL --fail "$RAW_URL" || { echo "Error: Could not fetch upstream YAML for v$VERSION"; exit 1; }) -# Extract the list of toolsets -UPSTREAM_TOOLSETS=$(echo "$UPSTREAM_YAML" | awk '/^toolsets:/{flag=1; next} flag && /^ [a-zA-Z0-9_-]+:/{print $1}' | sed 's/://g') +# Extract the list of toolsets. Each toolset is its own YAML document: +# kind: toolset +# name: +UPSTREAM_TOOLSETS=$(echo "$UPSTREAM_YAML" | awk '$1=="kind:" && $2=="toolset"{f=1; next} f && $1=="name:"{print $2; f=0}') # Compare upstream toolsets against our supported list MISSING_TOOLSETS=false From 9c9d47eff58c1a747de0f76e5f92bd63a2329943 Mon Sep 17 00:00:00 2001 From: Twisha Bansal <58483338+twishabansal@users.noreply.github.com> Date: Fri, 19 Jun 2026 12:51:52 +0530 Subject: [PATCH 4/4] fix cla issue --- .github/workflows/skills-generate.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/skills-generate.yml b/.github/workflows/skills-generate.yml index 11d00f2..e31c015 100644 --- a/.github/workflows/skills-generate.yml +++ b/.github/workflows/skills-generate.yml @@ -49,8 +49,9 @@ jobs: fi echo "Changes detected. Committing regenerated skills..." - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config user.name "release-please[bot]" + git config user.email "55107282+release-please[bot]@users.noreply.github.com" + git add . git commit -m "chore: auto-generate skills for toolbox v$(tr -d '\n' < toolbox_version.txt)" git push