.github/workflows/_refresh_model_profiles.yml YAML 203 lines View on github.com → Search inside
1# Reusable workflow: refreshes model profile data for any repo that uses the2# `langchain-profiles` CLI. Creates (or updates) a pull request with the3# resulting changes.4#5# Callers MUST set `permissions: { contents: write, pull-requests: write }` 6# reusable workflows cannot escalate the caller's token permissions.7#8# ── Example: external repo (langchain-google) ──────────────────────────9#10#   jobs:11#     refresh-profiles:12#       uses: langchain-ai/langchain/.github/workflows/_refresh_model_profiles.yml@master13#       with:14#         providers: >-15#           [16#             {"provider":"google",        "data_dir":"libs/genai/langchain_google_genai/data"},17#           ]18#       secrets:19#         MODEL_PROFILE_BOT_APP_ID:      ${{ secrets.MODEL_PROFILE_BOT_APP_ID }}20#         MODEL_PROFILE_BOT_PRIVATE_KEY: ${{ secrets.MODEL_PROFILE_BOT_PRIVATE_KEY }}2122name: "Refresh Model Profiles (reusable)"2324on:25  workflow_call:26    inputs:27      providers:28        description: >-29          JSON array of objects, each with `provider` (models.dev provider ID)30          and `data_dir` (path relative to repo root where `_profiles.py` and31          `profile_augmentations.toml` live).32        required: true33        type: string34      cli-path:35        description: >-36          Path (relative to workspace) to an existing `libs/model-profiles`37          checkout.  When set the workflow skips cloning the langchain repo and38          uses this directory for the CLI instead.  Useful when the caller IS39          the langchain monorepo.40        required: false41        type: string42        default: ""43      cli-ref:44        description: >-45          Git ref of langchain-ai/langchain to checkout for the CLI.46          Ignored when `cli-path` is set.47        required: false48        type: string49        default: master50      add-paths:51        description: "Glob for files to stage in the PR commit."52        required: false53        type: string54        default: "**/_profiles.py"55      pr-branch:56        description: "Branch name for the auto-created PR."57        required: false58        type: string59        default: bot/refresh-model-profiles60      pr-title:61        description: "PR / commit title."62        required: false63        type: string64        default: "chore(model-profiles): refresh model profile data"65      pr-body:66        description: "PR body."67        required: false68        type: string69        default: |70          Automated refresh of model profile data via `langchain-profiles refresh`.7172          🤖 Generated by the `refresh_model_profiles` workflow.73      pr-labels:74        description: "Comma-separated labels to apply to the PR."75        required: false76        type: string77        default: bot78    secrets:79      MODEL_PROFILE_BOT_APP_ID:80        required: true81      MODEL_PROFILE_BOT_PRIVATE_KEY:82        required: true8384permissions:85  contents: write86  pull-requests: write8788jobs:89  refresh-profiles:90    name: refresh model profiles91    runs-on: ubuntu-latest92    steps:93      - name: "📋 Checkout"94        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v69596      - name: "📋 Checkout langchain-profiles CLI"97        if: inputs.cli-path == ''98        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v699        with:100          repository: langchain-ai/langchain101          ref: ${{ inputs.cli-ref }}102          sparse-checkout: libs/model-profiles103          path: _langchain-cli104105      - name: "🔧 Resolve CLI directory"106        id: cli107        env:108          CLI_PATH: ${{ inputs.cli-path }}109        run: |110          if [ -n "${CLI_PATH}" ]; then111            resolved="${GITHUB_WORKSPACE}/${CLI_PATH}"112            if [ ! -d "${resolved}" ]; then113              echo "::error::cli-path '${CLI_PATH}' does not exist at ${resolved}"114              exit 1115            fi116            echo "dir=${CLI_PATH}" >> "$GITHUB_OUTPUT"117          else118            echo "dir=_langchain-cli/libs/model-profiles" >> "$GITHUB_OUTPUT"119          fi120121      - name: "🐍 Set up Python + uv"122        uses: astral-sh/setup-uv@0ca8f610542aa7f4acaf39e65cf4eb3c35091883 # v7123        with:124          version: "0.5.25"125          python-version: "3.12"126          enable-cache: true127          cache-dependency-glob: "**/model-profiles/uv.lock"128129      - name: "📦 Install langchain-profiles CLI"130        working-directory: ${{ steps.cli.outputs.dir }}131        run: uv sync --frozen --no-group test --no-group dev --no-group lint132133      - name: "✅ Validate providers input"134        env:135          PROVIDERS_JSON: ${{ inputs.providers }}136        run: |137          echo "${PROVIDERS_JSON}" | jq -e 'type == "array" and length > 0' > /dev/null || {138            echo "::error::providers input must be a non-empty JSON array"139            exit 1140          }141          echo "${PROVIDERS_JSON}" | jq -e 'all(has("provider") and has("data_dir"))' > /dev/null || {142            echo "::error::every entry in providers must have 'provider' and 'data_dir' keys"143            exit 1144          }145146      - name: "🔄 Refresh profiles"147        env:148          PROVIDERS_JSON: ${{ inputs.providers }}149        run: |150          cli_dir="${GITHUB_WORKSPACE}/${{ steps.cli.outputs.dir }}"151          failed=""152          mapfile -t rows < <(echo "${PROVIDERS_JSON}" | jq -c '.[]')153          for row in "${rows[@]}"; do154            provider=$(echo "${row}" | jq -r '.provider')155            data_dir=$(echo "${row}" | jq -r '.data_dir')156            echo "--- Refreshing ${provider} -> ${data_dir} ---"157            if ! echo y | uv run --frozen --project "${cli_dir}" \158              langchain-profiles refresh \159              --provider "${provider}" \160              --data-dir "${GITHUB_WORKSPACE}/${data_dir}"; then161              echo "::error::Failed to refresh provider: ${provider}"162              failed="${failed} ${provider}"163            fi164          done165          if [ -n "${failed}" ]; then166            echo "::error::The following providers failed:${failed}"167            exit 1168          fi169170      - name: "🔑 Generate GitHub App token"171        id: app-token172        uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3173        with:174          app-id: ${{ secrets.MODEL_PROFILE_BOT_APP_ID }}175          private-key: ${{ secrets.MODEL_PROFILE_BOT_PRIVATE_KEY }}176177      - name: "🔀 Create pull request"178        id: create-pr179        uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8180        with:181          token: ${{ steps.app-token.outputs.token }}182          branch: ${{ inputs.pr-branch }}183          commit-message: ${{ inputs.pr-title }}184          title: ${{ inputs.pr-title }}185          body: ${{ inputs.pr-body }}186          labels: ${{ inputs.pr-labels }}187          add-paths: ${{ inputs.add-paths }}188189      - name: "📝 Summary"190        if: always()191        env:192          PR_OP: ${{ steps.create-pr.outputs.pull-request-operation }}193          PR_URL: ${{ steps.create-pr.outputs.pull-request-url }}194          JOB_STATUS: ${{ job.status }}195        run: |196          if [ "${PR_OP}" = "created" ] || [ "${PR_OP}" = "updated" ]; then197            echo "### ✅ PR ${PR_OP}: ${PR_URL}" >> "$GITHUB_STEP_SUMMARY"198          elif [ -z "${PR_OP}" ] && [ "${JOB_STATUS}" = "success" ]; then199            echo "### ⏭️ Skipped: profiles already up to date" >> "$GITHUB_STEP_SUMMARY"200          elif [ "${JOB_STATUS}" = "failure" ]; then201            echo "### ❌ Job failed — check step logs for details" >> "$GITHUB_STEP_SUMMARY"202          fi

Findings

✓ No findings reported for this file.

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.