The fork takes its own name everywhere a user can see it: binaries (voculinux, voculinux-gui), desktop entry, autostart, tray, D-Bus namespace (com.voculinux.Voculinux, no alias for the old name), config/data/cache dirs, single-instance lock, IBus engine identity, tray icons, resource prefixes, VOCULINUX_* environment names, and the update-checker user agent. The internal Python module stays vocalinux and the distribution metadata keeps the upstream URLs as provenance. On first run a previous Vocalinux install's config.json, custom dictionary, and portal restore token are copied once into the new locations (new config always wins, no merge, no write-back); models re-resolve through the pinned-checksum download path. An offline naming-sweep test proves no old-name strings remain on user-visible surfaces outside the allowlist. Refs #18
63 lines
2.2 KiB
Python
63 lines
2.2 KiB
Python
"""The release documentation carries the upstream-fix intake policy.
|
|
|
|
Ticket #30 (spec #16): the fork's upstream-intake rule must live where
|
|
maintainers run releases from, not only on a decision ticket. A maintainer
|
|
following only docs/RELEASE_PROCESS.md must be able to state when intake
|
|
happens, when it freezes, what qualifies, and how conflicts resolve.
|
|
"""
|
|
|
|
from pathlib import Path
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parents[1]
|
|
RELEASE_PROCESS = REPO_ROOT / "docs" / "RELEASE_PROCESS.md"
|
|
|
|
|
|
def _policy() -> str:
|
|
assert RELEASE_PROCESS.is_file(), "docs/RELEASE_PROCESS.md is missing"
|
|
return RELEASE_PROCESS.read_text(encoding="utf-8")
|
|
|
|
|
|
def test_policy_states_when_intake_happens() -> None:
|
|
policy = _policy()
|
|
assert "release-preparation" in policy or "release preparation" in policy
|
|
assert "on demand" in policy or "on-demand" in policy
|
|
|
|
|
|
def test_policy_states_freeze_once_release_branch_opens() -> None:
|
|
policy = _policy()
|
|
assert "freeze" in policy.lower()
|
|
assert "release branch" in policy.lower()
|
|
assert "release-blocker" in policy or "release blocker" in policy
|
|
|
|
|
|
def test_policy_states_one_fix_per_pull_request_through_standard_gates() -> None:
|
|
policy = _policy()
|
|
assert "one upstream fix per" in policy.lower() or "one upstream fix" in policy.lower()
|
|
assert "pull request" in policy.lower()
|
|
|
|
|
|
def test_policy_states_conflict_resolution() -> None:
|
|
policy = _policy()
|
|
assert "keep" in policy.lower() and "upstream" in policy.lower()
|
|
assert "re-apply" in policy.lower() or "reapply" in policy.lower()
|
|
|
|
|
|
def test_policy_states_qualification_rule() -> None:
|
|
policy = _policy()
|
|
lowered = policy.lower()
|
|
assert "security advisory" in lowered # dependency/CI churn ports only then
|
|
assert "re-decided" in lowered # features are re-decided per release
|
|
assert "triage" in lowered # out-of-scope material is dropped at triage
|
|
|
|
|
|
def test_policy_names_retained_internal_module_name() -> None:
|
|
policy = _policy()
|
|
assert "voculinux" in policy
|
|
assert "internal" in policy.lower()
|
|
|
|
|
|
def test_policy_keeps_pull_request_flow_and_never_commit_to_main() -> None:
|
|
policy = _policy().lower()
|
|
assert "pull request" in policy
|
|
assert "never" in policy and "main" in policy
|