Update provider types #5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Update provider types | |
| on: | |
| schedule: | |
| - cron: "0 10 * * 1" | |
| workflow_dispatch: | |
| inputs: | |
| providers: | |
| description: 'Providers to update (comma-separated: openai,anthropic,google or "all")' | |
| required: false | |
| default: "all" | |
| type: string | |
| concurrency: | |
| group: update-provider-types | |
| cancel-in-progress: false | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| jobs: | |
| update-provider-types: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up Rust | |
| uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable | |
| with: | |
| components: rustfmt, clippy | |
| - name: Set up Node.js | |
| uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 | |
| with: | |
| node-version: 24 | |
| registry-url: "https://registry.npmjs.org" | |
| - name: Set up pnpm | |
| uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 | |
| with: | |
| version: 10.33.0 | |
| - name: Cache cargo registry | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| target | |
| key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo- | |
| - name: Install dependencies | |
| run: | | |
| set -euo pipefail | |
| sudo apt-get update | |
| sudo apt-get install -y protobuf-compiler | |
| pnpm add -g quicktype | |
| - name: Parse provider input | |
| id: providers | |
| env: | |
| REQUESTED_PROVIDERS: ${{ inputs.providers || 'all' }} | |
| run: | | |
| set -euo pipefail | |
| providers="$REQUESTED_PROVIDERS" | |
| if [ "$providers" = "all" ]; then | |
| providers="openai,anthropic,google" | |
| fi | |
| echo "providers=$providers" >> "$GITHUB_OUTPUT" | |
| echo "Will update providers: $providers" | |
| - name: Update provider specifications and types | |
| id: generate | |
| continue-on-error: true | |
| run: | | |
| set +e | |
| log_path="$RUNNER_TEMP/provider-type-generation.log" | |
| : > "$log_path" | |
| providers="${{ steps.providers.outputs.providers }}" | |
| status=0 | |
| IFS=',' read -ra provider_array <<< "$providers" | |
| for provider in "${provider_array[@]}"; do | |
| provider=$(echo "$provider" | xargs) | |
| if [ -z "$provider" ]; then | |
| continue | |
| fi | |
| { | |
| echo | |
| echo "## Updating $provider" | |
| ./pipelines/generate-provider-types.sh "$provider" | |
| } 2>&1 | tee -a "$log_path" | |
| provider_status=${PIPESTATUS[0]} | |
| if [ "$provider_status" -ne 0 ]; then | |
| status="$provider_status" | |
| break | |
| fi | |
| done | |
| echo "log_path=$log_path" >> "$GITHUB_OUTPUT" | |
| exit "$status" | |
| - name: Repair failed generation | |
| if: steps.generate.outcome == 'failure' | |
| uses: anthropics/claude-code-action@df37d2f0760a4b5683a6e617c9325bc1a36443f6 # v1.0.75 | |
| with: | |
| anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} | |
| github_token: ${{ github.token }} | |
| show_full_output: "true" | |
| display_report: "true" | |
| timeout_minutes: "20" | |
| claude_args: | | |
| --model claude-opus-4-6 | |
| --max-turns 80 | |
| --allowedTools "Read,Glob,Grep,LS,Bash,WebSearch,WebFetch,Edit,Write" | |
| --disallowedTools "MultiEdit,Replace,NotebookEditCell,mcp__github__create_issue,mcp__github__create_issue_comment,mcp__github__update_issue,mcp__github__create_pr,mcp__github__create_or_update_file,mcp__github__delete_file,mcp__github_file_ops__commit_files,mcp__github_file_ops__delete_files" | |
| prompt: | | |
| # Goal | |
| The automated Lingua provider type update failed. Make one focused repair attempt so the regenerated provider types build, then leave the repository ready for the workflow to validate and open a PR. | |
| # Inputs | |
| - Providers requested: `${{ steps.providers.outputs.providers }}` | |
| - Generation/build log: `${{ steps.generate.outputs.log_path }}` | |
| # Local files to read first | |
| - `AGENTS.md` | |
| - `Makefile` | |
| - `pipelines/generate-provider-types.sh` | |
| - `crates/generate-types/src/main.rs` | |
| - Provider modules under `crates/lingua/src/providers/` for the providers requested above | |
| # Process | |
| 1. Read the log and identify whether the failure is a local Rust/type-generation/build problem. | |
| 2. If the failure is a transient network, provider API, package install, or external service failure, do not work around it with fake data or fallback content. | |
| 3. If the failure is a local generation or compile issue, fix the smallest responsible source area. | |
| 4. Prefer fixing generation logic in `crates/generate-types/` or typed provider adapters/converters. Do not manually edit files named `generated.rs`. | |
| 5. Keep typed boundaries: deserialize into typed structs/enums instead of adding raw `serde_json::Value` field-plucking for provider semantics. | |
| 6. Rerun the relevant generation/build command if you changed generation logic so generated outputs reflect the fix. | |
| 7. Do not create or update GitHub issues, comments, pull requests, or branches. | |
| # Output | |
| Leave code changes in the working tree only. The workflow will run formatting, build validation, and PR creation after this step. | |
| - name: Re-run provider update after repair | |
| if: steps.generate.outcome == 'failure' | |
| run: | | |
| set -euo pipefail | |
| log_path="$RUNNER_TEMP/provider-type-generation.retry.log" | |
| : > "$log_path" | |
| providers="${{ steps.providers.outputs.providers }}" | |
| IFS=',' read -ra provider_array <<< "$providers" | |
| for provider in "${provider_array[@]}"; do | |
| provider=$(echo "$provider" | xargs) | |
| if [ -z "$provider" ]; then | |
| continue | |
| fi | |
| { | |
| echo | |
| echo "## Updating $provider" | |
| ./pipelines/generate-provider-types.sh "$provider" | |
| } 2>&1 | tee -a "$log_path" | |
| done | |
| - name: Check for changes | |
| id: changes | |
| run: | | |
| set -euo pipefail | |
| if [ -z "$(git status --porcelain)" ]; then | |
| echo "has_changes=false" >> "$GITHUB_OUTPUT" | |
| echo "No changes detected in provider types" | |
| exit 0 | |
| fi | |
| echo "has_changes=true" >> "$GITHUB_OUTPUT" | |
| echo "Changes detected:" | |
| git status --short | |
| - name: Format code | |
| if: steps.changes.outputs.has_changes == 'true' | |
| run: cargo fmt --all | |
| - name: Validate build | |
| if: steps.changes.outputs.has_changes == 'true' | |
| run: | | |
| set -euo pipefail | |
| cargo build --all-features | |
| - name: Run clippy | |
| if: steps.changes.outputs.has_changes == 'true' | |
| run: cargo clippy --all-targets --all-features -- -D warnings | |
| - name: Build PR body | |
| if: steps.changes.outputs.has_changes == 'true' | |
| run: | | |
| set -euo pipefail | |
| { | |
| echo "Automated update of Lingua provider types." | |
| echo | |
| echo "Providers: \`${{ steps.providers.outputs.providers }}\`" | |
| echo | |
| echo "**Validation**" | |
| echo | |
| echo "- Ran \`./pipelines/generate-provider-types.sh\` for each requested provider" | |
| if [ "${{ steps.generate.outcome }}" = "failure" ]; then | |
| echo "- Ran one Claude repair pass after the initial generation/build failure" | |
| echo "- Re-ran \`./pipelines/generate-provider-types.sh\` for each requested provider after repair" | |
| fi | |
| echo "- Ran \`cargo fmt --all\`" | |
| echo "- Ran \`cargo build --all-features\`" | |
| echo "- Ran \`cargo clippy --all-targets --all-features -- -D warnings\`" | |
| } > "$RUNNER_TEMP/update-provider-types-pr-body.md" | |
| - name: Create PR | |
| if: steps.changes.outputs.has_changes == 'true' | |
| uses: peter-evans/create-pull-request@22a9089034f40e5a961c8808d113e2c98fb63676 # v7.0.11 | |
| with: | |
| token: ${{ github.token }} | |
| base: main | |
| branch: update-provider-types | |
| commit-message: "Update ${{ steps.providers.outputs.providers }} provider types" | |
| title: "Update ${{ steps.providers.outputs.providers }} provider types" | |
| body-path: ${{ runner.temp }}/update-provider-types-pr-body.md | |
| labels: auto-sync | |
| delete-branch: true | |
| signoff: false | |
| - name: Summary | |
| run: | | |
| set -euo pipefail | |
| if [ "${{ steps.changes.outputs.has_changes }}" = "true" ]; then | |
| echo "Provider types changed; PR creation step ran." | |
| else | |
| echo "Provider types are already up to date." | |
| fi |