Skip to content
Open
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
59 changes: 59 additions & 0 deletions .claude/skills/update-changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
I need you to analyze the code changes in this SDK repository and update the CHANGELOG.md file.

Changes were made by syncing the OpenAPI spec from managed-service.

## Environment Variables

The following environment variables are set. Read each one individually
using `printenv <VAR>` (one variable per command):

- MANAGED_SERVICE_PR_URL — The managed-service PR URL that triggered this sync
- MANAGED_SERVICE_SHA — (optional) The managed-service commit SHA if the PR was merged

## Instructions

Please follow these steps:

1. Use git diff to see all changes in the working tree
2. Read the current CHANGELOG.md file to understand its existing structure
3. Update CHANGELOG.md following Keep a Changelog conventions (https://keepachangelog.com/):
- Add all new entries under the [Unreleased] section
- For each change, choose the appropriate subsection:
- Added: for new features
- Changed: for changes in existing functionality
- Deprecated: for soon-to-be removed features
- Removed: for now removed features
- Fixed: for any bug fixes
- Security: in case of vulnerabilities
- If a subsection header (e.g., ### Added) does not exist under [Unreleased], create it
- If the subsection header already exists, add new entries at the top of that subsection
- Maintain the subsection order: Added, Changed, Deprecated, Removed, Fixed, Security
4. For each change, determine if it's a breaking change for SDK consumers
5. If a change is breaking, prefix that specific entry with "Breaking Change: "
6. Write entries as bullet points using past tense (e.g., "Added X field", not "Add X field")

IMPORTANT: Only modify CHANGELOG.md. Do not modify any other files including generated code, spec files, or configuration files.

After updating CHANGELOG.md, you MUST output structured metadata in the following format.
This is critical - end your response with these exact markers:

---COMMIT_TITLE---
<one line commit title - keep it under 72 characters>
---COMMIT_BODY---
<multi-line commit body explaining the changes - wrap lines at 72 characters>

Managed-service-pr-url: $MANAGED_SERVICE_PR_URL
---PR_TITLE---
<one line PR title - keep it under 72 characters>
---PR_DESCRIPTION---
<multi-line PR description with summary and details>

IMPORTANT GUIDANCE FOR COMMIT AND PR TITLES:
- Describe the actual SDK/API changes from a user perspective
- NEVER write titles like "Update CHANGELOG.md" - the changelog update is just a side effect, not the main change
- If changes are focused on one area, describe that (e.g., "Add MFA audit log actions", "Update invoice field descriptions")
- If there are multiple unrelated changes that can't fit in 72 characters, use "Sync OpenAPI spec from managed-service"
- Focus on WHAT changed in the API/SDK, not the process of updating files

The commit body MUST include the trailer "Managed-service-pr-url: $MANAGED_SERVICE_PR_URL" exactly as shown.
Do not add any text after the PR description section.
60 changes: 60 additions & 0 deletions .github/workflows/openapi-sync.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Sync OpenAPI Spec from Managed Service

on:
workflow_dispatch:
inputs:
event_type:
description: 'Event type (openapi-spec-changed or openapi-spec-merged)'
required: true
type: choice
options:
- openapi-spec-changed
- openapi-spec-merged
pr_url:
description: 'Managed-service PR URL'
required: true
type: string
sha:
description: 'Managed-service commit SHA (required for merged events)'
required: false
type: string

# Required permissions for the workflow
permissions:
contents: write
pull-requests: write
id-token: write

jobs:
openapi-sync:
runs-on: ubuntu-latest
env:
EVENT_TYPE: ${{ github.event.inputs.event_type }}
MANAGED_SERVICE_PR_URL: ${{ github.event.inputs.pr_url }}
MANAGED_SERVICE_SHA: ${{ github.event.inputs.sha }}
MANAGED_SERVICE_TOKEN: ${{ secrets.MANAGED_SERVICE_TOKEN }}
FORK_OWNER: crl-gh-actions-pr-bot
FORK_PUSH_TOKEN: ${{ secrets.FORK_PUSH_TOKEN }}
CREATE_PR_TOKEN: ${{ github.token }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
token: ${{ github.token }}
persist-credentials: false

- name: Set up Go
uses: actions/setup-go@v6
with:
go-version-file: go.mod

- name: Authenticate to Google Cloud (Vertex AI)
uses: google-github-actions/auth@v3
with:
project_id: vertex-model-runners
service_account: [email protected]
workload_identity_provider: projects/108106229451/locations/global/workloadIdentityPools/vertex-ai-user/providers/vertex-ai-user

- name: Run OpenAPI sync workflow
run: scripts/openapi-sync.sh
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Added automated workflow for OpenAPI spec synchronization from managed-service.
Supports both `openapi-spec-changed` (creates/updates PRs) and `openapi-spec-merged`
(updates PRs with exact merged commit) event types.

## [7.1.0] - 2026-04-14

### Added
Expand Down
19 changes: 19 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,22 @@
## GitHub Actions

- When writing or modifying GitHub Actions workflows, always look up the latest major version of each action before using it. Do not assume you know the current version.

## Versioning

CHANGELOG.md is the single source of truth for the version. When committing changes, add a user-facing entry under the `## [Unreleased]` section describing what changed. Follow the [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) format with these subsections: `### Added`, `### Changed`, `### Deprecated`, `### Removed`, `### Fixed`, `### Security`. Prefix breaking changes with "Breaking Change: ".

When releasing a new version, move `[Unreleased]` entries in CHANGELOG.md to a new `[x.y.z]` section.

### Writing good changelog entries

- Be brief. One sentence per entry.
- Write from the user's perspective. Describe what they can now do, not what code changed.
- Start each entry with a verb (e.g. Add, Update, Fix, Remove).
- Group related changes into one entry when they form a single feature (e.g. "Add support for folder management operations").
- Don't list individual fields, models, or implementation details unless they're the primary change.
- For OpenAPI spec syncs, mention the new operations and capabilities, not the sync process itself. The managed-service PR reference belongs in the commit message,
not the changelog.

Good: `Add support for JWT issuer management operations (CreateJwtIssuer, GetJwtIssuer, ListJwtIssuers, UpdateJwtIssuer, DeleteJwtIssuer).`
Bad: `Sync OpenAPI spec from managed-service PR #1234 and add JwtIssuer CRUD operations with Audience, IssuerUrl, JwksUri, and ClaimMap fields.`
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ TOOLPATH := $(abspath bin)
.PHONY: generate-openapi-client
generate-openapi-client: bin/goimports
rm -rf ./pkg/client/*.go docs
docker-compose -f ./docker-compose.yml run --rm \
docker compose -f ./docker-compose.yml run --rm \
jq -M -f filter.jq internal/spec/openapi.json > internal/openapi-generator/api/openapi-modified.json
docker-compose -f ./docker-compose.yml run --rm \
docker compose -f ./docker-compose.yml run --rm \
openapi-generator generate \
-g go \
-i internal/openapi-generator/api/openapi-modified.json \
Expand Down
77 changes: 77 additions & 0 deletions scripts/lib/find-sdk-pr.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#!/usr/bin/env bash
# Find an SDK PR that corresponds to a managed-service PR URL.
#
# This searches all open PRs in the current repository and inspects
# all commits in each PR to find one containing a trailer:
# Managed-service-pr-url: <pr_url>
#
# Usage:
# find_sdk_pr <managed_service_pr_url>
#
# Exports on success:
# SDK_PR_NUMBER: The SDK PR number
# SDK_PR_BRANCH: The SDK PR branch name
#
# Returns:
# 0 if found, 1 if not found

# Get the script directory to find helper functions
LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$LIB_DIR/logging.sh"

find_sdk_pr() {
local managed_service_pr_url="$1"

if [[ -z "${managed_service_pr_url:-}" ]]; then
log_error "managed_service_pr_url is required"
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 need to include the logging.sh? Or is it assumed to included by the invoking script already? If it's assumed we should probably check that it's available when this script is invoked and fail with a message in case someone tries to use it differently.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

i decided to source in each file

return 1
fi

if [[ -z "${CREATE_PR_TOKEN:-}" ]]; then
log_error "CREATE_PR_TOKEN environment variable is not set"
return 1
fi

if [[ -z "${GITHUB_REPOSITORY:-}" ]]; then
log_error "GITHUB_REPOSITORY environment variable is not set"
return 1
fi

log_info "Searching for SDK PR corresponding to: $managed_service_pr_url"

export GH_TOKEN="$CREATE_PR_TOKEN"

# Get all open SDK PRs
local sdk_open_prs
sdk_open_prs=$(gh pr list --repo "$GITHUB_REPOSITORY" --state open --json number --jq '.[].number')

for sdk_pr_num in $sdk_open_prs; do
log_info "Checking SDK PR #$sdk_pr_num"

# Get all commits in this SDK PR
local sdk_commits
sdk_commits=$(gh api "repos/$GITHUB_REPOSITORY/pulls/$sdk_pr_num/commits" --jq '.[].sha')

# Check each commit's message for the trailer
for sdk_commit_sha in $sdk_commits; do
local sdk_commit_msg
sdk_commit_msg=$(gh api "repos/$GITHUB_REPOSITORY/git/commits/$sdk_commit_sha" --jq '.message')

if echo "$sdk_commit_msg" | grep --quiet --fixed-strings "Managed-service-pr-url: $managed_service_pr_url"; then
log_info "Found matching SDK PR #$sdk_pr_num (commit $sdk_commit_sha)"

# Get the SDK PR branch
local sdk_pr_branch
sdk_pr_branch=$(gh pr view "$sdk_pr_num" --repo "$GITHUB_REPOSITORY" --json headRefName --jq '.headRefName')

# Export results
export SDK_PR_NUMBER="$sdk_pr_num"
export SDK_PR_BRANCH="$sdk_pr_branch"
return 0
fi
done
done

log_info "No matching SDK PR found"
return 1
}
18 changes: 18 additions & 0 deletions scripts/lib/git-askpass.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env bash
# GIT_ASKPASS script for fork authentication. Reads credentials from
# environment variables so the token is never written to disk.
set -euo pipefail

# Get the script directory to find helper functions
LIB_DIR="$(cd "$(dirname "$0")" && pwd)"
source "$LIB_DIR/logging.sh"

if [ -z "$GIT_FORK_USER" ] || [ -z "$GIT_FORK_PASSWORD" ]; then
log_error "GIT_FORK_USER and GIT_FORK_PASSWORD must be set"
exit 1
fi

case "$1" in
Username*) echo "$GIT_FORK_USER" ;;
Password*) echo "$GIT_FORK_PASSWORD" ;;
esac
Loading
Loading