robotframework-chat 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- robotframework_chat-1.0.0/.env.example +50 -0
- robotframework_chat-1.0.0/.env.remote.example +34 -0
- robotframework_chat-1.0.0/.gitattributes +5 -0
- robotframework_chat-1.0.0/.github/workflows/mirror-staging-to-gitlab.yml +46 -0
- robotframework_chat-1.0.0/.github/workflows/pypi-publish.yml +67 -0
- robotframework_chat-1.0.0/.github/workflows/robot-tests.yml +86 -0
- robotframework_chat-1.0.0/.github/workflows/sync-from-gitlab.yml +88 -0
- robotframework_chat-1.0.0/.github/workflows/sync-to-gitlab.yml +73 -0
- robotframework_chat-1.0.0/.gitignore +68 -0
- robotframework_chat-1.0.0/.gitlab-ci.yml +152 -0
- robotframework_chat-1.0.0/.pre-commit-config.yaml +36 -0
- robotframework_chat-1.0.0/.python-version +1 -0
- robotframework_chat-1.0.0/CLAUDE.md +62 -0
- robotframework_chat-1.0.0/Dockerfile.ci +58 -0
- robotframework_chat-1.0.0/LICENSE +191 -0
- robotframework_chat-1.0.0/Makefile +160 -0
- robotframework_chat-1.0.0/PKG-INFO +165 -0
- robotframework_chat-1.0.0/ai/AGENTS.md +603 -0
- robotframework_chat-1.0.0/ai/CLAUDE.md +89 -0
- robotframework_chat-1.0.0/ai/DEV.md +251 -0
- robotframework_chat-1.0.0/ai/DEVOPS.md +278 -0
- robotframework_chat-1.0.0/ai/FEATURES.md +320 -0
- robotframework_chat-1.0.0/ai/PIPELINES.md +187 -0
- robotframework_chat-1.0.0/ai/REFACTOR.md +299 -0
- robotframework_chat-1.0.0/ai/SKILLS.md +214 -0
- robotframework_chat-1.0.0/ai/roles/DOCKER_DEBUGGER.md +258 -0
- robotframework_chat-1.0.0/ai/roles/GITLAB_PIPELINE_DEBUGGER.md +256 -0
- robotframework_chat-1.0.0/ai/roles/ROBOTFRAMEWORK_DEBUGGER.md +247 -0
- robotframework_chat-1.0.0/ai/roles/WELCOME_BOT.md +295 -0
- robotframework_chat-1.0.0/backups/superset_export_20260301_132327.zip +0 -0
- robotframework_chat-1.0.0/ci/AGENTS.md +51 -0
- robotframework_chat-1.0.0/ci/FEATURES.md +20 -0
- robotframework_chat-1.0.0/ci/audit_markdown.sh +261 -0
- robotframework_chat-1.0.0/ci/common.yml +31 -0
- robotframework_chat-1.0.0/ci/deploy.sh +27 -0
- robotframework_chat-1.0.0/ci/ensure_node.sh +71 -0
- robotframework_chat-1.0.0/ci/generate.sh +75 -0
- robotframework_chat-1.0.0/ci/lint.sh +51 -0
- robotframework_chat-1.0.0/ci/local_review.sh +140 -0
- robotframework_chat-1.0.0/ci/pipeline_report.sh +52 -0
- robotframework_chat-1.0.0/ci/release.sh +44 -0
- robotframework_chat-1.0.0/ci/report.sh +46 -0
- robotframework_chat-1.0.0/ci/review.sh +317 -0
- robotframework_chat-1.0.0/ci/send_results.sh +66 -0
- robotframework_chat-1.0.0/ci/sync.sh +36 -0
- robotframework_chat-1.0.0/ci/test.sh +120 -0
- robotframework_chat-1.0.0/config/local_models.yaml +58 -0
- robotframework_chat-1.0.0/config/test_suites.yaml +182 -0
- robotframework_chat-1.0.0/docker-compose.yml +120 -0
- robotframework_chat-1.0.0/docs/GITLAB_CI_SETUP.md +237 -0
- robotframework_chat-1.0.0/docs/GITLAB_CI_TRIGGERS.md +343 -0
- robotframework_chat-1.0.0/docs/GRAFANA_SUPERSET_SETUP.md +1112 -0
- robotframework_chat-1.0.0/docs/PIPELINE_DEBUG.md +110 -0
- robotframework_chat-1.0.0/docs/SUPERSET_EXPORT_GUIDE.md +363 -0
- robotframework_chat-1.0.0/docs/TEST_DATABASE.md +330 -0
- robotframework_chat-1.0.0/humans/MAKE.md +145 -0
- robotframework_chat-1.0.0/humans/TODO.md +256 -0
- robotframework_chat-1.0.0/opencode.json +15 -0
- robotframework_chat-1.0.0/pyproject.toml +90 -0
- robotframework_chat-1.0.0/readme.md +111 -0
- robotframework_chat-1.0.0/requirements.txt +12 -0
- robotframework_chat-1.0.0/robot/ci/fetch_model_metadata.robot +171 -0
- robotframework_chat-1.0.0/robot/ci/models.yaml +136 -0
- robotframework_chat-1.0.0/robot/docker/__init__.robot +21 -0
- robotframework_chat-1.0.0/robot/docker/llm/__init__.robot +30 -0
- robotframework_chat-1.0.0/robot/docker/llm/tests/multi_model.robot +145 -0
- robotframework_chat-1.0.0/robot/docker/python/__init__.robot +12 -0
- robotframework_chat-1.0.0/robot/docker/python/tests/code_generation.robot +196 -0
- robotframework_chat-1.0.0/robot/docker/shell/__init__.robot +14 -0
- robotframework_chat-1.0.0/robot/docker/shell/tests/terminal_workflow.robot +142 -0
- robotframework_chat-1.0.0/robot/math/tests/__init__.robot +5 -0
- robotframework_chat-1.0.0/robot/math/tests/iq.robot +84 -0
- robotframework_chat-1.0.0/robot/math/tests/llm_maths.robot +24 -0
- robotframework_chat-1.0.0/robot/resources/container_profiles.resource +46 -0
- robotframework_chat-1.0.0/robot/resources/environments.resource +122 -0
- robotframework_chat-1.0.0/robot/resources/llm_containers.resource +161 -0
- robotframework_chat-1.0.0/robot/safety/README.md +369 -0
- robotframework_chat-1.0.0/robot/safety/__init__.robot +62 -0
- robotframework_chat-1.0.0/robot/safety/safety.resource +64 -0
- robotframework_chat-1.0.0/robot/safety/test_cases/test_indirect_injection.robot +80 -0
- robotframework_chat-1.0.0/robot/safety/test_cases/test_jailbreak.robot +101 -0
- robotframework_chat-1.0.0/robot/safety/test_cases/test_prompt_injection.robot +131 -0
- robotframework_chat-1.0.0/robot/safety/test_cases/test_system_extraction.robot +101 -0
- robotframework_chat-1.0.0/robot/safety/variables/injection_patterns.yaml +167 -0
- robotframework_chat-1.0.0/robot/safety/variables/safety_criteria.yaml +96 -0
- robotframework_chat-1.0.0/scripts/__init__.py +0 -0
- robotframework_chat-1.0.0/scripts/build-ci-image.sh +94 -0
- robotframework_chat-1.0.0/scripts/bump_version.py +409 -0
- robotframework_chat-1.0.0/scripts/ci-diagnostics.sh +133 -0
- robotframework_chat-1.0.0/scripts/discover_nodes.py +232 -0
- robotframework_chat-1.0.0/scripts/discover_ollama.py +202 -0
- robotframework_chat-1.0.0/scripts/generate_ci_metadata.py +77 -0
- robotframework_chat-1.0.0/scripts/generate_pipeline.py +343 -0
- robotframework_chat-1.0.0/scripts/import_test_results.py +323 -0
- robotframework_chat-1.0.0/scripts/ollama_pull.sh +70 -0
- robotframework_chat-1.0.0/scripts/pipeline_summary.py +361 -0
- robotframework_chat-1.0.0/scripts/query_results.py +210 -0
- robotframework_chat-1.0.0/scripts/repo_metrics.py +404 -0
- robotframework_chat-1.0.0/scripts/run_local_models.py +559 -0
- robotframework_chat-1.0.0/scripts/start.sh +14 -0
- robotframework_chat-1.0.0/scripts/stop.sh +9 -0
- robotframework_chat-1.0.0/src/__init__.py +0 -0
- robotframework_chat-1.0.0/src/rfc/.gitignore +67 -0
- robotframework_chat-1.0.0/src/rfc/__init__.py +1 -0
- robotframework_chat-1.0.0/src/rfc/chat_log_listener.py +162 -0
- robotframework_chat-1.0.0/src/rfc/container_manager.py +397 -0
- robotframework_chat-1.0.0/src/rfc/db_listener.py +423 -0
- robotframework_chat-1.0.0/src/rfc/docker_config.py +125 -0
- robotframework_chat-1.0.0/src/rfc/docker_keywords.py +385 -0
- robotframework_chat-1.0.0/src/rfc/dry_run_listener.py +102 -0
- robotframework_chat-1.0.0/src/rfc/git_metadata.py +169 -0
- robotframework_chat-1.0.0/src/rfc/git_metadata_listener.py +217 -0
- robotframework_chat-1.0.0/src/rfc/grader.py +96 -0
- robotframework_chat-1.0.0/src/rfc/host_info.py +141 -0
- robotframework_chat-1.0.0/src/rfc/keywords.py +119 -0
- robotframework_chat-1.0.0/src/rfc/llm_client.py +5 -0
- robotframework_chat-1.0.0/src/rfc/models.py +45 -0
- robotframework_chat-1.0.0/src/rfc/ollama.py +289 -0
- robotframework_chat-1.0.0/src/rfc/ollama_timestamp_listener.py +125 -0
- robotframework_chat-1.0.0/src/rfc/pre_run_modifier.py +208 -0
- robotframework_chat-1.0.0/src/rfc/safety_grader.py +222 -0
- robotframework_chat-1.0.0/src/rfc/safety_keywords.py +313 -0
- robotframework_chat-1.0.0/src/rfc/suite_config.py +169 -0
- robotframework_chat-1.0.0/src/rfc/test_database.py +1555 -0
- robotframework_chat-1.0.0/superset/Dockerfile +5 -0
- robotframework_chat-1.0.0/superset/bootstrap_dashboards.py +1288 -0
- robotframework_chat-1.0.0/superset/superset_config.py +51 -0
- robotframework_chat-1.0.0/superset_example_dashboard.png +0 -0
- robotframework_chat-1.0.0/superset_example_dashboard_2_27.png +0 -0
- robotframework_chat-1.0.0/tasks.py +208 -0
- robotframework_chat-1.0.0/tests/conftest.py +100 -0
- robotframework_chat-1.0.0/tests/test_bootstrap_columns.py +166 -0
- robotframework_chat-1.0.0/tests/test_bump_version.py +406 -0
- robotframework_chat-1.0.0/tests/test_chat_log_listener.py +325 -0
- robotframework_chat-1.0.0/tests/test_container_manager.py +620 -0
- robotframework_chat-1.0.0/tests/test_db_listener.py +951 -0
- robotframework_chat-1.0.0/tests/test_discover_nodes.py +153 -0
- robotframework_chat-1.0.0/tests/test_discover_ollama.py +144 -0
- robotframework_chat-1.0.0/tests/test_docker_config.py +101 -0
- robotframework_chat-1.0.0/tests/test_docker_keywords.py +337 -0
- robotframework_chat-1.0.0/tests/test_dry_run_listener.py +194 -0
- robotframework_chat-1.0.0/tests/test_generate_ci_metadata.py +164 -0
- robotframework_chat-1.0.0/tests/test_generate_pipeline.py +151 -0
- robotframework_chat-1.0.0/tests/test_git_metadata.py +211 -0
- robotframework_chat-1.0.0/tests/test_git_metadata_listener.py +355 -0
- robotframework_chat-1.0.0/tests/test_grader.py +74 -0
- robotframework_chat-1.0.0/tests/test_host_info.py +91 -0
- robotframework_chat-1.0.0/tests/test_import_test_results.py +626 -0
- robotframework_chat-1.0.0/tests/test_keywords.py +171 -0
- robotframework_chat-1.0.0/tests/test_models.py +125 -0
- robotframework_chat-1.0.0/tests/test_ollama.py +471 -0
- robotframework_chat-1.0.0/tests/test_ollama_timestamp_listener.py +208 -0
- robotframework_chat-1.0.0/tests/test_pipeline_summary.py +224 -0
- robotframework_chat-1.0.0/tests/test_pre_run_modifier.py +198 -0
- robotframework_chat-1.0.0/tests/test_query_results.py +178 -0
- robotframework_chat-1.0.0/tests/test_release.py +130 -0
- robotframework_chat-1.0.0/tests/test_repo_metrics.py +141 -0
- robotframework_chat-1.0.0/tests/test_run_local_models.py +488 -0
- robotframework_chat-1.0.0/tests/test_safety_grader.py +170 -0
- robotframework_chat-1.0.0/tests/test_safety_keywords.py +318 -0
- robotframework_chat-1.0.0/tests/test_suite_config.py +164 -0
- robotframework_chat-1.0.0/tests/test_test_database.py +690 -0
- robotframework_chat-1.0.0/uv.lock +1959 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# robotframework-chat environment configuration
|
|
2
|
+
# Copy to .env and edit before running: cp .env.example .env
|
|
3
|
+
|
|
4
|
+
# ── PostgreSQL ────────────────────────────────────────────────────────
|
|
5
|
+
POSTGRES_USER=rfc
|
|
6
|
+
POSTGRES_PASSWORD=changeme
|
|
7
|
+
POSTGRES_DB=rfc
|
|
8
|
+
POSTGRES_PORT=5433
|
|
9
|
+
|
|
10
|
+
# ── Superset ──────────────────────────────────────────────────────────
|
|
11
|
+
SUPERSET_SECRET_KEY=generate-a-random-secret-here
|
|
12
|
+
SUPERSET_PORT=8088
|
|
13
|
+
SUPERSET_ADMIN_USER=admin
|
|
14
|
+
SUPERSET_ADMIN_PASSWORD=changeme
|
|
15
|
+
SUPERSET_ADMIN_EMAIL=admin@rfc.local
|
|
16
|
+
|
|
17
|
+
# ── Test runner ───────────────────────────────────────────────────────
|
|
18
|
+
# DATABASE_URL tells the test harness to archive to PostgreSQL.
|
|
19
|
+
# Construct from the variables above.
|
|
20
|
+
DATABASE_URL=postgresql://rfc:changeme@localhost:5433/rfc
|
|
21
|
+
|
|
22
|
+
# Ollama endpoint for LLM tests
|
|
23
|
+
OLLAMA_ENDPOINT=http://localhost:11434
|
|
24
|
+
DEFAULT_MODEL=gpt-oss:20b
|
|
25
|
+
# Timeout in seconds for Ollama generate requests (increase for large models)
|
|
26
|
+
OLLAMA_TIMEOUT=300
|
|
27
|
+
|
|
28
|
+
# Comma-separated list of Ollama node hostnames for monitoring.
|
|
29
|
+
# With host networking (default Docker setup), localhost and LAN names
|
|
30
|
+
# resolve directly. With bridge networking, localhost is auto-rewritten
|
|
31
|
+
# to host.docker.internal.
|
|
32
|
+
# Leave empty to use the nodes list from config/test_suites.yaml.
|
|
33
|
+
OLLAMA_NODES_LIST=localhost
|
|
34
|
+
|
|
35
|
+
# ── AI Code Review (OpenCode + OpenRouter) ─────────────────────────
|
|
36
|
+
# Required for the review pipeline stage (ci/review.sh)
|
|
37
|
+
OPENROUTER_API_KEY=
|
|
38
|
+
|
|
39
|
+
# Model for markdown audit (default: ollama/qwen3-coder:30b-a3b-q4_K_M)
|
|
40
|
+
# Override to use a different Ollama model or provider
|
|
41
|
+
AUDIT_MODEL=
|
|
42
|
+
|
|
43
|
+
# ── GitLab Pipeline Monitoring ───────────────────────────────────────
|
|
44
|
+
# Set these to enable GitLab pipeline monitoring.
|
|
45
|
+
# GITLAB_API_URL: Base URL of your GitLab instance (e.g. https://gitlab.example.com)
|
|
46
|
+
# GITLAB_PROJECT_ID: Numeric project ID (Settings > General in GitLab)
|
|
47
|
+
# GITLAB_TOKEN: Personal access token with read_api scope
|
|
48
|
+
GITLAB_API_URL=
|
|
49
|
+
GITLAB_PROJECT_ID=
|
|
50
|
+
GITLAB_TOKEN=
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Remote node environment configuration
|
|
2
|
+
#
|
|
3
|
+
# Copy to .env on each remote Ollama node and edit:
|
|
4
|
+
# cp .env.remote.example .env
|
|
5
|
+
#
|
|
6
|
+
# A "remote node" is any machine in the fleet (e.g. ai1, Mini1s-Mac-Mini)
|
|
7
|
+
# that runs Ollama and executes Robot Framework tests locally, then sends
|
|
8
|
+
# results back to the central server.
|
|
9
|
+
|
|
10
|
+
# ── Node Identity ────────────────────────────────────────────────────
|
|
11
|
+
# Friendly name for this node (used in result paths and metadata).
|
|
12
|
+
# Should match the hostname in config/test_suites.yaml.
|
|
13
|
+
NODE_NAME=my-node
|
|
14
|
+
|
|
15
|
+
# ── Ollama (local to this node) ─────────────────────────────────────
|
|
16
|
+
OLLAMA_ENDPOINT=http://localhost:11434
|
|
17
|
+
DEFAULT_MODEL=llama3.2:latest
|
|
18
|
+
|
|
19
|
+
# Comma-separated list of Ollama nodes to probe.
|
|
20
|
+
# Set to just "localhost" when this node only tests its own models.
|
|
21
|
+
OLLAMA_NODES_LIST=localhost
|
|
22
|
+
|
|
23
|
+
# ── Central Database ────────────────────────────────────────────────
|
|
24
|
+
# PostgreSQL connection string for the central results database.
|
|
25
|
+
# Point this at the server running docker-compose (PostgreSQL + Superset).
|
|
26
|
+
# Leave empty to fall back to local SQLite (data/test_history.db).
|
|
27
|
+
DATABASE_URL=postgresql://rfc:changeme@central-server:5433/rfc
|
|
28
|
+
|
|
29
|
+
# ── Results Server (for make send-results) ──────────────────────────
|
|
30
|
+
# SSH connection details for rsync-ing results to the central server.
|
|
31
|
+
RESULTS_SERVER=central-server
|
|
32
|
+
RESULTS_SERVER_USER=rfc
|
|
33
|
+
RESULTS_SERVER_PATH=/opt/rfc/results/
|
|
34
|
+
RESULTS_SERVER_PORT=22
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
name: Mirror claude-code-staging to GitLab
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- claude-code-staging
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
mirror:
|
|
11
|
+
runs-on: self-hosted
|
|
12
|
+
environment: robotframework
|
|
13
|
+
steps:
|
|
14
|
+
- name: Checkout claude-code-staging (full history)
|
|
15
|
+
uses: actions/checkout@v4
|
|
16
|
+
with:
|
|
17
|
+
ref: claude-code-staging
|
|
18
|
+
fetch-depth: 0
|
|
19
|
+
|
|
20
|
+
- name: Push to GitLab
|
|
21
|
+
env:
|
|
22
|
+
GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }}
|
|
23
|
+
run: |
|
|
24
|
+
set -euo pipefail
|
|
25
|
+
|
|
26
|
+
echo "::add-mask::${GITLAB_TOKEN}"
|
|
27
|
+
|
|
28
|
+
if [ -z "${GITLAB_TOKEN:-}" ]; then
|
|
29
|
+
echo "::error::GITLAB_TOKEN secret must be configured."
|
|
30
|
+
echo "Create a GitLab personal access token with write_repository scope"
|
|
31
|
+
echo "and add it as a repository secret named GITLAB_TOKEN."
|
|
32
|
+
exit 1
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
AUTH_URL="https://oauth2:${GITLAB_TOKEN}@gitlab.com/space-nomads/robotframework-chat.git"
|
|
36
|
+
|
|
37
|
+
if git remote get-url gitlab >/dev/null 2>&1; then
|
|
38
|
+
git remote set-url gitlab "${AUTH_URL}"
|
|
39
|
+
else
|
|
40
|
+
git remote add gitlab "${AUTH_URL}"
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
echo "Mirroring claude-code-staging to GitLab"
|
|
44
|
+
git push gitlab refs/heads/claude-code-staging:refs/heads/claude-code-staging --force
|
|
45
|
+
|
|
46
|
+
echo "Mirror complete."
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
id-token: write # Required for OIDC trusted publishing
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
build:
|
|
14
|
+
name: Build distribution
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Install uv
|
|
20
|
+
uses: astral-sh/setup-uv@v4
|
|
21
|
+
|
|
22
|
+
- name: Install dependencies
|
|
23
|
+
run: uv sync --extra dev
|
|
24
|
+
|
|
25
|
+
- name: Validate tag matches package version
|
|
26
|
+
run: |
|
|
27
|
+
PKG_VERSION=$(uv run python -c "
|
|
28
|
+
import tomllib, pathlib
|
|
29
|
+
data = tomllib.loads(pathlib.Path('pyproject.toml').read_text())
|
|
30
|
+
print(data['project']['version'])
|
|
31
|
+
")
|
|
32
|
+
TAG_VERSION="${GITHUB_REF_NAME#v}"
|
|
33
|
+
echo "Tag version: $TAG_VERSION"
|
|
34
|
+
echo "Package version: $PKG_VERSION"
|
|
35
|
+
if [ "$TAG_VERSION" != "$PKG_VERSION" ]; then
|
|
36
|
+
echo "::error::Tag $GITHUB_REF_NAME does not match pyproject.toml version $PKG_VERSION"
|
|
37
|
+
exit 1
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
- name: Build sdist and wheel
|
|
41
|
+
run: uv run python -m build
|
|
42
|
+
|
|
43
|
+
- name: Verify distributions
|
|
44
|
+
run: uv run twine check dist/*
|
|
45
|
+
|
|
46
|
+
- name: Upload distributions
|
|
47
|
+
uses: actions/upload-artifact@v4
|
|
48
|
+
with:
|
|
49
|
+
name: dist
|
|
50
|
+
path: dist/
|
|
51
|
+
|
|
52
|
+
publish:
|
|
53
|
+
name: Publish to PyPI
|
|
54
|
+
runs-on: ubuntu-latest
|
|
55
|
+
needs: build
|
|
56
|
+
environment:
|
|
57
|
+
name: pypi
|
|
58
|
+
url: https://pypi.org/project/robotframework-chat/
|
|
59
|
+
steps:
|
|
60
|
+
- name: Download distributions
|
|
61
|
+
uses: actions/download-artifact@v4
|
|
62
|
+
with:
|
|
63
|
+
name: dist
|
|
64
|
+
path: dist/
|
|
65
|
+
|
|
66
|
+
- name: Publish to PyPI
|
|
67
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
name: Robot Framework Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
lint:
|
|
12
|
+
name: Lint & Typecheck
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: Install uv
|
|
18
|
+
uses: astral-sh/setup-uv@v4
|
|
19
|
+
|
|
20
|
+
- name: Install dependencies
|
|
21
|
+
run: uv sync --extra dev
|
|
22
|
+
|
|
23
|
+
- name: Ruff check
|
|
24
|
+
run: uv run ruff check .
|
|
25
|
+
|
|
26
|
+
- name: Mypy
|
|
27
|
+
run: uv run mypy src/
|
|
28
|
+
|
|
29
|
+
robot-dryrun:
|
|
30
|
+
name: Robot Suite Validation (dry-run)
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@v4
|
|
34
|
+
|
|
35
|
+
- name: Install uv
|
|
36
|
+
uses: astral-sh/setup-uv@v4
|
|
37
|
+
|
|
38
|
+
- name: Install dependencies
|
|
39
|
+
run: uv sync --extra dev
|
|
40
|
+
|
|
41
|
+
- name: Validate robot files (dry-run)
|
|
42
|
+
run: uv run robot --dryrun --exclude browser -d results/dryrun robot/
|
|
43
|
+
|
|
44
|
+
- name: Upload dry-run results
|
|
45
|
+
if: always()
|
|
46
|
+
uses: actions/upload-artifact@v4
|
|
47
|
+
with:
|
|
48
|
+
name: dryrun-results
|
|
49
|
+
path: results/dryrun/
|
|
50
|
+
|
|
51
|
+
robot-tests:
|
|
52
|
+
name: Robot Tests
|
|
53
|
+
runs-on: self-hosted
|
|
54
|
+
needs: [lint, robot-dryrun]
|
|
55
|
+
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
|
|
56
|
+
env:
|
|
57
|
+
LISTENERS: >-
|
|
58
|
+
--listener rfc.db_listener.DbListener
|
|
59
|
+
--listener rfc.git_metadata_listener.GitMetaData
|
|
60
|
+
--listener rfc.ollama_timestamp_listener.OllamaTimestampListener
|
|
61
|
+
steps:
|
|
62
|
+
- uses: actions/checkout@v4
|
|
63
|
+
|
|
64
|
+
- name: Install uv
|
|
65
|
+
uses: astral-sh/setup-uv@v4
|
|
66
|
+
|
|
67
|
+
- name: Install dependencies
|
|
68
|
+
run: uv sync --extra dev
|
|
69
|
+
|
|
70
|
+
- name: Run math tests
|
|
71
|
+
run: uv run robot -d results/math $LISTENERS robot/math/tests/
|
|
72
|
+
|
|
73
|
+
- name: Run safety tests
|
|
74
|
+
if: always()
|
|
75
|
+
run: uv run robot -d results/safety $LISTENERS robot/safety/
|
|
76
|
+
|
|
77
|
+
- name: Run Docker tests
|
|
78
|
+
if: always()
|
|
79
|
+
run: uv run robot -d results/docker $LISTENERS robot/docker/
|
|
80
|
+
|
|
81
|
+
- name: Upload test results
|
|
82
|
+
if: always()
|
|
83
|
+
uses: actions/upload-artifact@v4
|
|
84
|
+
with:
|
|
85
|
+
name: robot-results
|
|
86
|
+
path: results/
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
name: Sync from GitLab
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
schedule:
|
|
5
|
+
# Run every 15 minutes to pick up GitLab changes
|
|
6
|
+
- cron: "*/15 * * * *"
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
inputs:
|
|
9
|
+
branch:
|
|
10
|
+
description: "Branch to sync (leave empty for main only)"
|
|
11
|
+
required: false
|
|
12
|
+
default: ""
|
|
13
|
+
sync_tags:
|
|
14
|
+
description: "Also sync tags from GitLab"
|
|
15
|
+
required: false
|
|
16
|
+
default: "true"
|
|
17
|
+
type: choice
|
|
18
|
+
options:
|
|
19
|
+
- "true"
|
|
20
|
+
- "false"
|
|
21
|
+
|
|
22
|
+
permissions:
|
|
23
|
+
contents: write
|
|
24
|
+
|
|
25
|
+
jobs:
|
|
26
|
+
sync:
|
|
27
|
+
runs-on: self-hosted
|
|
28
|
+
environment: robotframework
|
|
29
|
+
steps:
|
|
30
|
+
- name: Checkout (full history)
|
|
31
|
+
uses: actions/checkout@v4
|
|
32
|
+
with:
|
|
33
|
+
fetch-depth: 0
|
|
34
|
+
|
|
35
|
+
- name: Pull from GitLab and push to GitHub
|
|
36
|
+
env:
|
|
37
|
+
GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }}
|
|
38
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
39
|
+
run: |
|
|
40
|
+
set -euo pipefail
|
|
41
|
+
|
|
42
|
+
GITLAB_URL="https://gitlab.com/space-nomads/robotframework-chat.git"
|
|
43
|
+
|
|
44
|
+
echo "::add-mask::${GITLAB_TOKEN}"
|
|
45
|
+
echo "::add-mask::${GITLAB_URL}"
|
|
46
|
+
|
|
47
|
+
if [ -z "${GITLAB_TOKEN:-}" ]; then
|
|
48
|
+
echo "::error::GITLAB_TOKEN secret must be configured."
|
|
49
|
+
echo "Create a GitLab personal access token with read_repository scope"
|
|
50
|
+
echo "and add it as a repository secret named GITLAB_TOKEN."
|
|
51
|
+
exit 1
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
AUTH_URL="https://oauth2:${GITLAB_TOKEN}@gitlab.com/space-nomads/robotframework-chat.git"
|
|
55
|
+
|
|
56
|
+
# Configure origin with GITHUB_TOKEN so pushes authenticate
|
|
57
|
+
git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@github.com/${{ github.repository }}.git"
|
|
58
|
+
|
|
59
|
+
# Add GitLab as a remote
|
|
60
|
+
if git remote get-url gitlab >/dev/null 2>&1; then
|
|
61
|
+
git remote set-url gitlab "${AUTH_URL}"
|
|
62
|
+
else
|
|
63
|
+
git remote add gitlab "${AUTH_URL}"
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
# Fetch all branches and tags from GitLab
|
|
67
|
+
echo "Fetching from GitLab..."
|
|
68
|
+
git fetch gitlab --prune
|
|
69
|
+
|
|
70
|
+
BRANCH="${{ github.event.inputs.branch }}"
|
|
71
|
+
|
|
72
|
+
if [ -n "${BRANCH}" ]; then
|
|
73
|
+
echo "Syncing branch: ${BRANCH}"
|
|
74
|
+
git push origin "refs/remotes/gitlab/${BRANCH}:refs/heads/${BRANCH}" --force
|
|
75
|
+
else
|
|
76
|
+
echo "Syncing main from GitLab to GitHub"
|
|
77
|
+
git push origin refs/remotes/gitlab/main:refs/heads/main --force
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
SYNC_TAGS="${{ github.event.inputs.sync_tags }}"
|
|
81
|
+
# Default to true for scheduled runs (inputs are empty)
|
|
82
|
+
if [ "${SYNC_TAGS}" = "true" ] || [ -z "${SYNC_TAGS}" ]; then
|
|
83
|
+
echo "Syncing tags from GitLab"
|
|
84
|
+
git fetch gitlab --tags --force
|
|
85
|
+
git push origin --tags --force
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
echo "Sync from GitLab complete."
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
name: Sync to GitLab
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
inputs:
|
|
9
|
+
branch:
|
|
10
|
+
description: "Branch to sync (leave empty for all branches)"
|
|
11
|
+
required: false
|
|
12
|
+
default: ""
|
|
13
|
+
sync_tags:
|
|
14
|
+
description: "Also sync tags"
|
|
15
|
+
required: false
|
|
16
|
+
default: "true"
|
|
17
|
+
type: choice
|
|
18
|
+
options:
|
|
19
|
+
- "true"
|
|
20
|
+
- "false"
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
sync:
|
|
24
|
+
runs-on: self-hosted
|
|
25
|
+
environment: robotframework
|
|
26
|
+
steps:
|
|
27
|
+
- name: Checkout (full history)
|
|
28
|
+
uses: actions/checkout@v4
|
|
29
|
+
with:
|
|
30
|
+
fetch-depth: 0
|
|
31
|
+
|
|
32
|
+
- name: Push to GitLab
|
|
33
|
+
env:
|
|
34
|
+
GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }}
|
|
35
|
+
run: |
|
|
36
|
+
set -euo pipefail
|
|
37
|
+
|
|
38
|
+
GITLAB_URL="https://gitlab.com/space-nomads/robotframework-chat.git"
|
|
39
|
+
|
|
40
|
+
echo "::add-mask::${GITLAB_TOKEN}"
|
|
41
|
+
echo "::add-mask::${GITLAB_URL}"
|
|
42
|
+
|
|
43
|
+
if [ -z "${GITLAB_TOKEN:-}" ]; then
|
|
44
|
+
echo "::error::GITLAB_TOKEN secret must be configured."
|
|
45
|
+
echo "Create a GitLab personal access token with write_repository scope"
|
|
46
|
+
echo "and add it as a repository secret named GITLAB_TOKEN."
|
|
47
|
+
exit 1
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
AUTH_URL="https://oauth2:${GITLAB_TOKEN}@gitlab.com/space-nomads/robotframework-chat.git"
|
|
51
|
+
|
|
52
|
+
if git remote get-url gitlab >/dev/null 2>&1; then
|
|
53
|
+
git remote set-url gitlab "${AUTH_URL}"
|
|
54
|
+
else
|
|
55
|
+
git remote add gitlab "${AUTH_URL}"
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
BRANCH="${{ github.event.inputs.branch }}"
|
|
59
|
+
|
|
60
|
+
if [ -n "${BRANCH}" ]; then
|
|
61
|
+
echo "Syncing branch: ${BRANCH}"
|
|
62
|
+
git push gitlab "refs/heads/${BRANCH}:refs/heads/${BRANCH}" --force
|
|
63
|
+
else
|
|
64
|
+
echo "Syncing all branches"
|
|
65
|
+
git push gitlab --all --force
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
if [ "${{ github.event.inputs.sync_tags }}" = "true" ]; then
|
|
69
|
+
echo "Syncing tags"
|
|
70
|
+
git push gitlab --tags --force
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
echo "Sync complete."
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
*.egg-info/
|
|
20
|
+
.installed.cfg
|
|
21
|
+
*.egg
|
|
22
|
+
|
|
23
|
+
# Virtual environments
|
|
24
|
+
.env
|
|
25
|
+
.venv
|
|
26
|
+
env/
|
|
27
|
+
venv/
|
|
28
|
+
ENV/
|
|
29
|
+
env.bak/
|
|
30
|
+
venv.bak/
|
|
31
|
+
|
|
32
|
+
# IDE
|
|
33
|
+
.idea/
|
|
34
|
+
.vscode/
|
|
35
|
+
*.swp
|
|
36
|
+
*.swo
|
|
37
|
+
*~
|
|
38
|
+
|
|
39
|
+
# Robot Framework results
|
|
40
|
+
results/
|
|
41
|
+
*.log
|
|
42
|
+
log.html
|
|
43
|
+
output.xml
|
|
44
|
+
report.html
|
|
45
|
+
ci_metadata.json
|
|
46
|
+
ollama_timestamps.json
|
|
47
|
+
|
|
48
|
+
# OS
|
|
49
|
+
.DS_Store
|
|
50
|
+
Thumbs.db
|
|
51
|
+
|
|
52
|
+
# Database
|
|
53
|
+
data/
|
|
54
|
+
|
|
55
|
+
# Metrics output (generated by CI)
|
|
56
|
+
metrics/
|
|
57
|
+
|
|
58
|
+
# Generated CI artifacts
|
|
59
|
+
config/nodes_inventory.yaml
|
|
60
|
+
generated-pipeline.yml
|
|
61
|
+
generated-dynamic-pipeline.yml
|
|
62
|
+
|
|
63
|
+
# Coverage
|
|
64
|
+
.coverage
|
|
65
|
+
htmlcov/
|
|
66
|
+
|
|
67
|
+
# Project specific
|
|
68
|
+
*.local
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# .gitlab-ci.yml - Bare-bones pipeline skeleton
|
|
2
|
+
#
|
|
3
|
+
# All logic lives in ci/*.sh scripts and Makefile targets.
|
|
4
|
+
# This file is intentionally minimal. To modify pipeline behavior,
|
|
5
|
+
# edit the scripts -- not this file.
|
|
6
|
+
#
|
|
7
|
+
# Pipeline modes:
|
|
8
|
+
# 1. Test - every push/MR, per-node `make run-local-models` (allow_failure)
|
|
9
|
+
# 2. Release - clean semver tag (v1.2.3), build + publish to PyPI
|
|
10
|
+
# 3. Test Release - pre-release tag (v1.2.3-rc1), build + verify only
|
|
11
|
+
#
|
|
12
|
+
# Nodes: ai1, mini1, mini2, dev1, dev2 (matched by GitLab runner tags)
|
|
13
|
+
#
|
|
14
|
+
# See: ai/PIPELINES.md
|
|
15
|
+
|
|
16
|
+
include:
|
|
17
|
+
- local: ci/common.yml
|
|
18
|
+
|
|
19
|
+
stages:
|
|
20
|
+
- lint
|
|
21
|
+
- test
|
|
22
|
+
- report
|
|
23
|
+
- deploy
|
|
24
|
+
- release
|
|
25
|
+
- review
|
|
26
|
+
|
|
27
|
+
variables:
|
|
28
|
+
OLLAMA_ENDPOINT: "http://localhost:11434"
|
|
29
|
+
DEFAULT_MODEL: "llama3"
|
|
30
|
+
ROBOT_OPTIONS: "--metadata CI:true"
|
|
31
|
+
|
|
32
|
+
# ── Lint ─────────────────────────────────────────────────────────────
|
|
33
|
+
|
|
34
|
+
lint:
|
|
35
|
+
extends: .uv-setup
|
|
36
|
+
stage: lint
|
|
37
|
+
script: [bash ci/lint.sh all]
|
|
38
|
+
rules:
|
|
39
|
+
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
|
40
|
+
- if: $CI_COMMIT_TAG =~ /^v/
|
|
41
|
+
- if: $CI_COMMIT_BRANCH
|
|
42
|
+
|
|
43
|
+
# ── Test: Per-Node Model Runs ──────────────────────────────────────
|
|
44
|
+
|
|
45
|
+
.run-local-models:
|
|
46
|
+
extends: .robot-test
|
|
47
|
+
stage: test
|
|
48
|
+
needs:
|
|
49
|
+
- job: lint
|
|
50
|
+
artifacts: false
|
|
51
|
+
script: [make run-local-models]
|
|
52
|
+
allow_failure: true
|
|
53
|
+
rules:
|
|
54
|
+
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
|
55
|
+
- if: $CI_COMMIT_BRANCH
|
|
56
|
+
|
|
57
|
+
run-local-models-ai1:
|
|
58
|
+
extends: .run-local-models
|
|
59
|
+
tags: [ai1]
|
|
60
|
+
|
|
61
|
+
run-local-models-mini1:
|
|
62
|
+
extends: .run-local-models
|
|
63
|
+
tags: [mini1]
|
|
64
|
+
|
|
65
|
+
run-local-models-mini2:
|
|
66
|
+
extends: .run-local-models
|
|
67
|
+
tags: [mini2]
|
|
68
|
+
|
|
69
|
+
run-local-models-dev1:
|
|
70
|
+
extends: .run-local-models
|
|
71
|
+
tags: [dev1]
|
|
72
|
+
|
|
73
|
+
run-local-models-dev2:
|
|
74
|
+
extends: .run-local-models
|
|
75
|
+
tags: [dev2]
|
|
76
|
+
|
|
77
|
+
# ── Report ───────────────────────────────────────────────────────────
|
|
78
|
+
|
|
79
|
+
repo-metrics:
|
|
80
|
+
extends: .uv-setup
|
|
81
|
+
stage: report
|
|
82
|
+
needs: []
|
|
83
|
+
script: [make ci-report POST_MR=1]
|
|
84
|
+
artifacts:
|
|
85
|
+
paths: [metrics/]
|
|
86
|
+
expire_in: 30 days
|
|
87
|
+
rules:
|
|
88
|
+
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
|
89
|
+
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
|
90
|
+
|
|
91
|
+
pipeline-summary:
|
|
92
|
+
extends: .uv-setup
|
|
93
|
+
stage: report
|
|
94
|
+
needs:
|
|
95
|
+
- job: lint
|
|
96
|
+
artifacts: false
|
|
97
|
+
optional: true
|
|
98
|
+
script: [bash ci/pipeline_report.sh --post-mr]
|
|
99
|
+
artifacts:
|
|
100
|
+
paths: [metrics/]
|
|
101
|
+
expire_in: 30 days
|
|
102
|
+
rules:
|
|
103
|
+
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
|
104
|
+
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
|
105
|
+
|
|
106
|
+
# ── Deploy ───────────────────────────────────────────────────────────
|
|
107
|
+
|
|
108
|
+
deploy-superset:
|
|
109
|
+
stage: deploy
|
|
110
|
+
tags: [deploy]
|
|
111
|
+
script: [make ci-deploy]
|
|
112
|
+
rules:
|
|
113
|
+
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $SUPERSET_DEPLOY_HOST
|
|
114
|
+
|
|
115
|
+
# ── Release ──────────────────────────────────────────────────────────
|
|
116
|
+
# PyPI publishing is handled by GitHub Actions trusted publishing.
|
|
117
|
+
# See .github/workflows/pypi-publish.yml
|
|
118
|
+
#
|
|
119
|
+
# This job only verifies the package builds correctly.
|
|
120
|
+
build-check:
|
|
121
|
+
extends: .uv-setup
|
|
122
|
+
stage: release
|
|
123
|
+
needs:
|
|
124
|
+
- job: lint
|
|
125
|
+
artifacts: false
|
|
126
|
+
script: [make build-check]
|
|
127
|
+
artifacts:
|
|
128
|
+
paths: [dist/]
|
|
129
|
+
expire_in: 7 days
|
|
130
|
+
rules:
|
|
131
|
+
- if: $CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+/
|
|
132
|
+
|
|
133
|
+
# ── Review ───────────────────────────────────────────────────────────
|
|
134
|
+
|
|
135
|
+
opencode-review:
|
|
136
|
+
stage: review
|
|
137
|
+
tags: [nodejs]
|
|
138
|
+
variables:
|
|
139
|
+
REVIEW_MODEL: "openrouter/moonshotai/kimi-k2.5"
|
|
140
|
+
before_script:
|
|
141
|
+
- npm install -g opencode-ai
|
|
142
|
+
script: [make opencode-pipeline-review]
|
|
143
|
+
artifacts:
|
|
144
|
+
paths:
|
|
145
|
+
- review-result.md
|
|
146
|
+
- review-fix-attempt.md
|
|
147
|
+
- review-patch-*.diff
|
|
148
|
+
expire_in: 30 days
|
|
149
|
+
when: always
|
|
150
|
+
rules:
|
|
151
|
+
- if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_LABELS =~ /opencode-review/
|
|
152
|
+
- when: manual
|