chore: import upstream snapshot with attribution
CI / Run CI (push) Has been cancelled
CI / check-backend (push) Has been cancelled
CI / check-frontend (push) Has been cancelled
CI / tests (push) Has been cancelled
CI / e2e-tests (push) Has been cancelled
Copilot Setup Steps / copilot-setup-steps (push) Has been cancelled
CI / Run CI (push) Has been cancelled
CI / check-backend (push) Has been cancelled
CI / check-frontend (push) Has been cancelled
CI / tests (push) Has been cancelled
CI / e2e-tests (push) Has been cancelled
Copilot Setup Steps / copilot-setup-steps (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1 @@
|
||||
* @hayescode @asvishnyakov @sandangel
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: needs-triage
|
||||
assignees: ''
|
||||
type: 'Bug'
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Smartphone (please complete the following information):**
|
||||
|
||||
- Device: [e.g. iPhone6]
|
||||
- OS: [e.g. iOS8.1]
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: needs-triage
|
||||
assignees: ''
|
||||
type: 'Feature'
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
@@ -0,0 +1,26 @@
|
||||
name: Install Node, pnpm and dependencies.
|
||||
description: Install Node, pnpm and dependencies using cache.
|
||||
|
||||
inputs:
|
||||
node-version:
|
||||
description: Node.js version
|
||||
required: true
|
||||
default: 'lts/*'
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- uses: pnpm/action-setup@v5.0.0
|
||||
name: Install pnpm
|
||||
with:
|
||||
run_install: false
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v6.3.0
|
||||
with:
|
||||
node-version: ${{ inputs.node-version }}
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
cache: 'pnpm'
|
||||
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||
- name: Install JS dependencies
|
||||
run: pnpm install
|
||||
shell: bash
|
||||
@@ -0,0 +1,37 @@
|
||||
name: Install Python, uv and dependencies.
|
||||
description: Install Python, uv and project dependencies using cache
|
||||
|
||||
inputs:
|
||||
python-version:
|
||||
description: Python version
|
||||
required: true
|
||||
default: '3.10'
|
||||
uv-version:
|
||||
description: uv version
|
||||
required: true
|
||||
default: 'latest'
|
||||
uv-args:
|
||||
description: Extra uv args, for example dependencies to install, e.g. --extra tests --extra dev.
|
||||
required: false
|
||||
working-directory:
|
||||
description: Working directory for uv command.
|
||||
required: false
|
||||
default: .
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v8.0.0
|
||||
with:
|
||||
version: ${{ inputs.uv-version }}
|
||||
enable-cache: true
|
||||
- name: Set up Python ${{ inputs.python-version }}
|
||||
id: setup_python
|
||||
uses: actions/setup-python@v6.2.0
|
||||
with:
|
||||
python-version: ${{ inputs.python-version }}
|
||||
- name: Install Python dependencies
|
||||
run: uv sync --all-packages ${{ inputs.uv-args }}
|
||||
shell: bash
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
@@ -0,0 +1,194 @@
|
||||
# Chainlit Development Instructions
|
||||
|
||||
Chainlit is a Python framework for building conversational AI applications with Python backend and React frontend. It uses uv for Python dependency management and pnpm for Node.js packages.
|
||||
|
||||
Always reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.
|
||||
|
||||
## Working Effectively
|
||||
|
||||
### Bootstrap, Build, and Test the Repository
|
||||
|
||||
**CRITICAL**: All commands must complete - NEVER CANCEL any build or test operations. Use appropriate timeouts.
|
||||
|
||||
1. **Install Dependencies (Required first)**:
|
||||
|
||||
```bash
|
||||
# Install uv (if not available)
|
||||
python3 -m pip install pipx
|
||||
python3 -m pipx install uv
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
|
||||
# Install pnpm (if not available)
|
||||
npm install -g pnpm
|
||||
|
||||
# Install Python dependencies - takes ~2 minutes, NEVER CANCEL
|
||||
cd backend
|
||||
uv sync --extra tests --extra mypy --extra dev --extra custom-data
|
||||
# Timeout: Use 300+ seconds (5+ minutes)
|
||||
|
||||
# Install Node.js dependencies - takes ~3 minutes, NEVER CANCEL
|
||||
cd ..
|
||||
pnpm install --frozen-lockfile
|
||||
# Timeout: Use 600+ seconds (10+ minutes)
|
||||
# NOTE: Cypress download may fail due to network restrictions - this is expected in CI environments
|
||||
```
|
||||
|
||||
2. **Run Tests**:
|
||||
|
||||
```bash
|
||||
# Backend tests - takes ~17 seconds, NEVER CANCEL
|
||||
cd backend
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
uv run pytest --cov=chainlit/
|
||||
# Timeout: Use 120+ seconds (2+ minutes)
|
||||
|
||||
# Frontend tests - takes ~4 seconds
|
||||
cd ../frontend
|
||||
pnpm test
|
||||
# Timeout: Use 60 seconds
|
||||
|
||||
# E2E tests require Cypress download - may not work in restricted environments
|
||||
# If available: pnpm test:e2e (takes variable time depending on tests)
|
||||
```
|
||||
|
||||
3. **Run Development Servers**:
|
||||
|
||||
```bash
|
||||
# Start backend (in one terminal)
|
||||
cd backend
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
uv run chainlit run chainlit/sample/hello.py -h
|
||||
# Available at http://localhost:8000
|
||||
|
||||
# Start frontend dev server (in another terminal)
|
||||
cd frontend
|
||||
pnpm run dev
|
||||
# Available at http://localhost:5173/
|
||||
```
|
||||
|
||||
## Validation
|
||||
|
||||
### Manual Validation Requirements
|
||||
|
||||
- **ALWAYS** manually validate any changes by running complete scenarios.
|
||||
- **ALWAYS** test the Chainlit application after making changes.
|
||||
- Create a test app and verify it runs: `uv run chainlit run /path/to/test.py -h`
|
||||
- **ALWAYS** run through at least one complete user workflow after making changes.
|
||||
|
||||
### Linting and Formatting - takes ~2 minutes, NEVER CANCEL
|
||||
|
||||
```bash
|
||||
# Lint (check)
|
||||
pnpm lint
|
||||
# Timeout: Use 300+ seconds (5+ minutes)
|
||||
|
||||
# Lint (auto-fix)
|
||||
pnpm lint:fix
|
||||
|
||||
# Check formatting
|
||||
pnpm format-check
|
||||
|
||||
# Fix formatting
|
||||
pnpm format
|
||||
|
||||
# Python (scripts/ wrappers around ruff and mypy)
|
||||
uv run scripts/lint.py
|
||||
uv run scripts/format.py
|
||||
uv run scripts/format.py --check
|
||||
```
|
||||
|
||||
### CI Requirements
|
||||
|
||||
- **ALWAYS** run `pnpm lint` and `pnpm format-check` before committing or the CI (.github/workflows/ci.yaml) will fail.
|
||||
- The CI runs: pytest, lint-backend, lint-ui, and e2e-tests.
|
||||
- **NEVER CANCEL** any CI commands - they take time but must complete.
|
||||
|
||||
## Key Project Structure
|
||||
|
||||
### Repository Root
|
||||
|
||||
```
|
||||
/
|
||||
├── README.md
|
||||
├── CONTRIBUTING.md
|
||||
├── package.json # Root pnpm workspace config
|
||||
├── pnpm-workspace.yaml # Workspace definition
|
||||
├── backend/ # Python backend with uv
|
||||
├── frontend/ # React frontend app
|
||||
├── libs/
|
||||
│ ├── react-client/ # React client library
|
||||
│ └── copilot/ # Copilot functionality
|
||||
├── cypress/ # E2E tests
|
||||
└── .github/
|
||||
├── workflows/ # CI/CD pipelines
|
||||
└── actions/ # Reusable GitHub actions
|
||||
```
|
||||
|
||||
### Working with the Backend
|
||||
|
||||
- **Technology**: Python 3.10+ with uv, FastAPI, SocketIO
|
||||
- **Entry point**: `backend/chainlit/`
|
||||
- **Tests**: `backend/tests/`
|
||||
- **Dependencies**: Defined in `backend/pyproject.toml`
|
||||
- **Hello app**: `backend/chainlit/sample/hello.py`
|
||||
|
||||
### Working with the Frontend
|
||||
|
||||
- **Technology**: React 18+ with Vite, TypeScript, Tailwind CSS
|
||||
- **Entry point**: `frontend/src/`
|
||||
- **Dependencies**: Defined in `frontend/package.json`
|
||||
- **Build output**: `frontend/dist/`
|
||||
|
||||
## Common Tasks
|
||||
|
||||
### Creating a New Chainlit App
|
||||
|
||||
```python
|
||||
# Create app.py
|
||||
import chainlit as cl
|
||||
|
||||
@cl.on_message
|
||||
async def main(message: cl.Message):
|
||||
await cl.Message(content=f"You said: {message.content}").send()
|
||||
|
||||
# Run it
|
||||
uv run chainlit run app.py -w
|
||||
```
|
||||
|
||||
### Timing Expectations
|
||||
|
||||
- **pnpm install**: ~3 minutes (may fail on Cypress - this is normal)
|
||||
- **uv install**: ~2 minutes
|
||||
- **pnpm build**: ~1 minute
|
||||
- **pnpm run lint**: ~2 minutes
|
||||
- **Backend tests**: ~17 seconds
|
||||
- **Frontend tests**: ~4 seconds
|
||||
- **pnpm format-check**: ~12 seconds
|
||||
- **pnpm format**: ~12 seconds
|
||||
|
||||
### Common Gotchas
|
||||
|
||||
- **NEVER CANCEL** long-running operations - they need time to complete.
|
||||
- Cypress download often fails in CI environments - this is expected.
|
||||
- Use `uv run` prefix for all Python commands in backend.
|
||||
- Use `export PATH="$HOME/.local/bin:$PATH"` to ensure uv is available.
|
||||
- Python lint/format/type-check: use `uv run scripts/lint.py`, `uv run scripts/format.py`, `uv run scripts/type_check.py` from repo root.
|
||||
- Frontend dev server connects to backend at localhost:8000.
|
||||
- Always start backend before frontend for development.
|
||||
|
||||
### File Locations for Quick Reference
|
||||
|
||||
- **Main CLI**: `backend/chainlit/cli/`
|
||||
- **Server code**: `backend/chainlit/server.py`
|
||||
- **Frontend app**: `frontend/src/App.tsx`
|
||||
- **React client**: `libs/react-client/src/`
|
||||
- **CI workflows**: `.github/workflows/ci.yaml`
|
||||
- **uv config**: `backend/pyproject.toml`
|
||||
- **Frontend config**: `frontend/package.json`
|
||||
|
||||
## Requirements
|
||||
|
||||
- **Python**: >= 3.10
|
||||
- **Node.js**: >= 20 (24+ recommended)
|
||||
- **uv**: 2.1.3 (install via pipx)
|
||||
- **pnpm**: Latest (install via npm)
|
||||
@@ -0,0 +1,29 @@
|
||||
name: Check backend
|
||||
|
||||
on: [workflow_call]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
check-backend:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: 'Linting: backend'
|
||||
command: uv run --no-project scripts/lint.py
|
||||
- name: 'Formatting: backend'
|
||||
command: uv run --no-project scripts/format.py --check
|
||||
- name: 'Type checking: backend'
|
||||
command: uv run --no-project scripts/type_check.py
|
||||
name: ${{ matrix.name }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: ./.github/actions/uv-python-install
|
||||
name: Install Python, uv and Python dependencies
|
||||
with:
|
||||
uv-args: --no-install-workspace --all-extras --dev
|
||||
- name: ${{ matrix.name }}
|
||||
run: ${{ matrix.command }}
|
||||
@@ -0,0 +1,29 @@
|
||||
name: Check frontend & libs
|
||||
|
||||
on: [workflow_call]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
check-frontend:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: 'Linting: frontend'
|
||||
command: pnpm lint
|
||||
- name: 'Formatting: frontend'
|
||||
command: pnpm format-check
|
||||
- name: 'Type checking: frontend'
|
||||
command: pnpm type-check
|
||||
name: ${{ matrix.name }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: ./.github/actions/pnpm-node-install
|
||||
name: Install Node, pnpm and dependencies.
|
||||
- name: Build @chainlit/react-client
|
||||
run: pnpm --filter @chainlit/react-client build
|
||||
- name: ${{ matrix.name }}
|
||||
run: ${{ matrix.command }}
|
||||
@@ -0,0 +1,42 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
workflow_dispatch:
|
||||
merge_group:
|
||||
pull_request:
|
||||
branches: [main, dev, 'release/**']
|
||||
push:
|
||||
branches: [main, dev, 'release/**']
|
||||
|
||||
concurrency:
|
||||
group: ci-${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: ${{ github.ref_name != 'main' }}
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
check-backend:
|
||||
uses: ./.github/workflows/check-backend.yaml
|
||||
secrets: inherit
|
||||
check-frontend:
|
||||
uses: ./.github/workflows/check-frontend.yaml
|
||||
secrets: inherit
|
||||
tests:
|
||||
uses: ./.github/workflows/tests.yaml
|
||||
secrets: inherit
|
||||
e2e-tests:
|
||||
uses: ./.github/workflows/e2e-tests.yaml
|
||||
secrets: inherit
|
||||
ci:
|
||||
runs-on: ubuntu-slim
|
||||
name: Run CI
|
||||
if: always() # This ensures the job always runs
|
||||
needs: [check-backend, check-frontend, tests, e2e-tests]
|
||||
steps:
|
||||
# Propagate failure
|
||||
- name: Check dependent jobs
|
||||
if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'action_required') || contains(needs.*.result, 'timed_out')
|
||||
run: |
|
||||
echo "Not all required jobs succeeded"
|
||||
exit 1
|
||||
@@ -0,0 +1,30 @@
|
||||
name: Close inactive issues and pull requests
|
||||
on:
|
||||
schedule:
|
||||
- cron: '30 1 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
close-issues:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
operations-per-run: 400
|
||||
ascending: true
|
||||
days-before-issue-stale: 14
|
||||
days-before-issue-close: 7
|
||||
stale-issue-label: 'stale'
|
||||
exempt-issue-labels: 'enhancement,dev-tooling,e2e-tests,unit-tests,keep-for-a-while'
|
||||
stale-issue-message: 'This issue is stale because it has been open for 14 days with no activity.'
|
||||
close-issue-message: 'This issue was closed because it has been inactive for 7 days since being marked as stale.'
|
||||
days-before-pr-stale: 14
|
||||
days-before-pr-close: 7
|
||||
stale-pr-label: 'stale'
|
||||
exempt-pr-labels: 'enhancement,dev-tooling,e2e-tests,unit-tests,keep-for-a-while'
|
||||
stale-pr-message: 'This PR is stale because it has been open for 14 days with no activity.'
|
||||
close-pr-message: 'This PR was closed because it has been inactive for 7 days since being marked as stale.'
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -0,0 +1,41 @@
|
||||
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
|
||||
# This workflow optimizes the GitHub Copilot coding agent's ephemeral development environment
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- .github/workflows/copilot-setup-steps.yaml
|
||||
pull_request:
|
||||
paths:
|
||||
- .github/workflows/copilot-setup-steps.yaml
|
||||
|
||||
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-minutes: 15
|
||||
|
||||
# Set the permissions to the lowest permissions possible needed for your steps.
|
||||
# Copilot will be given its own token for its operations.
|
||||
permissions:
|
||||
# If you want to clone the repository as part of your setup steps, for example to install dependencies, you'll need the `contents: read` permission. If you don't clone the repository in your setup steps, Copilot will do this for you automatically after the steps complete.
|
||||
contents: read
|
||||
|
||||
# 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@v6
|
||||
|
||||
- name: Install Node.js, pnpm and dependencies
|
||||
uses: ./.github/actions/pnpm-node-install
|
||||
|
||||
- name: Install Python, uv and dependencies
|
||||
uses: ./.github/actions/uv-python-install
|
||||
with:
|
||||
python-version: '3.10'
|
||||
uv-version: 'latest'
|
||||
uv-args: '--all-extras --dev'
|
||||
@@ -0,0 +1,72 @@
|
||||
name: E2E tests
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
e2e_parallel_shards:
|
||||
description: Number of parallel E2E shards per OS.
|
||||
type: number
|
||||
default: 5
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
prepare:
|
||||
name: Validate inputs and compute shard matrix
|
||||
runs-on: ubuntu-slim
|
||||
outputs:
|
||||
indexes: ${{ steps.shard-indexes.outputs.indexes }}
|
||||
steps:
|
||||
- name: Validate e2e_parallel_shards
|
||||
run: |
|
||||
n="${{ inputs.e2e_parallel_shards }}"
|
||||
if ! [[ "$n" =~ ^[0-9]+$ ]] || [[ "$n" -lt 1 ]]; then
|
||||
echo "❌ Error: e2e_parallel_shards must be at least 1, got: $n"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ Validation passed"
|
||||
- id: shard-indexes
|
||||
name: Compute shard indexes
|
||||
run: |
|
||||
json=$(jq -nc --argjson n "${{ inputs.e2e_parallel_shards }}" '[range(1; $n + 1)]')
|
||||
echo "indexes=$json" >> "$GITHUB_OUTPUT"
|
||||
|
||||
e2e-tests:
|
||||
needs: prepare
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
containers: ${{ fromJSON(needs.prepare.outputs.indexes) }}
|
||||
name: ${{ matrix.os }}-${{ matrix.containers }}
|
||||
env:
|
||||
BACKEND_DIR: ./backend
|
||||
# Single path for actions/cache on Linux + Windows (default Cypress dirs differ by OS).
|
||||
CYPRESS_CACHE_FOLDER: ${{ github.workspace }}/.cypress-cache
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Cache Cypress binary
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: .cypress-cache
|
||||
key: cypress-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
- uses: ./.github/actions/pnpm-node-install
|
||||
name: Install Node, pnpm and dependencies.
|
||||
- uses: ./.github/actions/uv-python-install
|
||||
name: Install Python, uv and Python & pnpm (uv does it automatically) dependencies
|
||||
with:
|
||||
working-directory: ${{ env.BACKEND_DIR }}
|
||||
uv-args: --extra tests
|
||||
- name: Run tests
|
||||
env:
|
||||
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
|
||||
SPLIT: ${{ inputs.e2e_parallel_shards }}
|
||||
SPLIT_INDEX1: ${{ matrix.containers }}
|
||||
run: pnpm test:e2e
|
||||
shell: bash
|
||||
- name: Upload screenshots
|
||||
uses: actions/upload-artifact@v7
|
||||
if: always() && hashFiles('cypress/screenshots/**') != ''
|
||||
with:
|
||||
name: cypress-screenshots-${{ matrix.os }}-${{ matrix.containers }}
|
||||
path: cypress/screenshots
|
||||
@@ -0,0 +1,52 @@
|
||||
name: Publish libs
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
dry_run:
|
||||
description: 'Dry run (test publishing)'
|
||||
required: false
|
||||
default: false
|
||||
type: boolean
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
name: Validate inputs
|
||||
runs-on: ubuntu-slim
|
||||
steps:
|
||||
- name: Validate publishing branch and destination package index
|
||||
run: |
|
||||
if [[ "${{ github.ref_name }}" != "main" && "${{ github.event_name }}" != "release" ]]; then
|
||||
if [[ "${{ inputs.dry_run }}" != "true" ]]; then
|
||||
echo "❌ Error: Only build from main branch or release tag can be published to npm registry."
|
||||
echo "Please check 'Dry run (test publishing)' when running from branch: ${{ github.ref_name }}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
echo "✅ Validation passed"
|
||||
ci:
|
||||
needs: [validate]
|
||||
uses: ./.github/workflows/ci.yaml
|
||||
secrets: inherit
|
||||
build-n-publish:
|
||||
name: Upload libs release to npm registry
|
||||
runs-on: ubuntu-latest
|
||||
needs: [ci]
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: ./.github/actions/pnpm-node-install
|
||||
name: Install Node, pnpm and dependencies.
|
||||
|
||||
- name: Build react-client
|
||||
run: pnpm --filter @chainlit/react-client build
|
||||
|
||||
- name: Publish packages to npm
|
||||
# --no-git-checks allows testing from non-main branches and publishing from release tags
|
||||
run: pnpm publish --recursive --no-git-checks ${{ inputs.dry_run && '--dry-run' || '' }}
|
||||
@@ -0,0 +1,80 @@
|
||||
name: Publish
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
use_testpypi:
|
||||
description: 'Publish to TestPyPI instead of PyPI'
|
||||
required: false
|
||||
default: false
|
||||
type: boolean
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
name: Validate inputs
|
||||
runs-on: ubuntu-slim
|
||||
steps:
|
||||
- name: Validate publishing branch and destination package index
|
||||
run: |
|
||||
if [[ "${{ github.ref_name }}" != "main" && "${{ github.event_name }}" != "release" ]]; then
|
||||
if [[ "${{ inputs.use_testpypi }}" != "true" ]]; then
|
||||
echo "❌ Error: Only build from main branch or release tag can be published to PyPI."
|
||||
echo "Please check 'Publish to TestPyPI instead of PyPI' when running from branch: ${{ github.ref_name }}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
echo "✅ Validation passed"
|
||||
ci:
|
||||
needs: [validate]
|
||||
uses: ./.github/workflows/ci.yaml
|
||||
secrets: inherit
|
||||
build-n-publish:
|
||||
name: Upload release to PyPI/TestPyPI
|
||||
runs-on: ubuntu-latest
|
||||
needs: [ci]
|
||||
env:
|
||||
name: ${{ inputs.use_testpypi && 'testpypi' || 'pypi' }}
|
||||
url: ${{ inputs.use_testpypi && 'https://test.pypi.org/project/chainlit' || 'https://pypi.org/project/chainlit' }}
|
||||
BACKEND_DIR: ./backend
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: ./.github/actions/pnpm-node-install
|
||||
name: Install Node, pnpm and dependencies.
|
||||
- uses: ./.github/actions/uv-python-install
|
||||
name: Install Python, uv and Python dependencies
|
||||
with:
|
||||
working-directory: ${{ env.BACKEND_DIR }}
|
||||
|
||||
- name: Build Python distribution
|
||||
run: uv build
|
||||
working-directory: ${{ env.BACKEND_DIR }}
|
||||
|
||||
- name: Check frontend and copilot folder included
|
||||
run: |
|
||||
pip install wheel
|
||||
python -m wheel unpack dist/chainlit-*.whl -d unpacked
|
||||
ls unpacked/chainlit-*/chainlit/frontend/dist
|
||||
ls unpacked/chainlit-*/chainlit/copilot/dist
|
||||
|
||||
- name: Publish package distributions to TestPyPI
|
||||
if: inputs.use_testpypi
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
packages-dir: dist
|
||||
repository-url: https://test.pypi.org/legacy/
|
||||
password: ${{ secrets.TEST_PYPI_API_TOKEN }}
|
||||
verbose: true
|
||||
|
||||
- name: Publish package distributions to PyPI
|
||||
if: ${{ !inputs.use_testpypi }}
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
packages-dir: dist
|
||||
password: ${{ secrets.PYPI_API_TOKEN }}
|
||||
@@ -0,0 +1,28 @@
|
||||
name: Unit & integration tests
|
||||
|
||||
on: [workflow_call]
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.10', '3.11', '3.12', '3.13']
|
||||
name: python ${{ matrix.python-version }}
|
||||
env:
|
||||
BACKEND_DIR: ./backend
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: ./.github/actions/pnpm-node-install
|
||||
name: Install Node, pnpm and dependencies.
|
||||
- uses: ./.github/actions/uv-python-install
|
||||
name: Install Python, uv and Python dependencies
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
uv-args: --extra tests --extra custom-data
|
||||
- name: Run backend tests
|
||||
run: uv run --no-project pytest --cov=chainlit/
|
||||
- name: Run frontend tests
|
||||
run: pnpm run test
|
||||
Reference in New Issue
Block a user