alloc-context 0.1.1__tar.gz → 0.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. {alloc_context-0.1.1 → alloc_context-0.1.2}/PKG-INFO +1 -1
  2. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloc_context.egg-info/PKG-INFO +1 -1
  3. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/__init__.py +1 -1
  4. {alloc_context-0.1.1 → alloc_context-0.1.2}/pyproject.toml +1 -1
  5. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_bump_version.py +2 -2
  6. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_workflows.py +64 -39
  7. {alloc_context-0.1.1 → alloc_context-0.1.2}/LICENSE +0 -0
  8. {alloc_context-0.1.1 → alloc_context-0.1.2}/README.md +0 -0
  9. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloc_context.egg-info/SOURCES.txt +0 -0
  10. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloc_context.egg-info/dependency_links.txt +0 -0
  11. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloc_context.egg-info/entry_points.txt +0 -0
  12. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloc_context.egg-info/requires.txt +0 -0
  13. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloc_context.egg-info/top_level.txt +0 -0
  14. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/__main__.py +0 -0
  15. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/config.py +0 -0
  16. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/horizon.py +0 -0
  17. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/__init__.py +0 -0
  18. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/cf_benchmarks.py +0 -0
  19. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/cf_history.py +0 -0
  20. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/coinbase_client.py +0 -0
  21. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/coinbase_portfolio.py +0 -0
  22. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/coingecko.py +0 -0
  23. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/coinmarketcap.py +0 -0
  24. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/env_keys.py +0 -0
  25. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/etf_flows.py +0 -0
  26. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/exchange/__init__.py +0 -0
  27. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/exchange/coinbase_adapter.py +0 -0
  28. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/exchange/kraken_adapter.py +0 -0
  29. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/exchange/live.py +0 -0
  30. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/exchange/portfolio.py +0 -0
  31. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/exchange/registry.py +0 -0
  32. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/exchange/types.py +0 -0
  33. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/exchange_http.py +0 -0
  34. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/fear_greed.py +0 -0
  35. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/fred.py +0 -0
  36. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/http_errors.py +0 -0
  37. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/kalshi.py +0 -0
  38. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/kalshi_api.py +0 -0
  39. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/kalshi_client.py +0 -0
  40. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/kalshi_files.py +0 -0
  41. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/kalshi_state.py +0 -0
  42. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/kraken_client.py +0 -0
  43. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/kraken_portfolio.py +0 -0
  44. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/macro_calendar.py +0 -0
  45. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/macro_normalize.py +0 -0
  46. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/market_snapshots.py +0 -0
  47. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/outcome.py +0 -0
  48. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/parse_helpers.py +0 -0
  49. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/ingest/runner.py +0 -0
  50. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/mcp/__init__.py +0 -0
  51. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/mcp/assets.py +0 -0
  52. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/mcp/bazaar.py +0 -0
  53. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/mcp/contracts.py +0 -0
  54. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/mcp/handlers.py +0 -0
  55. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/mcp/http.py +0 -0
  56. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/mcp/payment_middleware.py +0 -0
  57. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/mcp/server.py +0 -0
  58. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/mcp/staleness.py +0 -0
  59. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/mcp/validation.py +0 -0
  60. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/mcp/x402_bazaar_dynamic.py +0 -0
  61. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/mcp/x402_config.py +0 -0
  62. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/mcp/x402_pricing.py +0 -0
  63. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/mcp/x402_stables.py +0 -0
  64. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/rollup/__init__.py +0 -0
  65. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/rollup/band.py +0 -0
  66. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/rollup/breadth.py +0 -0
  67. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/rollup/cf_math.py +0 -0
  68. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/rollup/cluster.py +0 -0
  69. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/rollup/cluster_config.py +0 -0
  70. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/rollup/comparison.py +0 -0
  71. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/rollup/context.py +0 -0
  72. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/rollup/delta.py +0 -0
  73. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/rollup/etf.py +0 -0
  74. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/rollup/fear_greed.py +0 -0
  75. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/rollup/macro.py +0 -0
  76. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/rollup/portfolio.py +0 -0
  77. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/rollup/rebalance.py +0 -0
  78. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/rollup/regime.py +0 -0
  79. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/rollup/sentiment.py +0 -0
  80. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/rollup/snapshots.py +0 -0
  81. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/rollup/tape.py +0 -0
  82. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/status_report.py +0 -0
  83. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/store/__init__.py +0 -0
  84. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/store/db.py +0 -0
  85. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/store/jsonutil.py +0 -0
  86. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/store/meta.py +0 -0
  87. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/store/retention.py +0 -0
  88. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/store/status.py +0 -0
  89. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/timeutil.py +0 -0
  90. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/x402_production_check.py +0 -0
  91. {alloc_context-0.1.1 → alloc_context-0.1.2}/alloccontext/x402_smoke_redact.py +0 -0
  92. {alloc_context-0.1.1 → alloc_context-0.1.2}/setup.cfg +0 -0
  93. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_adr005_ingest.py +0 -0
  94. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_backup_sqlite.py +0 -0
  95. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_coinbase_portfolio.py +0 -0
  96. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_context_snapshots.py +0 -0
  97. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_db_schema.py +0 -0
  98. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_deploy.py +0 -0
  99. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_dev_stack.py +0 -0
  100. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_etf.py +0 -0
  101. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_exchanges_config.py +0 -0
  102. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_fear_greed.py +0 -0
  103. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_fred.py +0 -0
  104. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_horizon.py +0 -0
  105. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_ingest_outcome.py +0 -0
  106. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_ingest_runner.py +0 -0
  107. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_kalshi_api.py +0 -0
  108. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_kraken_portfolio.py +0 -0
  109. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_macro.py +0 -0
  110. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_market_breadth.py +0 -0
  111. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_mcp_assets_regime.py +0 -0
  112. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_mcp_bazaar.py +0 -0
  113. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_mcp_contracts.py +0 -0
  114. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_mcp_freshness.py +0 -0
  115. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_mcp_handlers.py +0 -0
  116. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_mcp_health.py +0 -0
  117. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_mcp_http_lifecycle.py +0 -0
  118. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_mcp_live_portfolio.py +0 -0
  119. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_mcp_server.py +0 -0
  120. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_mcp_validation.py +0 -0
  121. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_mcp_x402.py +0 -0
  122. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_mcp_x402_http.py +0 -0
  123. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_mcp_x402_pricing.py +0 -0
  124. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_mcp_x402_stables.py +0 -0
  125. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_qa_ingest_store.py +0 -0
  126. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_rebalance.py +0 -0
  127. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_rollup.py +0 -0
  128. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_scaffold.py +0 -0
  129. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_script_runtime.py +0 -0
  130. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_security_hardening.py +0 -0
  131. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_server_json.py +0 -0
  132. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_snapshots_and_delta.py +0 -0
  133. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_status_report.py +0 -0
  134. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_x402_bazaar_dynamic.py +0 -0
  135. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_x402_production_check.py +0 -0
  136. {alloc_context-0.1.1 → alloc_context-0.1.2}/tests/test_x402_smoke_redact.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alloc-context
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: AllocContext — BTC/ETH allocation context, drift, and rebalance facts
5
5
  License: MIT
6
6
  Project-URL: Homepage, https://github.com/negillett/alloc-context
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alloc-context
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: AllocContext — BTC/ETH allocation context, drift, and rebalance facts
5
5
  License: MIT
6
6
  Project-URL: Homepage, https://github.com/negillett/alloc-context
@@ -1,3 +1,3 @@
1
1
  """AllocContext — BTC/ETH allocation context and rebalance facts."""
2
2
 
3
- __version__ = "0.1.1"
3
+ __version__ = "0.1.2"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "alloc-context"
3
- version = "0.1.1"
3
+ version = "0.1.2"
4
4
  description = "AllocContext — BTC/ETH allocation context, drift, and rebalance facts"
5
5
  readme = "README.md"
6
6
  license = { text = "MIT" }
@@ -45,7 +45,7 @@ def test_resolve_target_version_rejects_downgrade():
45
45
 
46
46
 
47
47
  def test_resolve_target_version_rejects_unchanged_exact():
48
- with pytest.raises(ValueError, match="tag-only"):
48
+ with pytest.raises(ValueError, match="already"):
49
49
  resolve_target_version(current="0.1.0", bump=None, exact="0.1.0")
50
50
 
51
51
 
@@ -55,7 +55,7 @@ def test_check_version_passes_when_in_sync(tmp_path: Path):
55
55
  dest = tmp_path / rel
56
56
  dest.parent.mkdir(parents=True, exist_ok=True)
57
57
  shutil.copy(src, dest)
58
- check_version("0.1.0", root=tmp_path)
58
+ check_version(read_current_version(REPO_ROOT), root=tmp_path)
59
59
 
60
60
 
61
61
  def test_check_version_fails_when_out_of_sync(tmp_path: Path):
@@ -55,65 +55,90 @@ def test_bump_release_workflow_removed():
55
55
  assert not (WORKFLOWS_DIR / "bump-release.yml").exists()
56
56
 
57
57
 
58
- def test_release_workflow_unified_pipeline():
59
- workflow = _load_workflow("release.yml")
58
+ def test_release_pr_workflow_opens_pr():
59
+ workflow = _load_workflow("release-pr.yml")
60
60
  on = _workflow_on(workflow)
61
61
  assert "workflow_dispatch" in on
62
62
  inputs = on["workflow_dispatch"]["inputs"]
63
63
  assert "bump" in inputs
64
64
  assert "exact_version" in inputs
65
- assert "tag_only" in inputs
66
- assert on["push"]["tags"] == ["v[0-9]+.[0-9]+.[0-9]+"]
67
- assert workflow["concurrency"]["group"].startswith("release-")
65
+ # Opening a release PR must not publish or deploy.
66
+ assert "tag_only" not in inputs
68
67
 
69
- jobs = workflow["jobs"]
70
- assert jobs["deploy"]["needs"] == ["validate-version", "publish-pypi"]
71
- assert jobs["finalize-tag"]["needs"] == [
72
- "prepare",
73
- "validate-version",
74
- "publish-pypi",
75
- "publish-mcp-registry",
76
- "deploy",
77
- ]
68
+ steps = _job_steps(workflow, "open-release-pr")
69
+ runs = [step.get("run", "") for step in steps]
70
+ assert any("scripts/bump_version.py" in run for run in runs)
71
+ assert any("git push -u origin" in run and "release/v" in run for run in runs)
72
+ assert any("gh pr create" in run for run in runs)
78
73
 
79
- prepare_runs = [step.get("run", "") for step in _job_steps(workflow, "prepare")]
80
- assert any("scripts/bump_version.py" in run for run in prepare_runs)
81
- assert any("release/v" in run and "git push" in run for run in prepare_runs)
82
74
 
83
- validate_runs = [
84
- step.get("run", "") for step in _job_steps(workflow, "validate-version")
85
- ]
86
- assert any("scripts/bump_version.py --check" in run for run in validate_runs)
75
+ def test_release_workflow_triggers_on_main_push_only():
76
+ workflow = _load_workflow("release.yml")
77
+ on = _workflow_on(workflow)
78
+ assert on["push"]["branches"] == ["main"]
79
+ # No manual or tag trigger — releases are driven by merges to main.
80
+ assert "workflow_dispatch" not in on
81
+ assert "tags" not in on["push"]
82
+ assert workflow["concurrency"]["group"].startswith("release-")
87
83
 
88
- deploy_steps = _job_steps(workflow, "deploy")
89
- names = [step.get("name", "") for step in deploy_steps]
90
- assert "Rsync to VPS" in names
91
- assert "Install on VPS" in names
92
- install = next(step for step in deploy_steps if step.get("name") == "Install on VPS")
93
- assert "deploy/remote-install.sh" in install["run"]
84
+
85
+ def test_release_workflow_gates_on_untagged_version():
86
+ workflow = _load_workflow("release.yml")
87
+ check = workflow["jobs"]["check"]
88
+ assert check["outputs"]["release"]
89
+ check_runs = [step.get("run", "") for step in _job_steps(workflow, "check")]
90
+ assert any("--current" in run for run in check_runs)
91
+ assert any("ls-remote --tags" in run for run in check_runs)
92
+ # Every downstream job is conditioned on the release decision.
93
+ for job_name in ("test", "publish-pypi", "publish-mcp-registry", "deploy", "finalize"):
94
+ cond = workflow["jobs"][job_name]["if"]
95
+ assert "needs.check.outputs.release" in cond
96
+
97
+
98
+ def test_release_workflow_publishes_then_deploys_then_finalizes():
99
+ workflow = _load_workflow("release.yml")
100
+ jobs = workflow["jobs"]
94
101
 
95
102
  publish_steps = _job_steps(workflow, "publish-pypi")
96
103
  publish_runs = [step.get("run", "") for step in publish_steps]
97
104
  assert any("python -m build" in run for run in publish_runs)
98
- assert any(
99
- step.get("uses", "").startswith("pypa/gh-action-pypi-publish")
105
+ pypi_step = next(
106
+ step
100
107
  for step in publish_steps
108
+ if step.get("uses", "").startswith("pypa/gh-action-pypi-publish")
101
109
  )
110
+ # Idempotent re-runs must not fail on an already-uploaded version.
111
+ assert pypi_step["with"]["skip-existing"] is True
102
112
 
103
- registry = workflow["jobs"]["publish-mcp-registry"]
104
- assert registry["needs"] in (
105
- ["publish-pypi", "validate-version"],
106
- ["validate-version", "publish-pypi"],
107
- )
108
113
  registry_runs = [
109
114
  step.get("run", "") for step in _job_steps(workflow, "publish-mcp-registry")
110
115
  ]
111
- assert any("mcp-publisher publish" in run for run in registry_runs)
116
+ assert any("publish-mcp-registry.sh" in run for run in registry_runs)
117
+
118
+ deploy_steps = _job_steps(workflow, "deploy")
119
+ names = [step.get("name", "") for step in deploy_steps]
120
+ assert "Rsync to VPS" in names
121
+ assert "Install on VPS" in names
122
+ install = next(step for step in deploy_steps if step.get("name") == "Install on VPS")
123
+ assert "deploy/remote-install.sh" in install["run"]
124
+
125
+ finalize = jobs["finalize"]
126
+ assert set(finalize["needs"]) == {
127
+ "check",
128
+ "publish-pypi",
129
+ "publish-mcp-registry",
130
+ "deploy",
131
+ }
132
+ finalize_runs = [step.get("run", "") for step in _job_steps(workflow, "finalize")]
133
+ assert any("git tag" in run for run in finalize_runs)
134
+ assert any("gh release create" in run for run in finalize_runs)
112
135
 
113
- finalize = workflow["jobs"]["finalize-tag"]
114
- assert "publish-mcp-registry" in finalize["needs"]
115
136
 
116
- assert "sync-main" in workflow["jobs"]
137
+ def test_release_workflow_drops_branch_juggling_jobs():
138
+ workflow = _load_workflow("release.yml")
139
+ jobs = workflow["jobs"]
140
+ for removed in ("gate", "prepare", "validate-version", "finalize-tag", "sync-main"):
141
+ assert removed not in jobs
117
142
 
118
143
 
119
144
  def test_publish_mcp_registry_workflow_dispatch():
@@ -122,4 +147,4 @@ def test_publish_mcp_registry_workflow_dispatch():
122
147
  assert "workflow_dispatch" in on
123
148
  runs = [step.get("run", "") for step in _job_steps(workflow, "publish")]
124
149
  assert any("install-mcp-publisher" in run for run in runs)
125
- assert any("github-oidc" in run for run in runs)
150
+ assert any("publish-mcp-registry.sh" in run for run in runs)
File without changes
File without changes
File without changes