mirror of
https://github.com/hwchase17/langchain.git
synced 2026-07-12 19:31:24 +00:00
Adds `github.repository_owner == 'langchain-ai'` guards to 14 GitHub
Actions workflows that were missing them. Without these guards,
write-capable automation (issue/PR labeling, closing, commenting, PR
reopening, release publishing) and CI jobs fire on forks — causing
unwanted mutations, wasted runner minutes, and failed GitHub App token
generation on repos that don't have the required secrets.
Also removes `v03_api_doc_build.yml`, which pushed built docs to
`langchain-ai/langchain-api-docs-html` via `TOKEN_GITHUB_API_DOCS_HTML`
— a secret that isn't set on this repo. The workflow was dead code with
no consumers.
---
## What changed
**Write-capable workflows now guarded** (8 files):
- `auto-label-by-package` — was adding/removing issue labels on forks
- `close_unchecked_issues` — was closing issues and posting comments on
forks via GitHub App token
- `tag-external-issues` — both `tag-external` and `backfill` jobs were
generating App tokens and labeling issues on forks
- `reopen_on_assignment` — was reopening PRs and re-running workflows on
forks
- `require_issue_link` — was closing PRs, creating labels, posting
comments, and canceling workflow runs on forks
- `remove_waiting_on_author` — was removing labels on fork issues/PRs
- `pr_labeler` — was generating App tokens and adding/removing PR labels
on forks
- `pr_labeler_backfill` — same, on manual trigger from a fork
**Read-only CI workflows now guarded** (5 files):
- `check_diffs` — `build` and `check-release-options` jobs (downstream
jobs inherit the skip)
- `codspeed` — `build` job
- `check_agents_sync`, `check_versions`, `check_release_deps`
**Release workflow guarded** (1 file):
- `_release` — `build` job (all downstream jobs chain via `needs`, so
they inherit the skip). Previously relied only on `environment: Release`
approval and a `github.ref` check.
**Removed**:
- `v03_api_doc_build.yml` — dead workflow depending on unset
`TOKEN_GITHUB_API_DOCS_HTML` secret
## What was already guarded
`block_fork_main_prs`, `bump_uv_pin`, `check_extras_sync`,
`integration_tests`, `pr_lint_trailer`, `refresh_model_profiles` already
had the guard. `pr_lint` (read-only, `pull-requests: read`) and the
`_*.yml` reusable workflows (only run when called by a guarded parent)
were intentionally left unguarded.
## Release note
- GitHub Actions workflows now skip execution on forks via
`repository_owner == 'langchain-ai'` guards, preventing unwanted
issue/PR automation and CI runs outside the canonical repo.
- Removed the dead `v03_api_doc_build` workflow that depended on an
unset secret.
---
🤖 Generated with AI-agent involvement.
117 lines
4.3 KiB
YAML
117 lines
4.3 KiB
YAML
name: Auto Label Issues by Package
|
|
|
|
on:
|
|
issues:
|
|
types: [opened, edited]
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
label-by-package:
|
|
if: github.repository_owner == 'langchain-ai'
|
|
permissions:
|
|
issues: write
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
- name: Sync package labels
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
with:
|
|
script: |
|
|
const body = context.payload.issue.body || "";
|
|
|
|
// Extract text under "## Package" or "### Package" (handles " (Required)" suffix and being last section)
|
|
const match = body.match(/#{2,3} Package[^\n]*\n([\s\S]*?)(?:\n#{2,3} |$)/i);
|
|
if (!match) {
|
|
core.setFailed(
|
|
`Could not find "## Package" section in issue #${context.issue.number} body. ` +
|
|
`The issue template may have changed — update the regex in this workflow.`
|
|
);
|
|
return;
|
|
}
|
|
|
|
const packageSection = match[1].trim();
|
|
|
|
// Mapping table for package names to labels
|
|
const mapping = {
|
|
"langchain": "langchain",
|
|
"langchain-openai": "openai",
|
|
"langchain-anthropic": "anthropic",
|
|
"langchain-classic": "langchain-classic",
|
|
"langchain-core": "core",
|
|
"langchain-model-profiles": "model-profiles",
|
|
"langchain-tests": "standard-tests",
|
|
"langchain-text-splitters": "text-splitters",
|
|
"langchain-chroma": "chroma",
|
|
"langchain-deepseek": "deepseek",
|
|
"langchain-exa": "exa",
|
|
"langchain-fireworks": "fireworks",
|
|
"langchain-groq": "groq",
|
|
"langchain-huggingface": "huggingface",
|
|
"langchain-mistralai": "mistralai",
|
|
"langchain-nomic": "nomic",
|
|
"langchain-ollama": "ollama",
|
|
"langchain-openrouter": "openrouter",
|
|
"langchain-perplexity": "perplexity",
|
|
"langchain-qdrant": "qdrant",
|
|
"langchain-xai": "xai",
|
|
};
|
|
|
|
// All possible package labels we manage
|
|
const allPackageLabels = Object.values(mapping);
|
|
const selectedLabels = [];
|
|
|
|
// Check if this is checkbox format (multiple selection)
|
|
const checkboxMatches = packageSection.match(/- \[x\]\s+([^\n\r]+)/gi);
|
|
if (checkboxMatches) {
|
|
// Handle checkbox format
|
|
for (const match of checkboxMatches) {
|
|
const packageName = match.replace(/- \[x\]\s+/i, '').trim();
|
|
const label = mapping[packageName];
|
|
if (label && !selectedLabels.includes(label)) {
|
|
selectedLabels.push(label);
|
|
}
|
|
}
|
|
} else {
|
|
// Handle dropdown format (single selection)
|
|
const label = mapping[packageSection];
|
|
if (label) {
|
|
selectedLabels.push(label);
|
|
}
|
|
}
|
|
|
|
// Get current issue labels
|
|
const issue = await github.rest.issues.get({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: context.issue.number
|
|
});
|
|
|
|
const currentLabels = issue.data.labels.map(label => label.name);
|
|
const currentPackageLabels = currentLabels.filter(label => allPackageLabels.includes(label));
|
|
|
|
// Determine labels to add and remove
|
|
const labelsToAdd = selectedLabels.filter(label => !currentPackageLabels.includes(label));
|
|
const labelsToRemove = currentPackageLabels.filter(label => !selectedLabels.includes(label));
|
|
|
|
// Add new labels
|
|
if (labelsToAdd.length > 0) {
|
|
await github.rest.issues.addLabels({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: context.issue.number,
|
|
labels: labelsToAdd
|
|
});
|
|
}
|
|
|
|
// Remove old labels
|
|
for (const label of labelsToRemove) {
|
|
await github.rest.issues.removeLabel({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: context.issue.number,
|
|
name: label
|
|
});
|
|
}
|