diff --git a/.github/workflows/update-generator.yml b/.github/workflows/update-generator.yml new file mode 100644 index 000000000..6112ca8ee --- /dev/null +++ b/.github/workflows/update-generator.yml @@ -0,0 +1,75 @@ +name: Update TypeSpec Generator Version + +on: + schedule: + # Run weekly on Mondays at 9 AM UTC + - cron: '0 9 * * 1' + workflow_dispatch: + # Allow manual triggering + repository_dispatch: + # Allow triggering from TypeSpec repository on new releases + types: [typespec-release] + +jobs: + update-generator: + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '22.x' + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.x + + - name: Check for generator updates + id: check-updates + run: | + # Get current version from the OpenAI package.json file + CURRENT_VERSION=$(node -p "require('.codegen/package.json').dependencies['@typespec/http-client-csharp']" 2>/dev/null || echo "unknown") + + echo "Current OpenAI version: $CURRENT_VERSION" + + # Get latest version from npm registry + LATEST_VERSION=$(npm view @typespec/http-client-csharp version 2>/dev/null || echo "unknown") + echo "Latest version from npm: $LATEST_VERSION" + + # Validate we got valid versions + if [ "$CURRENT_VERSION" = "unknown" ] || [ "$LATEST_VERSION" = "unknown" ]; then + echo "Error: Failed to get version information" + echo "Current: $CURRENT_VERSION, Latest: $LATEST_VERSION" + exit 1 + fi + + # Compare versions (simple string comparison for alpha versions) + if [ "$CURRENT_VERSION" != "$LATEST_VERSION" ]; then + echo "Update needed: $CURRENT_VERSION -> $LATEST_VERSION" + echo "needs-update=true" >> $GITHUB_OUTPUT + echo "current-version=$CURRENT_VERSION" >> $GITHUB_OUTPUT + echo "latest-version=$LATEST_VERSION" >> $GITHUB_OUTPUT + else + echo "No update needed - already at latest version: $CURRENT_VERSION" + echo "needs-update=false" >> $GITHUB_OUTPUT + fi + + - name: Update generator version and create PR + if: steps.check-updates.outputs.needs-update == 'true' + run: | + LATEST_VERSION="${{ steps.check-updates.outputs.latest-version }}" + + # Use the PowerShell script to handle the entire update process (following TypeSpec pattern) + pwsh ./scripts/Submit-GeneratorUpdatePr.ps1 \ + -PackageVersion "$LATEST_VERSION" \ + -AuthToken "${{ secrets.GITHUB_TOKEN }}" \ + -RepoPath "." diff --git a/scripts/Submit-GeneratorUpdatePr.ps1 b/scripts/Submit-GeneratorUpdatePr.ps1 new file mode 100644 index 000000000..b6d9cec6d --- /dev/null +++ b/scripts/Submit-GeneratorUpdatePr.ps1 @@ -0,0 +1,226 @@ +#!/usr/bin/env pwsh + +<# +.DESCRIPTION +Creates a pull request to update the @typespec/http-client-csharp dependency in the OpenAI SDK for .NET repository. +This script follows the pattern used by the TypeSpec repository for creating PRs in downstream repositories. + +.PARAMETER PackageVersion +The version of the @typespec/http-client-csharp package to update to. + +.PARAMETER AuthToken +A GitHub personal access token for authentication. + +.PARAMETER BranchName +The name of the branch to create in the repository. + +.PARAMETER RepoPath +The path to the local repository. Defaults to current directory. + +.EXAMPLE +# Update to a specific version +./Submit-GeneratorUpdatePr.ps1 -PackageVersion "1.0.0-alpha.20250625.4" -AuthToken "ghp_xxxx" +#> +[CmdletBinding(SupportsShouldProcess = $true)] +param( + [Parameter(Mandatory = $true)] + [string]$PackageVersion, + + [Parameter(Mandatory = $true)] + [string]$AuthToken, + + [Parameter(Mandatory = $false)] + [string]$BranchName = "typespec/update-http-client-csharp-$PackageVersion", + + [Parameter(Mandatory = $false)] + [string]$RepoPath = "." +) + +# Set up variables for the PR +$RepoOwner = "openai" +$RepoName = "openai-dotnet" +$BaseBranch = "main" +$PRBranch = $BranchName + +function Write-Log { + param([string]$Message) + Write-Host "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss'): $Message" -ForegroundColor Green +} + +function Write-Warning-Log { + param([string]$Message) + Write-Host "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss'): WARNING: $Message" -ForegroundColor Yellow +} + +function Write-Error-Log { + param([string]$Message) + Write-Host "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss'): ERROR: $Message" -ForegroundColor Red +} + +Write-Log "Starting TypeSpec generator update process" +Write-Log "Target version: $PackageVersion" +Write-Log "Repository: $RepoOwner/$RepoName" +Write-Log "Branch: $PRBranch" + +try { + Push-Location $RepoPath + + # Get current version from package.json files + $openAiPackageJsonPath = "codegen/package.json" + + if (-not (Test-Path $openAiPackageJsonPath)) { + throw "OpenAI package.json not found at: $openAiPackageJsonPath" + } + + # Read current versions + $openAiPackageJson = Get-Content $openAiPackageJsonPath -Raw | ConvertFrom-Json + + $currentVersion = $openAiPackageJson.dependencies.'@typespec/http-client-csharp' + + Write-Log "Current OpenAI version: $currentVersion" + + # Check if update is needed + if ($currentVersion -eq $PackageVersion) { + Write-Log "No update needed. Already at version: $PackageVersion" + return + } + + Write-Log "Update needed: $currentVersion -> $PackageVersion" + + # Create a new branch + Write-Log "Creating branch: $PRBranch" + git checkout -b $PRBranch + if ($LASTEXITCODE -ne 0) { + throw "Failed to create branch: $PRBranch" + } + + # Update OpenAI package.json + Write-Log "Updating OpenAI package.json" + $openAiPackageJson.dependencies.'@typespec/http-client-csharp' = $PackageVersion + $openAiPackageJson | ConvertTo-Json -Depth 10 | Set-Content -Path $openAiPackageJsonPath + + # Update Microsoft.TypeSpec.Generator.ClientModel version in csproj files + $openAiCsprojPath = "codegen/generator/src/OpenAI.Library.Plugin.csproj" + + Write-Log "Updating Microsoft.TypeSpec.Generator.ClientModel version in csproj files" + + # Update OpenAI csproj + if (Test-Path $openAiCsprojPath) { + $openAiCsproj = Get-Content $openAiCsprojPath -Raw + $openAiCsproj = $openAiCsproj -replace '(&1 + + if ($LASTEXITCODE -ne 0) { + throw "Failed to create PR using gh CLI: $prUrl" + } + + Write-Log "Successfully created PR: $prUrl" + +} catch { + Write-Error-Log "Error creating PR: $_" + exit 1 +} finally { + Pop-Location +}