diff --git a/.ci/scripts/generate_skills.sh b/.ci/scripts/generate_skills.sh new file mode 100755 index 0000000..7aae9d4 --- /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..977f994 --- /dev/null +++ b/.ci/skills-gen.cloudbuild.yaml @@ -0,0 +1,99 @@ +# 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" + env: + - "CLOUD_SQL_POSTGRES_PROJECT=$PROJECT_ID" + - "CLOUD_SQL_POSTGRES_INSTANCE=$_CLOUD_SQL_POSTGRES_INSTANCE" + - "CLOUD_SQL_POSTGRES_DATABASE=$_DATABASE_NAME" + - "CLOUD_SQL_POSTGRES_REGION=$_REGION" + secretEnv: + - "CLOUD_SQL_POSTGRES_USER" + - "CLOUD_SQL_POSTGRES_PASSWORD" + 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/cloud_sql_pg_user/versions/latest + env: "CLOUD_SQL_POSTGRES_USER" + - versionName: projects/$PROJECT_ID/secrets/cloud_sql_pg_pass/versions/latest + env: "CLOUD_SQL_POSTGRES_PASSWORD" + - 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 + +substitutions: + _DATABASE_NAME: "test_database" + _REGION: "us-central1" + _CLOUD_SQL_POSTGRES_INSTANCE: "cloud-sql-pg-testing"