mirror of
https://github.com/jhd3197/ServerKit.git
synced 2026-10-24 03:58:05 +09:00
The split point was clean: git_service.py L602-881 (Gitea install/ lifecycle/config) and 18 of git_bp's 32 routes (lifecycle + repo browsing via GiteaAPIService) move into builtin-extensions/serverkit-git/backend/, mounted back at the same /api/v1/git prefix when the extension is installed. GiteaAPIService moves wholesale (its only consumer). The deploy pipeline stays core untouched: clone/pull/deploy/webhook-verify on GitService (all 5 core importers keep every method they call), the webhook routes including the unauthenticated signature-verified receiver, and the deployment routes. NginxService's gitea-config helpers stay core as a deliberate two-speed seam the extension calls. Upgrade parity: serverkit-git joins GATED_BUILTIN_SLUGS (auto-install only when the panel-managed serverkit-gitea application exists) and run_backend_acquisition now sweeps gated slugs too, so a panel that installed the frontend-only extension picks the backend up once. The core repo pickers keep three fail-soft getGitea* aliases that 404 into a clean 'not installed' state. Proving suite test_git_split.py (7 tests); live smoke: builtin install mounts all 18 routes. Render smoke green for the Git + Security pages. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
80 lines
2.8 KiB
Python
80 lines
2.8 KiB
Python
"""Prove the serverkit-git backend split (plan 52 Phase 6).
|
|
|
|
The Gitea self-host half (server lifecycle + repo browsing) moved into the
|
|
serverkit-git extension; the deploy-side git CLI operations and the webhook +
|
|
deployment routes stay core — they ARE the deploy pipeline and must never
|
|
depend on the extension. These tests pin the absent-extension shape.
|
|
"""
|
|
from app.services.git_service import GitService
|
|
|
|
|
|
GITEA_ROUTES = [
|
|
'/api/v1/git/status',
|
|
'/api/v1/git/requirements',
|
|
'/api/v1/git/install',
|
|
'/api/v1/git/repos',
|
|
'/api/v1/git/version',
|
|
]
|
|
|
|
CORE_GIT_ROUTES = [
|
|
'/api/v1/git/webhooks',
|
|
'/api/v1/git/webhooks/receive/<token>',
|
|
'/api/v1/git/deployments/app/<int:app_id>',
|
|
'/api/v1/git/deployments/<int:deployment_id>',
|
|
]
|
|
|
|
|
|
def test_gitea_routes_are_unrouted_without_extension(app):
|
|
rules = {r.rule for r in app.url_map.iter_rules()}
|
|
for path in GITEA_ROUTES:
|
|
assert path not in rules, f'{path}: Gitea route still in core'
|
|
|
|
|
|
def test_deploy_pipeline_routes_stay_core(app):
|
|
rules = {r.rule for r in app.url_map.iter_rules()}
|
|
for path in CORE_GIT_ROUTES:
|
|
assert path in rules, f'{path}: deploy-pipeline route missing from core'
|
|
|
|
|
|
def test_gitea_routes_404_before_auth(client):
|
|
for path in ('/api/v1/git/status', '/api/v1/git/repos'):
|
|
resp = client.get(path)
|
|
assert resp.status_code == 404, f'{path} -> {resp.status_code}'
|
|
|
|
|
|
def test_git_service_shed_the_gitea_half():
|
|
for gone in [
|
|
'get_gitea_status', 'install_gitea', 'uninstall_gitea',
|
|
'start_gitea', 'stop_gitea', 'restart_gitea',
|
|
'get_gitea_resource_requirements', 'GITEA_APP_NAME',
|
|
]:
|
|
assert not hasattr(GitService, gone), f'GitService.{gone} still exists'
|
|
|
|
|
|
def test_git_service_keeps_the_deploy_half():
|
|
"""The 5 core importers (apps/buildpacks/deploy/deployment/manifest_apply)
|
|
keep every method they call."""
|
|
for kept in [
|
|
'get_config', 'save_config', 'get_app_config', 'configure_deployment',
|
|
'remove_deployment', 'clone_repository', 'pull_changes',
|
|
'get_commit_info', 'deploy', '_run_script', 'verify_webhook',
|
|
'get_remote_branches', 'get_remote_branches_from_url', 'handle_webhook',
|
|
'get_deployment_history', 'get_git_status', 'log_webhook',
|
|
'get_webhook_logs',
|
|
]:
|
|
assert hasattr(GitService, kept), f'GitService.{kept} missing'
|
|
|
|
|
|
def test_gitea_api_service_left_core():
|
|
import pytest
|
|
with pytest.raises(ImportError):
|
|
__import__('app.services.gitea_api_service')
|
|
|
|
|
|
def test_nginx_gitea_helpers_stay_core():
|
|
"""Deliberate core seam (the WP two-speed shape): the extension's
|
|
install/uninstall call these; they must keep existing in core."""
|
|
from app.services.nginx_service import NginxService
|
|
for kept in ('create_gitea_config', 'remove_gitea_config', 'get_gitea_config'):
|
|
assert hasattr(NginxService, kept)
|