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
+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