Skip to content
Open
Show file tree
Hide file tree
Changes from 7 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
6 changes: 3 additions & 3 deletions .github/actions/setup-test-env/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ runs:
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: 'npm'
cache-dependency-path: 'package-lock.json'
cache: 'yarn'
cache-dependency-path: 'yarn.lock'

- name: Install Node.js dependencies
shell: bash
run: |
echo "📦 Installing Node.js dependencies..."
npm ci
yarn install --frozen-lockfile
echo "✅ Node.js environment ready"
48 changes: 43 additions & 5 deletions .github/workflows/docs_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,24 @@ on:
# Only run when pushed to the testing-ci branch
branches:
- testing-ci
workflow_dispatch: # Manual trigger option
workflow_dispatch:
inputs:
python_client_branch:
description: 'Python client branch (leave empty to use pinned version from pyproject.toml)'
required: false
default: ''
typescript_client_branch:
description: 'TypeScript client branch (leave empty to use the workflow default below)'
required: false
default: ''
java_client_branch:
description: 'Java client branch (leave empty to use the workflow default below)'
required: false
default: ''
csharp_client_branch:
description: 'C# client branch (leave empty to use the workflow default below)'
required: false
default: ''

env:
# Centralize versions for easier maintenance
Expand Down Expand Up @@ -100,6 +117,13 @@ jobs:
with:
python-version: ${{ env.PYTHON_VERSION }}

- name: Override Python client branch
if: ${{ inputs.python_client_branch != '' }}
run: |
echo "📦 Installing weaviate-client from branch: ${{ inputs.python_client_branch }}"
uv pip install --reinstall "git+https://github.com/weaviate/weaviate-python-client.git@${{ inputs.python_client_branch }}"
echo "✅ Branch override installed"

- name: Start services
run: |
echo "🚀 Starting Weaviate and Ollama services..."
Expand Down Expand Up @@ -232,6 +256,18 @@ jobs:
with:
python-version: ${{ env.PYTHON_VERSION }}

- name: Override TypeScript client branch
run: |
TS_BRANCH="${{ inputs.typescript_client_branch || 'tokenization-updates' }}"
echo "📦 Building weaviate-client from branch: $TS_BRANCH"
git clone --depth 1 -b "$TS_BRANCH" https://github.com/weaviate/typescript-client.git /tmp/ts-client
cd /tmp/ts-client
npm install
npm run build
cd "$GITHUB_WORKSPACE"
yarn add "file:/tmp/ts-client"
echo "✅ Branch override installed"

- name: Start services
run: |
echo "🚀 Starting Weaviate and Ollama services..."
Expand Down Expand Up @@ -364,8 +400,9 @@ jobs:

- name: Clone and build Java client SNAPSHOT
run: |
echo "📦 Building Java client SNAPSHOT..."
git clone --depth 1 https://github.com/weaviate/java-client.git /tmp/java-client
JAVA_BRANCH="${{ inputs.java_client_branch || 'main' }}"
echo "📦 Building Java client SNAPSHOT from branch: $JAVA_BRANCH"
git clone --depth 1 -b "$JAVA_BRANCH" https://github.com/weaviate/java-client.git /tmp/java-client
cd /tmp/java-client
mvn install -DskipTests -Dmaven.javadoc.skip=true -q
echo "✅ Java client SNAPSHOT installed"
Expand Down Expand Up @@ -506,8 +543,9 @@ jobs:

- name: Clone C# client
run: |
echo "📦 Cloning C# client..."
git clone --depth 1 https://github.com/weaviate/csharp-client.git "${{ github.workspace }}/../csharp-client"
CSHARP_BRANCH="${{ inputs.csharp_client_branch || 'main' }}"
echo "📦 Cloning C# client from branch: $CSHARP_BRANCH"
git clone --depth 1 -b "$CSHARP_BRANCH" https://github.com/weaviate/csharp-client.git "${{ github.workspace }}/../csharp-client"
echo "✅ C# client cloned to $(realpath "${{ github.workspace }}/../csharp-client")"

- name: Start services
Expand Down
10 changes: 4 additions & 6 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -303,18 +303,16 @@ Before PR merge:
- **LLMs.txt plugin** - Generates LLM-friendly content dump
- **Mermaid** - Diagram support in markdown

## Package Managers
## Package Manager

This repo uses **two package managers** for different purposes:
This repo uses **yarn** for all Node dependencies — Docusaurus, the TypeScript code samples, and the test harness. There is a single `package.json` and a single `yarn.lock` at the repo root; no nested `package.json` files. CI installs with `yarn install --frozen-lockfile` (see `.github/actions/setup-test-env/action.yml`).

- **yarn** — for Docusaurus and all frontend dependencies (`package.json`). Always use `yarn install`, `yarn add`, etc. for Docusaurus packages. Never use `npm install` for Docusaurus dependencies — it creates a `package-lock.json` that conflicts with `yarn.lock`.
- **npm** — only for TypeScript test code execution (e.g., `npx tsx`).
Use `yarn install`, `yarn add`, etc. Never run `npm install` at the repo root — it generates a `package-lock.json` that drifts from `yarn.lock`. `npx tsx` is fine for running TS samples since it doesn't touch dependencies.

When adding or upgrading a Docusaurus dependency (e.g., `@scalar/docusaurus`), use:
When adding or upgrading a dependency (e.g., `@scalar/docusaurus`), use:
```bash
yarn add @scalar/docusaurus@latest
```
Not `npm install`.

## Environment Requirements

Expand Down
160 changes: 160 additions & 0 deletions _includes/code/csharp/ManageDataExportTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Weaviate.Client;
using Weaviate.Client.Models;
using Xunit;

namespace WeaviateProject.Tests;

public class ManageDataExportTest : IAsyncLifetime
{
private static readonly string[] COLLECTIONS = ["Articles", "Products", "TempData"];
private WeaviateClient client = null!;

public async Task InitializeAsync()
{
client = await Connect.Local();

foreach (var name in COLLECTIONS)
{
if (await client.Collections.Exists(name))
await client.Collections.Delete(name);

await client.Collections.Create(
new CollectionCreateParams
{
Name = name,
Properties = [Property.Text("title")],
}
);
var collection = client.Collections.Use(name);
await collection.Data.Insert(new { title = $"Test {name} object" });
}
}

public async Task DisposeAsync()
{
if (client != null)
{
foreach (var name in COLLECTIONS)
{
if (await client.Collections.Exists(name))
await client.Collections.Delete(name);
}
client.Dispose();
}
}

[Fact]
public async Task TestCreateExport()
{
// START CreateExport
// Export specific collections
var includeResult = await client.Export.CreateSync(
new ExportCreateRequest(
Id: "my-export-include",
Backend: ExportBackend.Filesystem(),
FileFormat: ExportFileFormat.Parquet,
IncludeCollections: ["Articles", "Products"]
),
timeout: TimeSpan.FromMinutes(2)
);

Console.WriteLine(includeResult.Status); // ExportStatus.Success
Console.WriteLine(string.Join(", ", includeResult.Collections ?? [])); // Articles, Products

// Or exclude specific collections (exports everything else)
var excludeResult = await client.Export.CreateSync(
new ExportCreateRequest(
Id: "my-export-exclude",
Backend: ExportBackend.Filesystem(),
FileFormat: ExportFileFormat.Parquet,
ExcludeCollections: ["TempData"]
),
timeout: TimeSpan.FromMinutes(2)
);
// END CreateExport

Assert.Equal(ExportStatus.Success, includeResult.Status);
Assert.Contains("Articles", includeResult.Collections!);
Assert.Contains("Products", includeResult.Collections!);

Assert.Equal(ExportStatus.Success, excludeResult.Status);
Assert.DoesNotContain("TempData", excludeResult.Collections!);
Assert.Contains("Articles", excludeResult.Collections!);
}

[Fact]
public async Task TestCreateExportAsyncAndStatus()
{
var asyncId = $"my-async-export-{Guid.NewGuid():N}".Substring(0, 28);

// START CreateExportAsync
await using var operation = await client.Export.Create(
new ExportCreateRequest(
Id: asyncId,
Backend: ExportBackend.Filesystem(),
FileFormat: ExportFileFormat.Parquet,
IncludeCollections: ["Articles"]
)
);

Console.WriteLine(operation.Current.Status); // Started or Transferring
// END CreateExportAsync

Assert.Contains(
operation.Current.Status,
new[] { ExportStatus.Started, ExportStatus.Transferring, ExportStatus.Success }
);

// START GetExportStatus
var status = await client.Export.GetStatus(
backend: ExportBackend.Filesystem(),
id: asyncId
);

Console.WriteLine(status.Status); // e.g. Transferring
Console.WriteLine(string.Join(", ", status.Collections ?? [])); // Articles
// status.ShardStatus has per-shard progress details (collection -> shard -> ShardProgress)
// END GetExportStatus

Assert.Equal(asyncId, status.Id);
Assert.Contains(
status.Status,
new[] { ExportStatus.Started, ExportStatus.Transferring, ExportStatus.Success }
);

// Wait for completion before the test ends so cleanup works.
await operation.WaitForCompletion(TimeSpan.FromMinutes(2));
}

[Fact]
public async Task TestCancelExport()
{
var cancelId = $"my-cancel-export-{Guid.NewGuid():N}".Substring(0, 28);

await using var operation = await client.Export.Create(
new ExportCreateRequest(
Id: cancelId,
Backend: ExportBackend.Filesystem(),
FileFormat: ExportFileFormat.Parquet,
IncludeCollections: ["Articles"]
)
);

// START CancelExport
await client.Export.Cancel(
backend: ExportBackend.Filesystem(),
id: cancelId
);
// END CancelExport

// Cancel may return false if the export already reached a terminal state on a small dataset.
var status = await client.Export.GetStatus(ExportBackend.Filesystem(), cancelId);
Assert.Contains(
status.Status,
new[] { ExportStatus.Canceled, ExportStatus.Success }
);
}
}
Loading
Loading