Skip to content

Implement boost_endpoint#50

Merged
wpak-ai merged 4 commits into
cppalliance:developfrom
whisper67265:feature/boost-endpoint
May 21, 2026
Merged

Implement boost_endpoint#50
wpak-ai merged 4 commits into
cppalliance:developfrom
whisper67265:feature/boost-endpoint

Conversation

@whisper67265
Copy link
Copy Markdown
Collaborator

@whisper67265 whisper67265 commented May 21, 2026

Close #42.
Close #43.
Close #44.
Close #45.

Summary by CodeRabbit

  • New Features

    • Background service added to scan repos and synchronize translation components; add/update endpoint now enqueues a background task and returns 202 with a task ID.
  • Improvements

    • Help text for organization field shortened.
    • Extensions input trims whitespace and accepts blank entries to avoid accidental filtering.
    • Endpoint now advertises plugin version and supported capabilities.
  • Tests

    • Updated to cover async task dispatch, per-language processing, and cloning/failure scenarios.
  • Chores

    • Coverage config updated to omit an endpoint test slice.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 232dc10c-dd3c-4db2-85d0-9fe655d98e6a

📥 Commits

Reviewing files that changed from the base of the PR and between ba83f71 and 6e5bde7.

📒 Files selected for processing (1)
  • src/boost_weblate/endpoint/services.py
💤 Files with no reviewable changes (1)
  • src/boost_weblate/endpoint/services.py

📝 Walkthrough

Walkthrough

Adds a Django-backed BoostComponentService that scans cloned repos to create/update/delete Weblate projects/components/translations, moves add-or-update work to a Celery task, updates DRF views to report version/capabilities and enqueue tasks, and adjusts serializers, coverage, and tests accordingly.

Changes

Async Background Component Sync Feature

Layer / File(s) Summary
Request schema and coverage config
pyproject.toml, src/boost_weblate/endpoint/serializers.py
organization help text simplified; extensions list items allow blank and are normalized/trimmed; coverage omit adds */endpoint/services.py.
Service foundation: constants, truncation, extension mapping, cloning, scanning
src/boost_weblate/endpoint/services.py
Module docstring, truncation constants and SHA-256-based truncation helpers, extension→format mapping from FILE_FORMATS, service init/extension normalization, clone_repository with timeout handling, and scan_documentation_files filtering supported extensions and excluding translation-stem/root files.
Project & component CRUD, repo sync and translation prep
src/boost_weblate/endpoint/services.py
get_or_create_project with atomic create/post_create; create_or_update_component upserts components with truncated identifiers and VCS settings; _do_update_git_only and _sync_component_for_translation handle repo updates and template preparation.
Language addition and permission checks
src/boost_weblate/endpoint/services.py
add_language_to_component enforces translation.add/translation.add_more checks, filters against available languages, runs create_translations_immediate, validates can_add_new_language, and calls add_new_language.
Component deletion, per-submodule orchestration, and process_all
src/boost_weblate/endpoint/services.py
_delete_component_and_commit_removal stages/removes removed translation files and commits/pushes when applicable; process_submodule orchestrates clone→scan→CRUD per submodule; process_all aggregates results and ensures temp-dir cleanup.
Celery task and view integration
src/boost_weblate/endpoint/tasks.py, src/boost_weblate/endpoint/views.py
New boost_add_or_update_task builds authenticated request context, runs BoostComponentService.process_all per language, and returns per-language results; views advertise package version (fallback "0.0.0") and capabilities, and AddOrUpdateView.post enqueues the task and returns 202 Accepted with task_id.
Tests for services, tasks, and views
tests/endpoint/test_services.py, tests/endpoint/test_views.py
Updates test expectations: clone-failure handling, info endpoint capability/version checks, background-task enqueuing and parameters, per-language task distribution, version fallback, and exception propagation in tasks.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant DRFView
  participant CeleryTask
  participant BoostComponentService
  participant WeblateDB
  Client->>DRFView: POST /add-or-update (validated)
  DRFView->>CeleryTask: boost_add_or_update_task.delay(args with user_id)
  CeleryTask->>BoostComponentService: process_all(submodules, user, request)
  BoostComponentService->>WeblateDB: get_or_create Project / Component / add_new_language
  BoostComponentService->>WeblateDB: delete or update component records
  CeleryTask-->>DRFView: task_id (immediate)
  DRFView-->>Client: 202 Accepted with task_id
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • wpak-ai
  • henry0816191

Poem

🐰 I hop through repos, trim slugs short and neat,
I spin SHA tails so names stay unique and sweet.
Tasks buzz in background while I scan each page,
Languages land as components take stage.
Celery hums — translations find their new home.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 64.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Implement boost_endpoint' accurately describes the main objective—implementing the boost endpoint feature across views, tasks, and services as required by issues #42-45.
Linked Issues check ✅ Passed All linked issues (#42, #43, #44, #45) are fully addressed: DRF views with async task dispatch (202), Celery task infrastructure, component helpers with truncation, and project/component/translation flows are all implemented.
Out of Scope Changes check ✅ Passed All changes align with the four linked issues. Configuration updates (pyproject.toml), serializer enhancements, service implementation, task creation, view refactoring, and corresponding tests are all directly required by the feature scope.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/boost_weblate/endpoint/serializers.py`:
- Around line 35-36: The extensions ListField currently allows blank strings
which makes [""] be treated as a non-empty filter by
BoostComponentService.get_supported_extensions(); update the serializer to
either set child=serializers.CharField(allow_blank=False) or (preferred)
add/modify validate_extensions(self, value) to strip/filter out
empty/whitespace-only strings (e.g., [v for v in value if v.strip()]) and return
the cleaned list so that an all-empty submission falls back to "use all
supported extensions" behavior when passed to
BoostComponentService.get_supported_extensions().

In `@src/boost_weblate/endpoint/services.py`:
- Around line 819-830: The permission check builds the wrong project slug
(boost-{submodule}-documentation) so existing projects created by
get_or_create_project (which uses boost-{submodule}-documentation-{lang_code})
are never found; update the slug construction in the permission gate to include
the language code the same way get_or_create_project does (use the same
lang_code variable/logic or call/get the exact slug from get_or_create_project)
so existing_project lookup and the subsequent user.has_perm("project.edit",
existing_project) check target the correct Project instance before falling back
to project.add; modify the code around project_slug, existing_project, and their
permission checks accordingly.
- Around line 842-850: The loop over configs currently ignores cases where
create_or_update_component(...) returns None but later the submodule is marked
success regardless; change logic so when create_or_update_component(project,
submodule, config, ...) returns None you mark the submodule as failed (e.g., set
success = False and increment a failure counter or add to
result["components_failed"]) and do not increment
components_created/components_updated; ensure the final assignment that sets
success (the variable used around line 865) is only true if at least one
component actually succeeded (was_created True or updated), and propagate
failure when all configs returned None so the async task sees the failure.
- Around line 404-430: The get_or_create branch only applies component_defaults
on create, so when created is False you must merge in changed fields; in the
else branch (after "Component exists") compare and set each field that can
change (e.g. name, repo, push, branch, filemask, template, new_base, file_format
and push_branch) against component_defaults or the incoming values (from
component_defaults/component_slug/repo/… in this scope), append their attribute
names to update_fields when different, then call
component.save(update_fields=update_fields) if any changes; preserve existing
lines that set component.acting_user and the current push_branch logic and
ensure not to call post_create or _sync_component_for_translation in the
non-created path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c18aa138-5b3d-49a4-9802-b6888ebb3e3e

📥 Commits

Reviewing files that changed from the base of the PR and between f0e884b and 5b04968.

📒 Files selected for processing (7)
  • pyproject.toml
  • src/boost_weblate/endpoint/serializers.py
  • src/boost_weblate/endpoint/services.py
  • src/boost_weblate/endpoint/tasks.py
  • src/boost_weblate/endpoint/views.py
  • tests/endpoint/test_services.py
  • tests/endpoint/test_views.py

Comment thread src/boost_weblate/endpoint/serializers.py
Comment thread src/boost_weblate/endpoint/services.py
Comment thread src/boost_weblate/endpoint/services.py
Comment thread src/boost_weblate/endpoint/services.py
Comment thread src/boost_weblate/endpoint/services.py
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/boost_weblate/endpoint/services.py (1)

844-877: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Propagate language-add failures into submodule success.

Line 848 only treats None as a failed config, but create_or_update_component() still returns a non-None component when add_language_to_component() returns False. That means permission/template/language-availability failures are counted as created/updated here, and Line 872 can mark the submodule successful even though the requested translation was never added.

Please return the add-language outcome from create_or_update_component() (or return None on that path) and keep success false whenever any scanned config failed end-to-end.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/boost_weblate/endpoint/services.py` around lines 844 - 877, The loop
treats any non-None component as success even when create_or_update_component()
internally failed to add the requested language (via
add_language_to_component()), so propagate that failure: change
create_or_update_component() to return an explicit success flag for the full
end-to-end config (or return None when add_language_to_component() returns
False) and update this loop to treat that flag as a failure (increment
components_failed and append error) instead of counting it as created/updated;
ensure truncate_component_slug, project.component_set iteration and
_delete_component_and_commit_removal logic remain unchanged while using the new
return shape from create_or_update_component().
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/boost_weblate/endpoint/services.py`:
- Around line 844-877: The loop treats any non-None component as success even
when create_or_update_component() internally failed to add the requested
language (via add_language_to_component()), so propagate that failure: change
create_or_update_component() to return an explicit success flag for the full
end-to-end config (or return None when add_language_to_component() returns
False) and update this loop to treat that flag as a failure (increment
components_failed and append error) instead of counting it as created/updated;
ensure truncate_component_slug, project.component_set iteration and
_delete_component_and_commit_removal logic remain unchanged while using the new
return shape from create_or_update_component().

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b42485d9-f526-42e9-a978-25e5b9ac57e4

📥 Commits

Reviewing files that changed from the base of the PR and between 5b04968 and ba83f71.

📒 Files selected for processing (2)
  • src/boost_weblate/endpoint/serializers.py
  • src/boost_weblate/endpoint/services.py

@whisper67265
Copy link
Copy Markdown
Collaborator Author

@coderabbitai, resume

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

@whisper67265: Sure! Resuming automatic reviews for this PR.

✅ Actions performed

Reviews resumed.

@whisper67265 whisper67265 requested a review from henry0816191 May 21, 2026 15:56
Comment thread src/boost_weblate/endpoint/services.py Outdated
@whisper67265 whisper67265 requested a review from wpak-ai May 21, 2026 19:35
@wpak-ai wpak-ai merged commit d6c55ad into cppalliance:develop May 21, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants