Files
langchain/.github/workflows/refresh_model_profiles.yml
John Kennedy bb8b057ac3 ci(infra): add top-level permissions and SHA-pin third-party actions [INF-0000] (#35588)
## Summary

- Adds top-level `permissions: contents: read` to 5 workflows that only
had job-level permissions: `pr_labeler_file`, `pr_labeler_title`,
`tag-external-contributions`, `v03_api_doc_build`,
`auto-label-by-package`
- SHA-pins all 14 third-party actions to full commit SHAs to prevent
supply chain attacks via tag hijacking

## Why

**Missing top-level permissions:** Without an explicit top-level
`permissions` block, workflows inherit the repository/org default token
permissions, which may be overly broad. Adding `contents: read` as the
default restricts the blast radius if a dependency or action step is
compromised.

**SHA pinning:** Mutable tags (`@v1`, `@master`) can be force-pushed by
the action maintainer or an attacker who compromises their account.
Pinning to a full 40-character SHA ensures the exact reviewed code
always runs. Tag comments are preserved for readability.

### Actions pinned

| Action | File(s) |
|--------|---------|
| `pypa/gh-action-pypi-publish` | `_release.yml` (2 uses) |
| `ncipollo/release-action` | `_release.yml` |
| `Ana06/get-changed-files` | `check_diffs.yml` |
| `astral-sh/setup-uv` | `check_diffs.yml`, `uv_setup/action.yml` |
| `CodSpeedHQ/action` | `check_diffs.yml` |
| `google-github-actions/auth` | `integration_tests.yml` |
| `aws-actions/configure-aws-credentials` | `integration_tests.yml` |
| `amannn/action-semantic-pull-request` | `pr_lint.yml` |
| `bcoe/conventional-release-labels` | `pr_labeler_title.yml` |
| `mikefarah/yq` | `v03_api_doc_build.yml` |
| `EndBug/add-and-commit` | `v03_api_doc_build.yml` |
| `peter-evans/create-pull-request` | `refresh_model_profiles.yml` |

## Test plan

- [x] CI passes — all workflows still resolve their actions correctly
- [x] Verify no functional change: SHA refs point to the same code as
the previous tags

---

> This PR was generated with assistance from an AI coding agent as part
of a repository posture check.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 07:20:05 +00:00

94 lines
3.2 KiB
YAML

# Refreshes model profile data for all in-monorepo partner integrations by
# pulling the latest metadata from models.dev via the `langchain-profiles` CLI.
#
# Creates a pull request with any changes. Runs daily and can be triggered
# manually from the Actions UI. Uses a fixed branch so each run supersedes
# any stale PR from a previous run.
name: "🔄 Refresh Model Profiles"
on:
schedule:
- cron: "0 8 * * *" # daily at 08:00 UTC
workflow_dispatch:
permissions:
contents: write
pull-requests: write
jobs:
refresh-profiles:
name: "refresh all partner profiles"
runs-on: ubuntu-latest
steps:
- name: "📋 Checkout"
uses: actions/checkout@v6
- name: "🐍 Set up Python + uv"
uses: ./.github/actions/uv_setup
with:
python-version: "3.12"
working-directory: libs/model-profiles
- name: "📦 Install langchain-profiles CLI"
working-directory: libs/model-profiles
run: uv sync
- name: "🔄 Refresh profiles"
working-directory: libs/model-profiles
run: |
declare -A PROVIDERS=(
[anthropic]=anthropic
[deepseek]=deepseek
[fireworks]=fireworks-ai
[groq]=groq
[huggingface]=huggingface
[mistralai]=mistral
[openai]=openai
[openrouter]=openrouter
[perplexity]=perplexity
[xai]=xai
)
for partner in "${!PROVIDERS[@]}"; do
provider="${PROVIDERS[$partner]}"
data_dir="../../libs/partners/${partner}/langchain_${partner//-/_}/data"
echo "--- Refreshing ${partner} (provider: ${provider}) ---"
echo y | uv run langchain-profiles refresh \
--provider "$provider" \
--data-dir "$data_dir"
done
- name: "🔑 Generate GitHub App token"
id: app-token
uses: actions/create-github-app-token@v2
with:
app-id: ${{ secrets.MODEL_PROFILE_BOT_APP_ID }}
private-key: ${{ secrets.MODEL_PROFILE_BOT_PRIVATE_KEY }}
- name: "🔀 Create pull request"
id: create-pr
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8
with:
token: ${{ steps.app-token.outputs.token }}
branch: bot/refresh-model-profiles
commit-message: "chore(model-profiles): refresh model profile data"
title: "chore(model-profiles): refresh model profile data"
body: |
Automated refresh of model profile data for all in-monorepo partner
integrations via `langchain-profiles refresh`.
🤖 Generated by the `refresh_model_profiles` workflow.
labels: bot
add-paths: libs/partners/**/data/_profiles.py
- name: "📝 Summary"
run: |
op="${{ steps.create-pr.outputs.pull-request-operation }}"
url="${{ steps.create-pr.outputs.pull-request-url }}"
if [ "$op" = "created" ] || [ "$op" = "updated" ]; then
echo "### ✅ PR ${op}: ${url}" >> "$GITHUB_STEP_SUMMARY"
else
echo "### ⏭️ Skipped: profiles already up to date" >> "$GITHUB_STEP_SUMMARY"
fi