Merge pull request #359 from AIOSAI/citizen/drone
feat(drone): switch merge_plugin from --squash to --merge (straight merge commits only)
This commit is contained in:
@@ -127,6 +127,21 @@
|
||||
"file": "apps/plugins/hook_sounds/hook_sounds_plugin.py",
|
||||
"standard": "trigger",
|
||||
"reason": "Simple toggle plugin — creates/removes a flag file. No state changes that warrant trigger events."
|
||||
},
|
||||
{
|
||||
"file": "tests/test_devpulse_plugins.py",
|
||||
"standard": "architecture",
|
||||
"reason": "Test file — intentionally outside 3-layer structure. tests/ is a peer of apps/, not part of it."
|
||||
},
|
||||
{
|
||||
"file": "tests/test_devpulse_plugins.py",
|
||||
"standard": "deep_nesting",
|
||||
"reason": "Test mock side_effect closures are necessarily nested inside test methods. Refactoring to top-level breaks test locality."
|
||||
},
|
||||
{
|
||||
"file": "tests/test_devpulse_plugins.py",
|
||||
"standard": "documentation",
|
||||
"reason": "Test methods and mock helpers in this file are pre-existing without docstrings. Class docstrings describe intent; per-method docs would be noise."
|
||||
}
|
||||
],
|
||||
"notes": {
|
||||
|
||||
@@ -417,8 +417,8 @@ def get_help(command: str | None = None) -> str:
|
||||
)
|
||||
if command == "merge":
|
||||
return (
|
||||
"git merge <PR#> — Squash-merge a PR and sync local main (devpulse only)\n"
|
||||
" Runs gh pr merge --squash --delete-branch, then git pull --rebase.\n"
|
||||
"git merge <PR#> — Merge a PR and sync local main (devpulse only)\n"
|
||||
" Runs gh pr merge --merge --delete-branch, then git pull --rebase.\n"
|
||||
)
|
||||
if command == "smart-sync":
|
||||
return (
|
||||
@@ -437,7 +437,7 @@ def get_help(command: str | None = None) -> str:
|
||||
"Commands:\n"
|
||||
" pr <description> Create a PR with scoped changes\n"
|
||||
" system-pr <desc> Create a system-wide PR (devpulse only)\n"
|
||||
" merge <PR#> Squash-merge a PR (devpulse only)\n"
|
||||
" merge <PR#> Merge a PR (devpulse only)\n"
|
||||
" smart-sync Fetch + rebase if behind (devpulse only)\n"
|
||||
" fix Fix broken git states (devpulse only)\n"
|
||||
" status Show git status for your branch\n"
|
||||
@@ -462,7 +462,7 @@ def get_introspective() -> str:
|
||||
" plugins/devpulse_ops/\n"
|
||||
" - auth.py (verify_caller — passport-based authorization)\n"
|
||||
" - pr_plugin.py (create_system_pr — system-wide PR workflow)\n"
|
||||
" - merge_plugin.py (merge_pr — squash-merge PR + sync)\n"
|
||||
" - merge_plugin.py (merge_pr — merge PR + sync)\n"
|
||||
" - sync_plugin.py (smart_sync — fetch + rebase if behind)\n"
|
||||
" - fix_plugin.py (fix_git_state — detect/fix broken states)\n"
|
||||
"\n"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
# =================== AIPass ====================
|
||||
# Name: merge_plugin.py
|
||||
# Description: Squash-merge a PR and sync local main
|
||||
# Description: Merge a PR and sync local main
|
||||
# Version: 1.0.0
|
||||
# Created: 2026-03-30
|
||||
# Modified: 2026-03-30
|
||||
# =============================================
|
||||
|
||||
"""Squash-merge a PR and sync local main.
|
||||
"""Merge a PR and sync local main.
|
||||
|
||||
Squash-merges the given PR number via ``gh``, deletes the remote branch,
|
||||
Merges the given PR number via ``gh``, deletes the remote branch,
|
||||
pulls to sync local main, and returns the merge commit hash and PR title.
|
||||
Only authorized callers (verified via :mod:`auth`) may invoke this.
|
||||
"""
|
||||
@@ -23,7 +23,7 @@ from aipass.drone.apps.handlers.git.lock_handler import find_repo_root
|
||||
|
||||
|
||||
def merge_pr(pr_number: str, caller: str) -> dict:
|
||||
"""Squash-merge a PR and sync local main.
|
||||
"""Merge a PR and sync local main.
|
||||
|
||||
Args:
|
||||
pr_number: The PR number to merge (e.g. ``"42"``).
|
||||
@@ -43,9 +43,9 @@ def merge_pr(pr_number: str, caller: str) -> dict:
|
||||
}
|
||||
|
||||
try:
|
||||
# Step 1: Squash-merge the PR
|
||||
# Step 1: Merge the PR
|
||||
merge = subprocess.run(
|
||||
["gh", "pr", "merge", pr_number, "--squash", "--delete-branch"],
|
||||
["gh", "pr", "merge", pr_number, "--merge", "--delete-branch"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
cwd=str(repo_root),
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
Creates PRs from local main commits that are ahead of origin/main.
|
||||
If there are uncommitted tracked changes, commits them first (like a
|
||||
normal commit), then creates a feature branch at main's current tip,
|
||||
pushes it, and opens a PR. Local main is never moved — after squash-
|
||||
merge and pull, git detects the commits are already applied and skips
|
||||
them cleanly.
|
||||
pushes it, and opens a PR. Local main is never moved — after the
|
||||
straight merge and pull, local commits are already in origin/main's
|
||||
ancestry via the merge commit, so git pull fast-forwards cleanly.
|
||||
|
||||
Only authorized callers (verified via :mod:`auth`) may invoke this.
|
||||
"""
|
||||
@@ -59,8 +59,9 @@ def create_system_pr(description: str, caller: str) -> dict:
|
||||
(just a normal commit). Then creates a feature branch at main's tip,
|
||||
pushes it, and opens a PR. Local main is never artificially moved.
|
||||
|
||||
After GitHub squash-merges the PR, ``git pull --rebase`` detects that
|
||||
the local commits are already applied and skips them cleanly.
|
||||
After GitHub merges the PR, local commits are already in origin/main's
|
||||
ancestry via the merge commit — ``git pull --rebase`` fast-forwards
|
||||
cleanly without replaying any commits.
|
||||
|
||||
Args:
|
||||
description: Short description for the PR title/commit.
|
||||
|
||||
@@ -119,7 +119,7 @@ class TestAuthDenialFix:
|
||||
|
||||
|
||||
class TestMergePrHappyPath:
|
||||
"""merge_pr should squash-merge, pull, and return commit + title."""
|
||||
"""merge_pr should merge, pull, and return commit + title."""
|
||||
|
||||
@patch("aipass.drone.apps.plugins.devpulse_ops.merge_plugin.find_repo_root")
|
||||
@patch("aipass.drone.apps.plugins.devpulse_ops.merge_plugin.subprocess.run")
|
||||
@@ -496,7 +496,7 @@ class TestGitModuleRouting:
|
||||
from aipass.drone.apps.modules.git_module import get_help
|
||||
|
||||
help_text = get_help("merge")
|
||||
assert "squash" in help_text.lower() or "Squash" in help_text
|
||||
assert "merge" in help_text.lower()
|
||||
|
||||
def test_get_help_smart_sync_specific(self) -> None:
|
||||
from aipass.drone.apps.modules.git_module import get_help
|
||||
|
||||
Reference in New Issue
Block a user