chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:08:54 +08:00
commit 4a4a1fed67
721 changed files with 262090 additions and 0 deletions
+163
View File
@@ -0,0 +1,163 @@
# Contributing to LightRAG
Thank you for your interest in contributing! This guide covers everything you need to get started.
## Table of Contents
- [Ways to Contribute](#ways-to-contribute)
- [Development Setup](#development-setup)
- [Code Style](#code-style)
- [Running Tests](#running-tests)
- [Submitting a Pull Request](#submitting-a-pull-request)
- [Reporting Bugs](#reporting-bugs)
- [Requesting Features](#requesting-features)
---
## Ways to Contribute
- **Bug reports** — open an [issue](https://github.com/HKUDS/LightRAG/issues) using the Bug Report template
- **Feature requests** — open an [issue](https://github.com/HKUDS/LightRAG/issues) using the Feature Request template
- **Documentation** — fix typos, clarify explanations, or add examples
- **Code** — fix bugs, implement features, or add storage/LLM backends
- **Testing** — add test coverage for untested code paths
---
## Development Setup
```bash
# Clone the repository
git clone https://github.com/HKUDS/LightRAG.git
cd LightRAG
# Install in development mode (requires uv)
uv sync
source .venv/bin/activate # Linux/macOS
# .venv\Scripts\activate # Windows
# Install with optional extras as needed
uv sync --extra api # FastAPI server
uv sync --extra test # Test dependencies
uv sync --extra offline-storage # Storage backends
uv sync --extra offline-llm # Additional LLM providers
# Set up pre-commit hooks (run once)
pip install pre-commit
pre-commit install
```
---
## Code Style
This project uses [Ruff](https://docs.astral.sh/ruff/) for formatting and linting, enforced via [pre-commit](https://pre-commit.com/).
### Automatic fixing
Running `pre-commit run --all-files` will automatically fix most style issues:
```bash
# Fix all files
pre-commit run --all-files
# Fix only staged files (faster during development)
pre-commit run
```
### What is checked
| Hook | What it does |
|------|-------------|
| `trailing-whitespace` | Removes trailing whitespace |
| `end-of-file-fixer` | Ensures files end with a newline |
| `requirements-txt-fixer` | Keeps `requirements.txt` entries sorted |
| `ruff-format` | Formats Python code (Black-compatible) |
| `ruff` | Fixes Python lint errors |
### CI check
The same checks run automatically on every pull request. If the CI check fails, run `pre-commit run --all-files` locally, commit the fixes, and push again.
### Language conventions
- **Python code and comments**: English
- **Frontend (WebUI)**: uses i18next for internationalization — add translation keys rather than hardcoding strings
---
## Running Tests
```bash
# Run offline tests (no external services required)
python -m pytest tests
# Run integration tests (requires configured external services)
python -m pytest tests --run-integration
# Run a specific test file
python -m pytest tests/chunker/test_chunking.py
# Keep test artifacts for debugging
python -m pytest tests --keep-artifacts
```
Set `LIGHTRAG_RUN_INTEGRATION=true` as an environment variable as an alternative to `--run-integration`.
---
## Submitting a Pull Request
1. **Fork** the repository and create a branch from `main`:
```bash
git checkout -b fix/your-descriptive-branch-name
```
2. **Make your changes** and ensure:
- Pre-commit checks pass: `pre-commit run --all-files`
- Relevant tests pass: `python -m pytest tests`
- New behavior is covered by tests where applicable
3. **Commit** with a clear message describing *why* the change was made:
```bash
git commit -m "fix: handle permission-only encrypted PDFs without password"
```
4. **Push** and open a pull request against `main`. Fill out the pull request template completely.
5. **Respond to review feedback** — a maintainer will review your PR and may request changes.
### Pull request checklist
- [ ] Changes tested locally
- [ ] Pre-commit checks pass (`pre-commit run --all-files`)
- [ ] Unit/integration tests added or updated where applicable
- [ ] Documentation updated if behavior changes
- [ ] PR description explains the *why*, not just the *what*
---
## Reporting Bugs
Please use the [Bug Report issue template](https://github.com/HKUDS/LightRAG/issues/new?template=bug_report.yml). Include:
- LightRAG version and Python version
- Storage backend and LLM provider being used
- Minimal reproducible example
- Full error traceback
---
## Requesting Features
Please use the [Feature Request issue template](https://github.com/HKUDS/LightRAG/issues/new?template=feature_request.yml). Describe:
- The problem you're trying to solve
- Your proposed solution
- Any alternatives you've considered
---
## Questions
For usage questions, check the [Discussions](https://github.com/HKUDS/LightRAG/discussions) tab or open a [Question issue](https://github.com/HKUDS/LightRAG/issues/new?template=question.yml).
+61
View File
@@ -0,0 +1,61 @@
name: Bug Report
description: File a bug report
title: "[Bug]:"
labels: ["bug", "triage"]
body:
- type: checkboxes
id: existingcheck
attributes:
label: Do you need to file an issue?
description: Please help us manage our time by avoiding duplicates and common bugs with the steps below.
options:
- label: I have searched the existing issues and this bug is not already filed.
- label: I believe this is a legitimate bug, not just a question or feature request.
- type: textarea
id: description
attributes:
label: Describe the bug
description: A clear and concise description of what the bug is.
placeholder: What went wrong?
- type: textarea
id: reproduce
attributes:
label: Steps to reproduce
description: Steps to reproduce the behavior.
placeholder: How can we replicate the issue?
- type: textarea
id: expected_behavior
attributes:
label: Expected Behavior
description: A clear and concise description of what you expected to happen.
placeholder: What should have happened?
- type: textarea
id: configused
attributes:
label: LightRAG Config Used
description: The LightRAG configuration used for the run.
placeholder: The settings content or LightRAG configuration
value: |
# Paste your config here
- type: textarea
id: screenshotslogs
attributes:
label: Logs and screenshots
description: If applicable, add screenshots and logs to help explain your problem.
placeholder: Add logs and screenshots here
- type: textarea
id: additional_information
attributes:
label: Additional Information
description: |
- LightRAG Version: e.g., v0.1.1
- Operating System: e.g., Windows 10, Ubuntu 20.04
- Python Version: e.g., 3.8
- Related Issues: e.g., #1
- Any other relevant information.
value: |
- LightRAG Version:
- Operating System:
- Python Version:
- Related Issues:
+1
View File
@@ -0,0 +1 @@
blank_issues_enabled: false
@@ -0,0 +1,26 @@
name: Feature Request
description: File a feature request
labels: ["enhancement"]
title: "[Feature Request]:"
body:
- type: checkboxes
id: existingcheck
attributes:
label: Do you need to file a feature request?
description: Please help us manage our time by avoiding duplicates and common feature request with the steps below.
options:
- label: I have searched the existing feature request and this feature request is not already filed.
- label: I believe this is a legitimate feature request, not just a question or bug.
- type: textarea
id: feature_request_description
attributes:
label: Feature Request Description
description: A clear and concise description of the feature request you would like.
placeholder: What this feature request add more or improve?
- type: textarea
id: additional_context
attributes:
label: Additional Context
description: Add any other context or screenshots about the feature request here.
placeholder: Any additional information
+26
View File
@@ -0,0 +1,26 @@
name: Question
description: Ask a general question
labels: ["question"]
title: "[Question]:"
body:
- type: checkboxes
id: existingcheck
attributes:
label: Do you need to ask a question?
description: Please help us manage our time by avoiding duplicates and common questions with the steps below.
options:
- label: I have searched the existing question and discussions and this question is not already answered.
- label: I believe this is a legitimate question, not just a bug or feature request.
- type: textarea
id: question
attributes:
label: Your Question
description: A clear and concise description of your question.
placeholder: What is your question?
- type: textarea
id: context
attributes:
label: Additional Context
description: Provide any additional context or details that might help us understand your question better.
placeholder: Add any relevant information here
+206
View File
@@ -0,0 +1,206 @@
# Keep GitHub Actions up to date with GitHub's Dependabot...
# https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot
# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#package-ecosystem
version: 2
updates:
# ============================================================
# GitHub Actions
# PR Strategy:
# - All updates (major/minor/patch): Grouped into a single PR
# ============================================================
- package-ecosystem: github-actions
directory: /
groups:
github-actions:
patterns:
- "*" # Group all Actions updates into a single larger pull request
schedule:
interval: weekly
day: monday
time: "02:00"
timezone: "Asia/Shanghai"
labels:
- "dependencies"
- "github-actions"
open-pull-requests-limit: 2
# ============================================================
# Python (pip) Dependencies
# PR Strategy:
# - Major updates: Individual PR per package (except numpy which is ignored)
# - Minor updates: Grouped by category (llm-providers, storage, etc.)
# - Patch updates: Grouped by category
# ============================================================
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
day: "wednesday"
time: "02:00"
timezone: "Asia/Shanghai"
cooldown:
default-days: 5
semver-major-days: 30
semver-minor-days: 7
semver-patch-days: 3
groups:
# Core dependencies - LLM providers and embeddings
llm-providers:
patterns:
- "openai"
- "anthropic"
- "google-*"
- "boto3"
- "botocore"
- "ollama"
update-types:
- "minor"
- "patch"
# Storage backends
storage:
patterns:
- "neo4j"
- "pymongo"
- "redis"
- "psycopg*"
- "asyncpg"
- "milvus*"
- "qdrant*"
update-types:
- "minor"
- "patch"
# Data processing and ML
data-processing:
patterns:
- "numpy"
- "scipy"
- "pandas"
- "tiktoken"
- "transformers"
- "torch*"
update-types:
- "minor"
- "patch"
# Web framework and API
web-framework:
patterns:
- "fastapi"
- "uvicorn"
- "gunicorn"
- "starlette"
- "pydantic*"
update-types:
- "minor"
- "patch"
# Development and testing tools
dev-tools:
patterns:
- "pytest*"
- "ruff"
- "pre-commit"
- "black"
- "mypy"
update-types:
- "minor"
- "patch"
# Minor and patch updates for everything else
python-minor-patch:
patterns:
- "*"
update-types:
- "minor"
- "patch"
ignore:
- dependency-name: "numpy"
update-types:
- "version-update:semver-major"
labels:
- "dependencies"
- "python"
open-pull-requests-limit: 5
# ============================================================
# Frontend (bun) Dependencies
# PR Strategy:
# - Major updates: Individual PR per package
# - Minor updates: Grouped by category (react, ui-components, etc.)
# - Patch updates: Grouped by category
# ============================================================
- package-ecosystem: "bun"
directory: "/lightrag_webui"
schedule:
interval: "weekly"
day: "friday"
time: "02:00"
timezone: "Asia/Shanghai"
cooldown:
default-days: 5
semver-major-days: 30
semver-minor-days: 7
semver-patch-days: 3
groups:
# React ecosystem
react:
patterns:
- "react"
- "react-dom"
- "react-router*"
- "@types/react*"
update-types:
- "minor"
- "patch"
# UI components and styling
ui-components:
patterns:
- "@radix-ui/*"
- "tailwind*"
- "@tailwindcss/*"
- "lucide-react"
- "class-variance-authority"
- "clsx"
update-types:
- "minor"
- "patch"
# Graph visualization
graph-viz:
patterns:
- "sigma"
- "@sigma/*"
- "graphology*"
update-types:
- "minor"
- "patch"
# Build tools and dev dependencies
build-tools:
patterns:
- "vite"
- "@vitejs/*"
- "typescript"
- "eslint*"
- "@eslint/*"
- "typescript-eslint"
- "prettier"
- "prettier-*"
- "@types/bun"
update-types:
- "minor"
- "patch"
# Content rendering libraries (math, diagrams, etc.)
content-rendering:
patterns:
- "katex"
- "mermaid"
update-types:
- "minor"
- "patch"
# All other minor and patch updates
frontend-minor-patch:
patterns:
- "*"
update-types:
- "minor"
- "patch"
labels:
- "dependencies"
- "frontend"
open-pull-requests-limit: 5
+32
View File
@@ -0,0 +1,32 @@
<!--
Thanks for contributing to LightRAG!
Please ensure your pull request is ready for review before submitting.
About this template
This template helps contributors provide a clear and concise description of their changes. Feel free to adjust it as needed.
-->
## Description
[Briefly describe the changes made in this pull request.]
## Related Issues
[Reference any related issues or tasks addressed by this pull request.]
## Changes Made
[List the specific changes made in this pull request.]
## Checklist
- [ ] Changes tested locally
- [ ] Code reviewed
- [ ] Documentation updated (if necessary)
- [ ] Unit tests added (if applicable)
## Additional Notes
[Add any additional notes or context for the reviewer(s).]
+58
View File
@@ -0,0 +1,58 @@
name: "Copilot Setup Steps"
# Automatically run the setup steps when they are changed to allow for easy validation, and
# allow manual testing through the repository's "Actions" tab
on:
workflow_dispatch:
push:
paths:
- .github/workflows/copilot-setup-steps.yml
pull_request:
paths:
- .github/workflows/copilot-setup-steps.yml
jobs:
# The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot.
copilot-setup-steps:
runs-on: ubuntu-latest
# Timeout after 30 minutes (maximum is 59)
timeout-minutes: 30
# You can define any steps you want, and they will run before the agent starts.
# If you do not check out your code, Copilot will do this for you.
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Set up Python 3.11
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Cache pip packages
uses: actions/cache@v6
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-copilot-${{ hashFiles('**/pyproject.toml') }}
restore-keys: |
${{ runner.os }}-pip-copilot-
${{ runner.os }}-pip-
- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[api]"
pip install pytest pytest-asyncio httpx2
- name: Create minimal frontend stub for Copilot agent
run: |
mkdir -p lightrag/api/webui
echo '<!DOCTYPE html><html><head><title>LightRAG - Copilot Agent</title></head><body><h1>Copilot Agent Mode</h1></body></html>' > lightrag/api/webui/index.html
echo "Created minimal frontend stub for Copilot agent environment"
- name: Verify installation
run: |
python --version
pip list | grep lightrag
lightrag-server --help || echo "Note: Server requires .env configuration to run"
+113
View File
@@ -0,0 +1,113 @@
name: Build Lite Docker Image
on:
workflow_dispatch:
inputs:
_notes_:
description: '⚠️ Create lite Docker images only after non-trivial version releases.'
required: false
type: boolean
default: false
permissions:
contents: read
id-token: write
packages: write
jobs:
build-and-push-lite:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.x"
- name: Get latest tag
id: get_tag
run: |
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
if [ -z "$LATEST_TAG" ]; then
LATEST_TAG="sha-$(git rev-parse --short HEAD)"
echo "No tags found, using commit SHA: $LATEST_TAG"
else
echo "Latest tag found: $LATEST_TAG"
fi
PACKAGE_VERSION="${LATEST_TAG#v}"
echo "tag=$LATEST_TAG" >> $GITHUB_OUTPUT
echo "package_version=$PACKAGE_VERSION" >> $GITHUB_OUTPUT
- name: Prepare lite tag
id: lite_tag
run: |
LITE_TAG="${{ steps.get_tag.outputs.tag }}-lite"
echo "Lite image tag: $LITE_TAG"
echo "lite_tag=$LITE_TAG" >> $GITHUB_OUTPUT
- name: Update version definitions
run: |
python scripts/release/set_version.py --core-version "${{ steps.get_tag.outputs.package_version }}"
grep '__version__ = ' lightrag/_version.py
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Login to GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Install cosign
uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
- name: Extract metadata for Docker
id: meta
uses: docker/metadata-action@v6
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=raw,value=${{ steps.lite_tag.outputs.lite_tag }}
type=raw,value=lite
- name: Build and push lite Docker image
id: build-and-push
uses: docker/build-push-action@v7
with:
context: .
file: ./Dockerfile.lite
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=min
- name: Sign lite Docker image
if: steps.build-and-push.outputs.digest != ''
env:
DIGEST: ${{ steps.build-and-push.outputs.digest }}
TAGS: ${{ steps.meta.outputs.tags }}
run: |
set -euo pipefail
echo "Signing manifest digest: $DIGEST"
while IFS= read -r tag; do
if [ -z "$tag" ]; then
continue
fi
echo "Signing ${tag}@${DIGEST}"
cosign sign --yes "${tag}@${DIGEST}"
done <<< "$TAGS"
- name: Output image details
run: |
echo "Lite Docker image built and pushed successfully!"
echo "Image tag: ghcr.io/${{ github.repository }}:${{ steps.lite_tag.outputs.lite_tag }}"
echo "Signed manifest digest: ${{ steps.build-and-push.outputs.digest }}"
echo "Base Git tag used: ${{ steps.get_tag.outputs.tag }}"
+109
View File
@@ -0,0 +1,109 @@
name: Build Test Docker Image manually
on:
workflow_dispatch:
inputs:
_notes_:
description: '⚠️ Please create a new git tag before building the docker image.'
required: false
type: boolean
default: false
permissions:
contents: read
id-token: write
packages: write
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v7
with:
fetch-depth: 0 # Fetch all history for tags
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.x"
- name: Get latest tag
id: get_tag
run: |
# Get the latest tag, fallback to commit SHA if no tags exist
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
if [ -z "$LATEST_TAG" ]; then
LATEST_TAG="sha-$(git rev-parse --short HEAD)"
echo "No tags found, using commit SHA: $LATEST_TAG"
else
echo "Latest tag found: $LATEST_TAG"
fi
PACKAGE_VERSION="${LATEST_TAG#v}"
echo "tag=$LATEST_TAG" >> $GITHUB_OUTPUT
echo "image_tag=$LATEST_TAG" >> $GITHUB_OUTPUT
echo "package_version=$PACKAGE_VERSION" >> $GITHUB_OUTPUT
- name: Update version definitions
run: |
python scripts/release/set_version.py --core-version "${{ steps.get_tag.outputs.package_version }}"
echo "Updated version definitions with ${{ steps.get_tag.outputs.package_version }}"
grep '__version__ = ' lightrag/_version.py
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Login to GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Install cosign
uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
- name: Extract metadata for Docker
id: meta
uses: docker/metadata-action@v6
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=raw,value=${{ steps.get_tag.outputs.tag }}
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@v7
with:
context: .
file: ./Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Sign Docker image
if: steps.build-and-push.outputs.digest != ''
env:
DIGEST: ${{ steps.build-and-push.outputs.digest }}
TAGS: ${{ steps.meta.outputs.tags }}
run: |
set -euo pipefail
echo "Signing manifest digest: $DIGEST"
while IFS= read -r tag; do
if [ -z "$tag" ]; then
continue
fi
echo "Signing ${tag}@${DIGEST}"
cosign sign --yes "${tag}@${DIGEST}"
done <<< "$TAGS"
- name: Output image details
run: |
echo "Docker image built and pushed successfully!"
echo "Image tags:"
echo " - ghcr.io/${{ github.repository }}:${{ steps.get_tag.outputs.tag }}"
echo "Signed manifest digest: ${{ steps.build-and-push.outputs.digest }}"
echo "Latest Git tag used: ${{ steps.get_tag.outputs.tag }}"
+120
View File
@@ -0,0 +1,120 @@
name: Build Latest Docker Image on Release
on:
release:
types: [published]
workflow_dispatch:
permissions:
contents: read
id-token: write
packages: write
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v7
with:
fetch-depth: 0 # Fetch all history for tags
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.x"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Login to GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Install cosign
uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
- name: Get latest tag
id: get_tag
run: |
if [ "${{ github.event_name }}" = "release" ] && [ -n "${{ github.event.release.tag_name }}" ]; then
TAG="${{ github.event.release.tag_name }}"
else
TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
fi
if [ -z "$TAG" ]; then
echo "No git tag found for docker publish"
exit 1
fi
PACKAGE_VERSION="${TAG#v}"
echo "Found tag: $TAG"
echo "tag=$TAG" >> $GITHUB_OUTPUT
echo "package_version=$PACKAGE_VERSION" >> $GITHUB_OUTPUT
- name: Check if pre-release
id: check_prerelease
run: |
TAG="${{ steps.get_tag.outputs.tag }}"
if [[ "$TAG" == *"rc"* ]] || [[ "$TAG" == *"dev"* ]]; then
echo "is_prerelease=true" >> $GITHUB_OUTPUT
echo "This is a pre-release version: $TAG"
else
echo "is_prerelease=false" >> $GITHUB_OUTPUT
echo "This is a stable release: $TAG"
fi
- name: Update version definitions
run: |
python scripts/release/set_version.py --core-version "${{ steps.get_tag.outputs.package_version }}"
echo "Updated version definitions with ${{ steps.get_tag.outputs.package_version }}"
grep '__version__ = ' lightrag/_version.py
- name: Extract metadata for Docker
id: meta
uses: docker/metadata-action@v6
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=raw,value=${{ steps.get_tag.outputs.tag }}
type=raw,value=latest,enable=${{ steps.check_prerelease.outputs.is_prerelease == 'false' }}
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@v7
with:
context: .
file: ./Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Sign Docker image
if: steps.build-and-push.outputs.digest != ''
env:
DIGEST: ${{ steps.build-and-push.outputs.digest }}
TAGS: ${{ steps.meta.outputs.tags }}
run: |
set -euo pipefail
echo "Signing manifest digest: $DIGEST"
while IFS= read -r tag; do
if [ -z "$tag" ]; then
continue
fi
echo "Signing ${tag}@${DIGEST}"
cosign sign --yes "${tag}@${DIGEST}"
done <<< "$TAGS"
- name: Output image details
run: |
echo "Docker image built and pushed successfully!"
echo "Image tags:"
echo " - ghcr.io/${{ github.repository }}:${{ steps.get_tag.outputs.tag }}"
echo " - ghcr.io/${{ github.repository }}:latest"
echo "Signed manifest digest: ${{ steps.build-and-push.outputs.digest }}"
echo "Latest Git tag used: ${{ steps.get_tag.outputs.tag }}"
+134
View File
@@ -0,0 +1,134 @@
name: Linting and Formatting
on:
push:
branches: [ main, dev ]
pull_request:
branches: [ main, dev ]
types: [opened, synchronize, reopened, ready_for_review]
permissions:
pull-requests: write
jobs:
lint-and-format:
name: Linting and Formatting
if: ${{ github.event_name != 'pull_request' || !github.event.pull_request.draft }}
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pre-commit
- name: Run pre-commit
id: pre-commit
run: pre-commit run --all-files --show-diff-on-failure
- name: Post fix instructions on failure
if: failure() && steps.pre-commit.outcome == 'failure'
run: |
cat >> "$GITHUB_STEP_SUMMARY" << 'EOF'
## ❌ Linting / Formatting checks failed
Pre-commit found issues in your code. Fix them locally and push again:
```bash
# Install pre-commit (one-time setup)
pip install pre-commit
pre-commit install
# Auto-fix all issues
pre-commit run --all-files
# Commit the fixes
git add -u
git commit -m "fix: apply pre-commit formatting fixes"
git push
```
### What was checked
| Hook | Tool | What it fixes |
|------|------|---------------|
| `trailing-whitespace` | pre-commit-hooks | Removes trailing whitespace |
| `end-of-file-fixer` | pre-commit-hooks | Ensures files end with a newline |
| `requirements-txt-fixer` | pre-commit-hooks | Sorts requirements.txt entries |
| `ruff-format` | Ruff | Auto-formats Python code (like Black) |
| `ruff` | Ruff | Fixes Python lint errors (`--fix`) |
> See the diff above for the exact changes needed.
EOF
- name: Comment on PR with fix instructions
if: failure() && steps.pre-commit.outcome == 'failure' && github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
uses: actions/github-script@v9
with:
script: |
const body = `## ❌ Linting / Formatting checks failed
Pre-commit found issues in your code. Run the following locally, then push again:
\`\`\`bash
# Install pre-commit (one-time setup)
pip install pre-commit
pre-commit install
# Auto-fix all issues
pre-commit run --all-files
# Commit the fixes
git add -u
git commit -m "fix: apply pre-commit formatting fixes"
git push
\`\`\`
<details>
<summary>What was checked</summary>
| Hook | Tool | What it fixes |
|------|------|---------------|
| \`trailing-whitespace\` | pre-commit-hooks | Removes trailing whitespace |
| \`end-of-file-fixer\` | pre-commit-hooks | Ensures files end with a newline |
| \`requirements-txt-fixer\` | pre-commit-hooks | Sorts requirements.txt entries |
| \`ruff-format\` | Ruff | Auto-formats Python code (like Black) |
| \`ruff\` | Ruff | Fixes Python lint errors (\`--fix\`) |
</details>
> See the [workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for the exact diff of required changes.`;
// Find existing bot comment to avoid duplicates
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Linting / Formatting checks failed')
);
if (existing) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existing.id,
body,
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body,
});
}
+101
View File
@@ -0,0 +1,101 @@
name: Upload LightRAG-hku Package
on:
release:
types: [published]
workflow_dispatch:
permissions:
contents: read
jobs:
release-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0 # Fetch all history for tags
# Build frontend WebUI
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Build Frontend WebUI
run: |
cd lightrag_webui
bun install --frozen-lockfile
bun run build
cd ..
- name: Verify Frontend Build
run: |
if [ ! -f "lightrag/api/webui/index.html" ]; then
echo "❌ Error: Frontend build failed - index.html not found"
exit 1
fi
echo "✅ Frontend build verified"
echo "Frontend files:"
ls -lh lightrag/api/webui/ | head -10
- uses: actions/setup-python@v6
with:
python-version: "3.x"
- name: Resolve release version
id: get_version
run: |
if [ "${{ github.event_name }}" = "release" ] && [ -n "${{ github.event.release.tag_name }}" ]; then
TAG="${{ github.event.release.tag_name }}"
else
TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
fi
if [ -z "$TAG" ]; then
echo "No git tag found for release build"
exit 1
fi
PACKAGE_VERSION="${TAG#v}"
echo "Found tag: $TAG"
echo "Package version: $PACKAGE_VERSION"
echo "version=$TAG" >> $GITHUB_OUTPUT
echo "package_version=$PACKAGE_VERSION" >> $GITHUB_OUTPUT
- name: Update version definitions
run: |
python scripts/release/set_version.py --core-version "${{ steps.get_version.outputs.package_version }}"
grep '__version__ = ' lightrag/_version.py
- name: Build release distributions
run: |
python -m pip install build
python -m build
- name: Upload distributions
uses: actions/upload-artifact@v7
with:
name: release-dists
path: dist/
pypi-publish:
runs-on: ubuntu-latest
needs:
- release-build
permissions:
id-token: write
environment:
name: pypi
steps:
- name: Retrieve release distributions
uses: actions/download-artifact@v8
with:
name: release-dists
path: dist/
- name: Publish release distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: dist/
+27
View File
@@ -0,0 +1,27 @@
# .github/workflows/stale.yml
name: Mark stale issues and pull requests
on:
schedule:
- cron: '30 22 * * *' # run at 22:30+08 every day
permissions:
issues: write
pull-requests: write
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v10
with:
days-before-stale: 90 # 90 days
days-before-close: 7 # 7 days after marked as stale
stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
close-issue-message: 'This issue has been automatically closed because it has not had recent activity. Please open a new issue if you still have this problem.'
stale-pr-message: 'This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.'
close-pr-message: 'This pull request has been automatically closed because it has not had recent activity.'
# If there are specific labels, exempt them from being marked as stale, for example:
exempt-issue-labels: 'enhancement,tracked'
# exempt-pr-labels: 'bug,enhancement,help wanted'
repo-token: ${{ secrets.GITHUB_TOKEN }} # token provided by GitHub
+61
View File
@@ -0,0 +1,61 @@
name: Offline Unit Tests
on:
push:
branches: [ main, dev ]
pull_request:
branches: [ main, dev ]
types: [opened, synchronize, reopened, ready_for_review]
jobs:
offline-tests:
name: Offline Tests
if: ${{ github.event_name != 'pull_request' || !github.event.pull_request.draft }}
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.12', '3.14']
steps:
- uses: actions/checkout@v7
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Cache pip packages
uses: actions/cache@v6
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt', '**/pyproject.toml') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Install dependencies
run: |
python -m pip install --upgrade pip
# Install optional-storage and optional-llm deps too — the offline
# test suite contains mock-based unit tests that construct real
# data classes from these libraries (qdrant-client, pymongo,
# anthropic, boto3, etc.). Without them, importorskip falls back
# and the tests are silently skipped.
pip install -e ".[api,offline-storage,offline-llm]"
pip install pytest pytest-asyncio httpx2
- name: Run offline tests
run: |
# Run only tests marked as 'offline' (no external dependencies)
# Integration tests requiring databases/APIs are skipped by default
pytest tests/ -m offline -v --tb=short
- name: Upload test results
if: always()
uses: actions/upload-artifact@v7
with:
name: test-results-py${{ matrix.python-version }}
path: |
.pytest_cache/
test-results.xml
retention-days: 7