mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-06-11 02:27:38 +00:00
* chore: harden CI supply chain workflows * chore: address CI hardening review feedback * chore: tighten GitNexus dispatch hardening * chore: use app token for Locize PR automation * chore: use dedicated token for Locize PR automation
141 lines
5.7 KiB
YAML
141 lines
5.7 KiB
YAML
# Responds to `/gitnexus index` comments on pull requests.
|
|
#
|
|
# Gated to the same author_association roles (OWNER, MEMBER, COLLABORATOR)
|
|
# as the automatic PR index trigger, but applied to the COMMENTER, not
|
|
# the PR author. This intentionally lets a contributor index a PR from
|
|
# a non-contributor / first-time fork author — the contributor takes
|
|
# responsibility for the trust boundary by typing the command.
|
|
#
|
|
# When a matching comment lands on a PR, this workflow dispatches
|
|
# `gitnexus-index.yml` with the PR number and the `refs/pull/<N>/head`
|
|
# ref so indexing works for fork PRs too (GitHub mirrors every PR's
|
|
# head ref into the base repo regardless of which fork it originated
|
|
# from, so actions/checkout can always resolve it).
|
|
#
|
|
# Use cases:
|
|
# - Re-index a PR after a rebase without pushing a new commit
|
|
# - Index a docs-only PR that was skipped by paths-ignore
|
|
# - Index a non-contributor (fork) PR that the auto-trigger skipped
|
|
# - Re-run a failed index
|
|
#
|
|
# Supported commands:
|
|
# /gitnexus index — index the PR with embeddings (default)
|
|
# /gitnexus index embeddings — explicit form of the above; same effect
|
|
# /gitnexus index fast — graph-only index (skip embeddings), for
|
|
# a quick re-index without waiting ~5 min
|
|
# of embedding generation
|
|
|
|
name: GitNexus PR Command
|
|
|
|
on:
|
|
issue_comment:
|
|
types: [created]
|
|
|
|
permissions:
|
|
contents: read
|
|
pull-requests: write
|
|
actions: write # needed to dispatch gitnexus-index.yml
|
|
|
|
concurrency:
|
|
group: gitnexus-pr-command-${{ github.event.issue.number }}
|
|
cancel-in-progress: false
|
|
|
|
jobs:
|
|
dispatch:
|
|
# Only run for PR comments that start with /gitnexus from trusted
|
|
# commenters. Intentionally checks the COMMENTER's association so a
|
|
# contributor can index a non-contributor's PR on demand.
|
|
if: |
|
|
github.event.issue.pull_request != null &&
|
|
startsWith(github.event.comment.body, '/gitnexus') &&
|
|
(github.event.comment.author_association == 'OWNER' ||
|
|
github.event.comment.author_association == 'MEMBER' ||
|
|
github.event.comment.author_association == 'COLLABORATOR')
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 5
|
|
steps:
|
|
- name: Parse command and resolve PR head ref
|
|
id: parse
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const body = context.payload.comment.body.trim();
|
|
const match = body.match(/^\/gitnexus\s+(\w+)(?:\s+(\w+))?/);
|
|
if (!match) {
|
|
core.setFailed(`Unrecognized command: ${body}. Try: /gitnexus index [fast]`);
|
|
return;
|
|
}
|
|
const [, subcommand, modifier] = match;
|
|
if (subcommand !== 'index') {
|
|
core.setFailed(`Unknown subcommand: ${subcommand}. Only 'index' is supported.`);
|
|
return;
|
|
}
|
|
// Default to embeddings on — a contributor typing the command
|
|
// has already decided they want a full re-index. The `fast`
|
|
// modifier is the explicit opt-out for graph-only runs.
|
|
// `embeddings` is accepted as a no-op alias for backwards
|
|
// compat with the previous command form.
|
|
let embeddings = 'true';
|
|
if (modifier === 'fast' || modifier === 'graph-only' || modifier === 'no-embeddings') {
|
|
embeddings = 'false';
|
|
}
|
|
|
|
// Use refs/pull/<N>/head instead of the raw head SHA. GitHub
|
|
// mirrors every PR's head into the base repo as this ref, so
|
|
// actions/checkout can always resolve it — even for PRs from
|
|
// forks whose raw SHAs don't exist in the base repo.
|
|
const prNum = context.payload.issue.number;
|
|
core.setOutput('pr_number', String(prNum));
|
|
core.setOutput('pr_ref', `refs/pull/${prNum}/head`);
|
|
core.setOutput('embeddings', embeddings);
|
|
core.info(
|
|
`Dispatching index for PR #${prNum} at refs/pull/${prNum}/head (embeddings=${embeddings}, modifier=${modifier || '(none)'})`,
|
|
);
|
|
|
|
- name: Dispatch gitnexus-index workflow
|
|
uses: actions/github-script@v7
|
|
env:
|
|
EMBEDDINGS: ${{ steps.parse.outputs.embeddings }}
|
|
PR_NUMBER: ${{ steps.parse.outputs.pr_number }}
|
|
PR_REF: ${{ steps.parse.outputs.pr_ref }}
|
|
with:
|
|
script: |
|
|
const prNumber = process.env.PR_NUMBER || '';
|
|
const prRef = process.env.PR_REF || '';
|
|
const embeddings = process.env.EMBEDDINGS || 'false';
|
|
if (!/^[0-9]+$/.test(prNumber)) {
|
|
core.setFailed(`Invalid PR number: ${prNumber}`);
|
|
return;
|
|
}
|
|
if (prRef !== `refs/pull/${prNumber}/head`) {
|
|
core.setFailed(`Invalid PR ref: ${prRef}`);
|
|
return;
|
|
}
|
|
if (!['true', 'false'].includes(embeddings)) {
|
|
core.setFailed(`Invalid embeddings value: ${embeddings}`);
|
|
return;
|
|
}
|
|
await github.rest.actions.createWorkflowDispatch({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
workflow_id: 'gitnexus-index.yml',
|
|
ref: 'main',
|
|
inputs: {
|
|
pr_number: prNumber,
|
|
pr_ref: prRef,
|
|
embeddings,
|
|
force: 'false',
|
|
deploy_after: 'true',
|
|
},
|
|
});
|
|
|
|
- name: React to the comment
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
await github.rest.reactions.createForIssueComment({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
comment_id: context.payload.comment.id,
|
|
content: 'rocket',
|
|
});
|