Updated CI/CD pipeline to run E2E tests on the ITSulu K8s cluster (itsulu-testing namespace) instead of using external Runboat service. .gitlab-ci.yml Changes: - Removed preview stage (no external Runboat dependency) - Removed e2e_tests dependency on runboat_preview - Updated e2e_tests job to run on K8s cluster: * Uses bitnami/kubectl image for K8s access * Configures kubectl with KUBE_CONFIG secret * Creates ephemeral E2E test job on K8s * initContainer: Creates test database from template * container: Installs Odoo, addon, Playwright, runs pytest * Waits for job completion and downloads report * Reports available in GitLab artifacts - Consolidated performance tests into unit_tests stage (same runner) K8s Job Manifest (inline YAML): - Namespace: itsulu-testing - Init container: postgres:15-alpine for DB setup - Test container: blog-publisher Docker image - Volumes: emptyDir for test results - TTL: 3600s (1 hour) for log retention - Uses existing secrets: test-db-info, gitlab-docker-creds e2e/conftest.py Changes: - Updated docstring: "Runs on ITSulu K8s cluster" - Changed RUNBOAT_TIMEOUT → K8S_TIMEOUT (300s) - Updated wait_for_odoo() to mention K8s namespace in error - Increased timeout: 180s → 300s (Odoo init + addon install) Required CI/CD Variables (now reduced): - KUBE_CONFIG: base64-encoded kubeconfig for itsulu-testing namespace * Only one variable needed (replaces 3 Runboat variables) * Must have permissions to create Jobs in itsulu-testing namespace Prerequisites (K8s cluster): - test-db-svc: PostgreSQL service in itsulu-testing namespace - odoo_template: Pre-seeded database - gitlab-docker-creds: Secret for image pull - test-runner: ServiceAccount with Job create permissions Benefits: - No external service dependency - Leverages existing ITSulu K8s infrastructure - Full isolation per test run (ephemeral jobs) - Persistent logs via TTL - Cost-effective (uses existing cluster) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> |
||
|---|---|---|
| .claude | ||
| addons/itsulu_blog_publisher | ||
| docs | ||
| e2e | ||
| templates | ||
| .gitlab-ci.yml | ||
| ARCHITECTURE.md | ||
| CLAUDE.md | ||
| conftest.py | ||
| conftest_runner.py | ||
| Dockerfile | ||
| LICENCE | ||
| main.py | ||
| PHASE2_ROADMAP.md | ||
| PHASE3_DEPLOYMENT_CHECKLIST.md | ||
| PHASE3_ROADMAP.md | ||
| README.md | ||
ITSulu Blog Publisher — Odoo 17 Addon
Automated blog post generation and publishing for Odoo 17 Community Edition, powered by generative AI (Anthropic Claude, OpenAI, Google Gemini, or Ollama).
Features
✨ Core Functionality
- On-Demand Generation — Wizard-driven blog post creation via backend form
- Scheduled Generation — Three configurable daily cron slots (morning, afternoon, evening)
- Multi-Provider LLM — Route requests to Anthropic Claude, OpenAI ChatGPT, Google Gemini, or local Ollama models
- SEO Automation — Auto-populate meta titles, descriptions, keywords, and tags
- Social Media Copy — Generate platform-specific posts for X, BlueSky, Mastodon, and LinkedIn
- Auto-Publish — Publish generated posts immediately or save as drafts for review
- Topic Queue — Priority-based topic queue for scheduled generation
- Notification Emails — Automated emails with generated content and social copy
- Generation Audit Trail — Complete logs with token usage, provider, model, and error tracking
- Error Recovery — Retry button on failed generation logs
🧠 Supported LLM Providers
| Provider | Model Examples | Config Parameter |
|---|---|---|
| Anthropic Claude | claude-sonnet-4-20250514, claude-opus-4-1 | itsulu_blog_publisher.anthropic_api_key |
| OpenAI | gpt-4o, gpt-4-turbo | itsulu_blog_publisher.openai_api_key |
| Google Gemini | gemini-2.0-flash, gemini-pro | itsulu_blog_publisher.gemini_api_key |
| Ollama | Any local model (mistral, llama2, etc.) | itsulu_blog_publisher.ollama_base_url |
📊 Test Coverage
Phase 2 Complete: 63 automated tests across 6 test files
| Test Suite | Count | Status |
|---|---|---|
| Unit Tests (TDD) | 48 | ✅ All Passing |
| Behavior Tests (BDD) | 15 | ✅ All Passing |
| Total | 63 | 100% ✅ |
Coverage Areas:
- Topic queue management (7 tests)
- Generation audit logs (8 tests)
- Social media copy (16 tests)
- Schedule slots (10 tests)
- LLM router dispatch (7 tests)
- E2E workflows (15 BDD scenarios)
Installation
Prerequisites
- Odoo 17.0 Community
- Python 3.10+
- PostgreSQL 13+
- pip packages:
requests,pytest-odoo,pytest-bdd
Steps
- Clone the repository into your Odoo addons directory:
git clone https://github.com/itsulu-odoo/itsulu-blog-publisher.git \
/path/to/odoo/addons/itsulu_blog_publisher
- Install Python dependencies:
pip install requests
- Install the addon in Odoo (UI or CLI):
odoo -d mydb -i itsulu_blog_publisher --stop-after-init
-
Configure API keys in Odoo Settings → Technical → Parameters:
itsulu_blog_publisher.anthropic_api_key(if using Claude)itsulu_blog_publisher.openai_api_key(if using OpenAI)itsulu_blog_publisher.gemini_api_key(if using Gemini)itsulu_blog_publisher.ollama_base_url(if using Ollama, e.g.,http://localhost:11434)
-
Configure notification emails in Settings:
itsulu_blog_publisher.notification_emails(comma-separated list)
Usage
1. Create a Blog Post On-Demand
- Go to Blog → Blog Publisher → Generate Now
- Enter topic/prompt
- Select LLM provider and model
- Choose auto-publish or draft
- Click Generate
The addon will:
- Call the selected LLM provider
- Create a blog.post with generated title, body, SEO fields
- Generate social media copy for enabled platforms
- Send notification email if published
- Log tokens used, provider, model, and generation time
2. Schedule Automatic Generation
- Go to Blog → Blog Publisher → Schedule Slots
- Create/configure 3 slots: Morning, Afternoon, Evening
- Set trigger time (UTC hours)
- Choose LLM provider and model per slot
- Enable auto-publish or save as draft
- Save and activate
The system will:
- Run active slots at configured times via cron
- Pull next topic from queue (if available) or LLM-chosen topic
- Publish immediately or save for review
- Send notification emails for published posts
3. Manage Topic Queue
- Go to Blog → Blog Publisher → Topics
- Create topics with title, notes, and priority (Urgent/High/Normal)
- Set state to "Pending"
- During generation, slots will consume pending topics in priority order
- Topics move to "Used" state after generation
4. Monitor Generation Logs
- Go to Blog → Blog Publisher → Generation Logs
- View all generation attempts (success/error)
- Check tokens used, provider, model, duration
- Retry failed generations using Retry button
Configuration
Settings
| Parameter | Type | Default | Description |
|---|---|---|---|
itsulu_blog_publisher.notification_emails |
Char | (empty) | Comma-separated email addresses for notifications |
itsulu_blog_publisher.anthropic_api_key |
Char | (empty) | Anthropic API key for Claude models |
itsulu_blog_publisher.openai_api_key |
Char | (empty) | OpenAI API key for ChatGPT models |
itsulu_blog_publisher.gemini_api_key |
Char | (empty) | Google Gemini API key |
itsulu_blog_publisher.ollama_base_url |
Char | (empty) | Base URL for local Ollama server |
Email Template
The addon includes a pre-configured email template (email_template_blog_published) that:
- Displays blog post title and metadata
- Includes social media copy for each enabled platform
- Links to the published post
- Shows generation stats (tokens, model, time)
Customize by editing the template in Email → Email Templates.
Architecture
Models
- itsulu.blog.topic — Topic queue with priority and state
- itsulu.blog.generation.log — Audit trail for all generation attempts
- itsulu.blog.post.social — Social media copy linked to blog posts
- itsulu.blog.schedule — Configurable cron slots for scheduled generation
Services
- llm_router.py — Dispatcher that routes requests to provider APIs
- anthropic_provider.py — Anthropic Claude integration
- openai_provider.py — OpenAI ChatGPT integration
- gemini_provider.py — Google Gemini integration
- ollama_provider.py — Local Ollama model integration
- image_router.py — Optional cover image generation (DALL·E, Imagen, Stable Diffusion)
Development
Running Tests
# All tests
pytest addons/itsulu_blog_publisher/tests/ -v
# Specific test file
pytest addons/itsulu_blog_publisher/tests/test_blog_topic.py -v
# Specific test
pytest addons/itsulu_blog_publisher/tests/test_blog_topic.py::TestBlogTopicPriority::test_get_next_topic_returns_highest_priority_pending_topic -v
# BDD scenarios only
pytest addons/itsulu_blog_publisher/tests/test_bdd_steps.py -v
TDD Workflow
This project follows strict TDD discipline (see CLAUDE.md):
- RED — Write failing test
- GREEN — Write minimum code to pass
- REFACTOR — Clean up while test stays green
- REPEAT — Next feature
Code Quality
Pre-commit hooks enforce:
- Black code formatting
- isort import sorting
- pylint-odoo linting
Run before committing:
pre-commit run --all-files
Troubleshooting
"Configuration error: API key not configured"
Cause: API key parameter not set in Settings
Solution: Go to Settings → Technical → Parameters and add the required key for your LLM provider
"Unknown provider: "
Cause: Provider name misspelled or provider not supported
Solution: Use one of: anthropic, openai, gemini, ollama
"No blog.post record was created"
Cause: LLM response parsing failed or validation error
Check: Generation log for error message; verify LLM response format
"No email sent for published post"
Cause: Notification email template not found or recipients not configured
Solution:
- Ensure template exists: Email → Email Templates → "Blog Post Published"
- Set notification emails: Settings → Technical → Parameters →
itsulu_blog_publisher.notification_emails
Documentation
- CLAUDE.md — Complete TDD framework, testing patterns, troubleshooting
- ARCHITECTURE.md — System design, data flow, API contracts
- PHASE2_ROADMAP.md — Phase 2 implementation status
License
MIT License. See LICENSE for details.
Support
For issues, feature requests, or questions, open an issue on GitLab:
https://gitlab.com/itsulu-odoo/itsulu-blog-publisher/issues
Roadmap
Phase 3 (Runboat E2E)
- Playwright end-to-end scenarios
- UI-driven generation workflow testing
- Multi-user collaboration scenarios
Phase 4 (Performance & Scale)
- Query optimization (N+1 detection)
- Batch generation for multiple topics
- Template caching and pre-rendering
- Performance benchmarks (throughput, latency)
Current Status: Phase 2 Complete ✅ (63/63 tests passing)
Last Updated: 2026-05-30
Maintainer: Nicholas Riegel (nicholasr@itsulu.com)