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.
Files changed (163) hide show
  1. robotframework_chat-1.0.0/.env.example +50 -0
  2. robotframework_chat-1.0.0/.env.remote.example +34 -0
  3. robotframework_chat-1.0.0/.gitattributes +5 -0
  4. robotframework_chat-1.0.0/.github/workflows/mirror-staging-to-gitlab.yml +46 -0
  5. robotframework_chat-1.0.0/.github/workflows/pypi-publish.yml +67 -0
  6. robotframework_chat-1.0.0/.github/workflows/robot-tests.yml +86 -0
  7. robotframework_chat-1.0.0/.github/workflows/sync-from-gitlab.yml +88 -0
  8. robotframework_chat-1.0.0/.github/workflows/sync-to-gitlab.yml +73 -0
  9. robotframework_chat-1.0.0/.gitignore +68 -0
  10. robotframework_chat-1.0.0/.gitlab-ci.yml +152 -0
  11. robotframework_chat-1.0.0/.pre-commit-config.yaml +36 -0
  12. robotframework_chat-1.0.0/.python-version +1 -0
  13. robotframework_chat-1.0.0/CLAUDE.md +62 -0
  14. robotframework_chat-1.0.0/Dockerfile.ci +58 -0
  15. robotframework_chat-1.0.0/LICENSE +191 -0
  16. robotframework_chat-1.0.0/Makefile +160 -0
  17. robotframework_chat-1.0.0/PKG-INFO +165 -0
  18. robotframework_chat-1.0.0/ai/AGENTS.md +603 -0
  19. robotframework_chat-1.0.0/ai/CLAUDE.md +89 -0
  20. robotframework_chat-1.0.0/ai/DEV.md +251 -0
  21. robotframework_chat-1.0.0/ai/DEVOPS.md +278 -0
  22. robotframework_chat-1.0.0/ai/FEATURES.md +320 -0
  23. robotframework_chat-1.0.0/ai/PIPELINES.md +187 -0
  24. robotframework_chat-1.0.0/ai/REFACTOR.md +299 -0
  25. robotframework_chat-1.0.0/ai/SKILLS.md +214 -0
  26. robotframework_chat-1.0.0/ai/roles/DOCKER_DEBUGGER.md +258 -0
  27. robotframework_chat-1.0.0/ai/roles/GITLAB_PIPELINE_DEBUGGER.md +256 -0
  28. robotframework_chat-1.0.0/ai/roles/ROBOTFRAMEWORK_DEBUGGER.md +247 -0
  29. robotframework_chat-1.0.0/ai/roles/WELCOME_BOT.md +295 -0
  30. robotframework_chat-1.0.0/backups/superset_export_20260301_132327.zip +0 -0
  31. robotframework_chat-1.0.0/ci/AGENTS.md +51 -0
  32. robotframework_chat-1.0.0/ci/FEATURES.md +20 -0
  33. robotframework_chat-1.0.0/ci/audit_markdown.sh +261 -0
  34. robotframework_chat-1.0.0/ci/common.yml +31 -0
  35. robotframework_chat-1.0.0/ci/deploy.sh +27 -0
  36. robotframework_chat-1.0.0/ci/ensure_node.sh +71 -0
  37. robotframework_chat-1.0.0/ci/generate.sh +75 -0
  38. robotframework_chat-1.0.0/ci/lint.sh +51 -0
  39. robotframework_chat-1.0.0/ci/local_review.sh +140 -0
  40. robotframework_chat-1.0.0/ci/pipeline_report.sh +52 -0
  41. robotframework_chat-1.0.0/ci/release.sh +44 -0
  42. robotframework_chat-1.0.0/ci/report.sh +46 -0
  43. robotframework_chat-1.0.0/ci/review.sh +317 -0
  44. robotframework_chat-1.0.0/ci/send_results.sh +66 -0
  45. robotframework_chat-1.0.0/ci/sync.sh +36 -0
  46. robotframework_chat-1.0.0/ci/test.sh +120 -0
  47. robotframework_chat-1.0.0/config/local_models.yaml +58 -0
  48. robotframework_chat-1.0.0/config/test_suites.yaml +182 -0
  49. robotframework_chat-1.0.0/docker-compose.yml +120 -0
  50. robotframework_chat-1.0.0/docs/GITLAB_CI_SETUP.md +237 -0
  51. robotframework_chat-1.0.0/docs/GITLAB_CI_TRIGGERS.md +343 -0
  52. robotframework_chat-1.0.0/docs/GRAFANA_SUPERSET_SETUP.md +1112 -0
  53. robotframework_chat-1.0.0/docs/PIPELINE_DEBUG.md +110 -0
  54. robotframework_chat-1.0.0/docs/SUPERSET_EXPORT_GUIDE.md +363 -0
  55. robotframework_chat-1.0.0/docs/TEST_DATABASE.md +330 -0
  56. robotframework_chat-1.0.0/humans/MAKE.md +145 -0
  57. robotframework_chat-1.0.0/humans/TODO.md +256 -0
  58. robotframework_chat-1.0.0/opencode.json +15 -0
  59. robotframework_chat-1.0.0/pyproject.toml +90 -0
  60. robotframework_chat-1.0.0/readme.md +111 -0
  61. robotframework_chat-1.0.0/requirements.txt +12 -0
  62. robotframework_chat-1.0.0/robot/ci/fetch_model_metadata.robot +171 -0
  63. robotframework_chat-1.0.0/robot/ci/models.yaml +136 -0
  64. robotframework_chat-1.0.0/robot/docker/__init__.robot +21 -0
  65. robotframework_chat-1.0.0/robot/docker/llm/__init__.robot +30 -0
  66. robotframework_chat-1.0.0/robot/docker/llm/tests/multi_model.robot +145 -0
  67. robotframework_chat-1.0.0/robot/docker/python/__init__.robot +12 -0
  68. robotframework_chat-1.0.0/robot/docker/python/tests/code_generation.robot +196 -0
  69. robotframework_chat-1.0.0/robot/docker/shell/__init__.robot +14 -0
  70. robotframework_chat-1.0.0/robot/docker/shell/tests/terminal_workflow.robot +142 -0
  71. robotframework_chat-1.0.0/robot/math/tests/__init__.robot +5 -0
  72. robotframework_chat-1.0.0/robot/math/tests/iq.robot +84 -0
  73. robotframework_chat-1.0.0/robot/math/tests/llm_maths.robot +24 -0
  74. robotframework_chat-1.0.0/robot/resources/container_profiles.resource +46 -0
  75. robotframework_chat-1.0.0/robot/resources/environments.resource +122 -0
  76. robotframework_chat-1.0.0/robot/resources/llm_containers.resource +161 -0
  77. robotframework_chat-1.0.0/robot/safety/README.md +369 -0
  78. robotframework_chat-1.0.0/robot/safety/__init__.robot +62 -0
  79. robotframework_chat-1.0.0/robot/safety/safety.resource +64 -0
  80. robotframework_chat-1.0.0/robot/safety/test_cases/test_indirect_injection.robot +80 -0
  81. robotframework_chat-1.0.0/robot/safety/test_cases/test_jailbreak.robot +101 -0
  82. robotframework_chat-1.0.0/robot/safety/test_cases/test_prompt_injection.robot +131 -0
  83. robotframework_chat-1.0.0/robot/safety/test_cases/test_system_extraction.robot +101 -0
  84. robotframework_chat-1.0.0/robot/safety/variables/injection_patterns.yaml +167 -0
  85. robotframework_chat-1.0.0/robot/safety/variables/safety_criteria.yaml +96 -0
  86. robotframework_chat-1.0.0/scripts/__init__.py +0 -0
  87. robotframework_chat-1.0.0/scripts/build-ci-image.sh +94 -0
  88. robotframework_chat-1.0.0/scripts/bump_version.py +409 -0
  89. robotframework_chat-1.0.0/scripts/ci-diagnostics.sh +133 -0
  90. robotframework_chat-1.0.0/scripts/discover_nodes.py +232 -0
  91. robotframework_chat-1.0.0/scripts/discover_ollama.py +202 -0
  92. robotframework_chat-1.0.0/scripts/generate_ci_metadata.py +77 -0
  93. robotframework_chat-1.0.0/scripts/generate_pipeline.py +343 -0
  94. robotframework_chat-1.0.0/scripts/import_test_results.py +323 -0
  95. robotframework_chat-1.0.0/scripts/ollama_pull.sh +70 -0
  96. robotframework_chat-1.0.0/scripts/pipeline_summary.py +361 -0
  97. robotframework_chat-1.0.0/scripts/query_results.py +210 -0
  98. robotframework_chat-1.0.0/scripts/repo_metrics.py +404 -0
  99. robotframework_chat-1.0.0/scripts/run_local_models.py +559 -0
  100. robotframework_chat-1.0.0/scripts/start.sh +14 -0
  101. robotframework_chat-1.0.0/scripts/stop.sh +9 -0
  102. robotframework_chat-1.0.0/src/__init__.py +0 -0
  103. robotframework_chat-1.0.0/src/rfc/.gitignore +67 -0
  104. robotframework_chat-1.0.0/src/rfc/__init__.py +1 -0
  105. robotframework_chat-1.0.0/src/rfc/chat_log_listener.py +162 -0
  106. robotframework_chat-1.0.0/src/rfc/container_manager.py +397 -0
  107. robotframework_chat-1.0.0/src/rfc/db_listener.py +423 -0
  108. robotframework_chat-1.0.0/src/rfc/docker_config.py +125 -0
  109. robotframework_chat-1.0.0/src/rfc/docker_keywords.py +385 -0
  110. robotframework_chat-1.0.0/src/rfc/dry_run_listener.py +102 -0
  111. robotframework_chat-1.0.0/src/rfc/git_metadata.py +169 -0
  112. robotframework_chat-1.0.0/src/rfc/git_metadata_listener.py +217 -0
  113. robotframework_chat-1.0.0/src/rfc/grader.py +96 -0
  114. robotframework_chat-1.0.0/src/rfc/host_info.py +141 -0
  115. robotframework_chat-1.0.0/src/rfc/keywords.py +119 -0
  116. robotframework_chat-1.0.0/src/rfc/llm_client.py +5 -0
  117. robotframework_chat-1.0.0/src/rfc/models.py +45 -0
  118. robotframework_chat-1.0.0/src/rfc/ollama.py +289 -0
  119. robotframework_chat-1.0.0/src/rfc/ollama_timestamp_listener.py +125 -0
  120. robotframework_chat-1.0.0/src/rfc/pre_run_modifier.py +208 -0
  121. robotframework_chat-1.0.0/src/rfc/safety_grader.py +222 -0
  122. robotframework_chat-1.0.0/src/rfc/safety_keywords.py +313 -0
  123. robotframework_chat-1.0.0/src/rfc/suite_config.py +169 -0
  124. robotframework_chat-1.0.0/src/rfc/test_database.py +1555 -0
  125. robotframework_chat-1.0.0/superset/Dockerfile +5 -0
  126. robotframework_chat-1.0.0/superset/bootstrap_dashboards.py +1288 -0
  127. robotframework_chat-1.0.0/superset/superset_config.py +51 -0
  128. robotframework_chat-1.0.0/superset_example_dashboard.png +0 -0
  129. robotframework_chat-1.0.0/superset_example_dashboard_2_27.png +0 -0
  130. robotframework_chat-1.0.0/tasks.py +208 -0
  131. robotframework_chat-1.0.0/tests/conftest.py +100 -0
  132. robotframework_chat-1.0.0/tests/test_bootstrap_columns.py +166 -0
  133. robotframework_chat-1.0.0/tests/test_bump_version.py +406 -0
  134. robotframework_chat-1.0.0/tests/test_chat_log_listener.py +325 -0
  135. robotframework_chat-1.0.0/tests/test_container_manager.py +620 -0
  136. robotframework_chat-1.0.0/tests/test_db_listener.py +951 -0
  137. robotframework_chat-1.0.0/tests/test_discover_nodes.py +153 -0
  138. robotframework_chat-1.0.0/tests/test_discover_ollama.py +144 -0
  139. robotframework_chat-1.0.0/tests/test_docker_config.py +101 -0
  140. robotframework_chat-1.0.0/tests/test_docker_keywords.py +337 -0
  141. robotframework_chat-1.0.0/tests/test_dry_run_listener.py +194 -0
  142. robotframework_chat-1.0.0/tests/test_generate_ci_metadata.py +164 -0
  143. robotframework_chat-1.0.0/tests/test_generate_pipeline.py +151 -0
  144. robotframework_chat-1.0.0/tests/test_git_metadata.py +211 -0
  145. robotframework_chat-1.0.0/tests/test_git_metadata_listener.py +355 -0
  146. robotframework_chat-1.0.0/tests/test_grader.py +74 -0
  147. robotframework_chat-1.0.0/tests/test_host_info.py +91 -0
  148. robotframework_chat-1.0.0/tests/test_import_test_results.py +626 -0
  149. robotframework_chat-1.0.0/tests/test_keywords.py +171 -0
  150. robotframework_chat-1.0.0/tests/test_models.py +125 -0
  151. robotframework_chat-1.0.0/tests/test_ollama.py +471 -0
  152. robotframework_chat-1.0.0/tests/test_ollama_timestamp_listener.py +208 -0
  153. robotframework_chat-1.0.0/tests/test_pipeline_summary.py +224 -0
  154. robotframework_chat-1.0.0/tests/test_pre_run_modifier.py +198 -0
  155. robotframework_chat-1.0.0/tests/test_query_results.py +178 -0
  156. robotframework_chat-1.0.0/tests/test_release.py +130 -0
  157. robotframework_chat-1.0.0/tests/test_repo_metrics.py +141 -0
  158. robotframework_chat-1.0.0/tests/test_run_local_models.py +488 -0
  159. robotframework_chat-1.0.0/tests/test_safety_grader.py +170 -0
  160. robotframework_chat-1.0.0/tests/test_safety_keywords.py +318 -0
  161. robotframework_chat-1.0.0/tests/test_suite_config.py +164 -0
  162. robotframework_chat-1.0.0/tests/test_test_database.py +690 -0
  163. 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,5 @@
1
+
2
+ # Git LFS for test database
3
+ data/*.db filter=lfs diff=lfs merge=lfs -text
4
+ data/*.sqlite filter=lfs diff=lfs merge=lfs -text
5
+ data/*.sqlite3 filter=lfs diff=lfs merge=lfs -text
@@ -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