Skip to content
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 115 additions & 0 deletions .github/workflows/update-graph.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# Incrementally updates the FalkorDB docs knowledge graph on PR merge.
#
# On merge to main of a PR touching .md files, this workflow:
# 1. Computes the diff (added / modified / deleted .md files).
# 2. Reads the content of added + modified files.
# 3. POSTs the payload to GraphRAG-UI's /api/admin/update-graph endpoint.
# 4. The endpoint does all the SDK / FalkorDB / smoke-test work server-side
# using its existing credentials. This workflow only needs ONE secret:
# ``UPDATE_GRAPH_TOKEN`` — a shared-secret bearer token.
#
# No Azure OpenAI keys, no FalkorDB credentials, no PAT for cross-repo
# checkout. Failures from the server come back as HTTP non-2xx with a
# detail message; curl --fail-with-body bubbles them up as a CI failure.

name: Update graph (incremental)

on:
pull_request:
types: [closed]
branches: [main]
paths:
- "**/*.md"

# Merge target is always main, so all runs share one group. Bursts of PR
# merges queue rather than race. cancel-in-progress: false because each
# run consumes LLM credit and we'd rather pay the wait than re-do work.
concurrency:
group: update-graph-${{ github.ref }}
cancel-in-progress: false
Comment thread
coderabbitai[bot] marked this conversation as resolved.

jobs:
update-graph:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
timeout-minutes: 30
env:
GRAPH_ID: docs_benchmark
# The base URL of the GraphRAG-UI deployment. Set this as a repo or
# environment variable so it can differ between staging and prod.
GRAPHRAG_UI_URL: ${{ vars.GRAPHRAG_UI_URL }}
steps:
- name: Checkout docs
uses: actions/checkout@v4
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
Comment thread
galshubeli marked this conversation as resolved.
Outdated
with:
fetch-depth: 0 # need history for diff against the PR base

- name: Build diff payload
id: payload
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.sha }}
run: |
python3 - <<'PY'
import json, os, pathlib, subprocess, sys

base, head = os.environ["BASE_SHA"], os.environ["HEAD_SHA"]
out = subprocess.run(
["git", "diff", "--name-status", base, head],
capture_output=True, text=True, check=True,
).stdout

added, modified, deleted = {}, {}, []
for line in out.splitlines():
parts = line.split("\t")
if not parts:
continue
status = parts[0][0] # R100 -> R
if status == "R" and len(parts) >= 3:
old, new = parts[1], parts[2]
if old.endswith(".md"):
deleted.append(old)
if new.endswith(".md"):
try:
added[new] = pathlib.Path(new).read_text(encoding="utf-8")
except FileNotFoundError:
pass
continue
if len(parts) < 2 or not parts[1].endswith(".md"):
continue
path = parts[1]
if status == "A":
added[path] = pathlib.Path(path).read_text(encoding="utf-8")
elif status == "M":
modified[path] = pathlib.Path(path).read_text(encoding="utf-8")
elif status == "D":
deleted.append(path)

payload = {
"graph_id": os.environ.get("GRAPH_ID", "docs_benchmark"),
"files": {"added": added, "modified": modified, "deleted": deleted},
}
if not (added or modified or deleted):
# Path filter on the workflow trigger should make this rare, but
# be explicit: no work to do, exit clean before the POST.
print("::notice::No .md changes after filtering — skipping graph update.", file=sys.stderr)
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
f.write("skip=true\n")
sys.exit(0)

pathlib.Path("payload.json").write_text(json.dumps(payload))
print(f"::notice::Diff: +{len(added)} ~{len(modified)} -{len(deleted)} files")
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
f.write("skip=false\n")
PY

- name: Call admin update-graph endpoint
if: steps.payload.outputs.skip != 'true'
run: |
curl -X POST "$GRAPHRAG_UI_URL/api/admin/update-graph" \
-H "Authorization: Bearer ${{ secrets.UPDATE_GRAPH_TOKEN }}" \
-H "Content-Type: application/json" \
--data-binary @payload.json \
--fail-with-body \
--show-error \
--max-time 1800

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed