sase-github 0.2.8__tar.gz → 0.2.9__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.
- sase_github-0.2.9/.release-please-manifest.json +3 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/CHANGELOG.md +7 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/PKG-INFO +1 -1
- {sase_github-0.2.8 → sase_github-0.2.9}/pyproject.toml +1 -1
- sase_github-0.2.9/src/sase_github/scripts/gh_release.py +27 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/src/sase_github/xprompts/gh.yml +7 -10
- {sase_github-0.2.8 → sase_github-0.2.9}/tests/test_gh_workspace_claims.py +90 -7
- sase_github-0.2.8/.release-please-manifest.json +0 -3
- {sase_github-0.2.8 → sase_github-0.2.9}/.github/workflows/ci.yml +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/.github/workflows/pr-title.yml +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/.github/workflows/publish.yml +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/.sase_beads/beads.db +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/.sase_beads/config.json +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/.sase_beads/issues.jsonl +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/CLAUDE.md +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/Justfile +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/LICENSE +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/README.md +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/docs/architecture.md +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/docs/configuration.md +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/docs/xprompts.md +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/release-please-config.json +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/src/sase_github/__init__.py +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/src/sase_github/config.py +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/src/sase_github/default_config.yml +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/src/sase_github/errors.py +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/src/sase_github/plugin.py +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/src/sase_github/scripts/__init__.py +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/src/sase_github/scripts/gh_setup.py +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/src/sase_github/scripts/new_pr_desc_get_context.py +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/src/sase_github/task_types.py +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/src/sase_github/workspace_plugin.py +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/src/sase_github/xprompts/new_pr_desc.yml +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/src/sase_github/xprompts/pr_diff.yml +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/src/sase_github/xprompts/prdd.yml +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/tests/__init__.py +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/tests/test_ci_install_contract.py +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/tests/test_config.py +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/tests/test_github_issues.py +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/tests/test_github_plugin.py +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/tests/test_github_pull_requests.py +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/tests/test_submit_with_recorded_pr.py +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/tests/test_task_types.py +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/tests/test_workspace_plugin.py +0 -0
- {sase_github-0.2.8 → sase_github-0.2.9}/uv.lock +0 -0
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.2.9](https://github.com/sase-org/sase-github/compare/v0.2.8...v0.2.9) (2026-08-29)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **workspace:** identity-check #gh release and skip on handoff ([2571c9d](https://github.com/sase-org/sase-github/commit/2571c9d7466d4c6020a87b6ee86068c12170cdab))
|
|
9
|
+
|
|
3
10
|
## [0.2.8](https://github.com/sase-org/sase-github/compare/v0.2.7...v0.2.8) (2026-08-29)
|
|
4
11
|
|
|
5
12
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Release step for the #gh xprompt workflow."""
|
|
2
|
+
|
|
3
|
+
from sase.workspace_provider.vcs_release import VcsReleaseResult, release_vcs_workspace
|
|
4
|
+
|
|
5
|
+
_CALLER_TAG = "gh-release"
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def main(
|
|
9
|
+
*,
|
|
10
|
+
project_file: str,
|
|
11
|
+
workspace_num: int,
|
|
12
|
+
workspace_dir: str,
|
|
13
|
+
workflow_name: str,
|
|
14
|
+
cl_name: str | None,
|
|
15
|
+
) -> None:
|
|
16
|
+
"""Identity-checked, handoff-aware release of the #gh workspace claim."""
|
|
17
|
+
result: VcsReleaseResult = release_vcs_workspace(
|
|
18
|
+
project_file=project_file,
|
|
19
|
+
workspace_num=workspace_num,
|
|
20
|
+
workspace_dir=workspace_dir,
|
|
21
|
+
workflow_name=workflow_name,
|
|
22
|
+
cl_name=cl_name,
|
|
23
|
+
caller_tag=_CALLER_TAG,
|
|
24
|
+
)
|
|
25
|
+
print(f"released={'true' if result.released else 'false'}")
|
|
26
|
+
if result.skip_reason:
|
|
27
|
+
print(f"skip_reason={result.skip_reason}")
|
|
@@ -120,18 +120,15 @@ steps:
|
|
|
120
120
|
finally: true
|
|
121
121
|
if: "{{ setup.should_release }}"
|
|
122
122
|
python: |
|
|
123
|
-
from
|
|
124
|
-
from sase.workspace_provider.occupant import clear_occupant_record
|
|
123
|
+
from sase_github.scripts.gh_release import main
|
|
125
124
|
|
|
126
|
-
|
|
127
|
-
{{ setup.project_file | tojson }},
|
|
128
|
-
{{ setup.workspace_num }},
|
|
129
|
-
{{ setup.
|
|
130
|
-
{{
|
|
131
|
-
|
|
125
|
+
main(
|
|
126
|
+
project_file={{ setup.project_file | tojson }},
|
|
127
|
+
workspace_num={{ setup.workspace_num }},
|
|
128
|
+
workspace_dir={{ setup.workspace_dir | tojson }},
|
|
129
|
+
workflow_name={{ setup.workflow_name | tojson }},
|
|
130
|
+
cl_name={{ gh_ref | tojson }} if "/" not in {{ gh_ref | tojson }} else None,
|
|
132
131
|
)
|
|
133
|
-
clear_occupant_record({{ setup.workspace_dir | tojson }})
|
|
134
|
-
print("released=true")
|
|
135
132
|
output: { released: bool }
|
|
136
133
|
|
|
137
134
|
- name: diff
|
|
@@ -23,7 +23,7 @@ from sase.workspace_provider.occupant import (
|
|
|
23
23
|
write_occupant_record,
|
|
24
24
|
)
|
|
25
25
|
|
|
26
|
-
from sase_github.scripts import gh_setup
|
|
26
|
+
from sase_github.scripts import gh_release, gh_setup
|
|
27
27
|
from sase_github.workspace_plugin import GitHubWorkspacePlugin
|
|
28
28
|
|
|
29
29
|
ROOT = Path(__file__).resolve().parents[1]
|
|
@@ -939,16 +939,99 @@ class TestWsSubmitAtomicClaim:
|
|
|
939
939
|
)
|
|
940
940
|
|
|
941
941
|
|
|
942
|
-
def
|
|
942
|
+
def test_gh_release_step_delegates_to_gh_release() -> None:
|
|
943
943
|
text = (ROOT / "src" / "sase_github" / "xprompts" / "gh.yml").read_text(
|
|
944
944
|
encoding="utf-8"
|
|
945
945
|
)
|
|
946
|
-
assert
|
|
946
|
+
assert "from sase_github.scripts.gh_release import main" in text
|
|
947
|
+
assert "workspace_dir={{ setup.workspace_dir | tojson }}" in text
|
|
948
|
+
assert "release_workspace(" not in text
|
|
949
|
+
assert "clear_occupant_record(" not in text
|
|
947
950
|
|
|
948
951
|
|
|
949
|
-
def
|
|
950
|
-
|
|
952
|
+
def test_gh_release_caller_tag() -> None:
|
|
953
|
+
source = (ROOT / "src" / "sase_github" / "scripts" / "gh_release.py").read_text(
|
|
951
954
|
encoding="utf-8"
|
|
952
955
|
)
|
|
953
|
-
assert "
|
|
954
|
-
|
|
956
|
+
assert '_CALLER_TAG = "gh-release"' in source
|
|
957
|
+
|
|
958
|
+
|
|
959
|
+
def test_gh_release_step_releases_owned_claim_and_occupant(
|
|
960
|
+
tmp_path: Path, capsys: pytest.CaptureFixture[str]
|
|
961
|
+
) -> None:
|
|
962
|
+
runner_pid = os.getppid()
|
|
963
|
+
project_file = _write_project_file(
|
|
964
|
+
tmp_path,
|
|
965
|
+
running_claims=[WorkspaceClaim(23, "gh-acme/widget", None, pid=runner_pid)],
|
|
966
|
+
)
|
|
967
|
+
workspace_dir = tmp_path / "widget_23"
|
|
968
|
+
workspace_dir.mkdir()
|
|
969
|
+
write_occupant_record(
|
|
970
|
+
str(workspace_dir),
|
|
971
|
+
new_occupant_record(
|
|
972
|
+
pid=runner_pid,
|
|
973
|
+
workflow="gh-acme/widget",
|
|
974
|
+
project="gh_acme__widget",
|
|
975
|
+
workspace_num=23,
|
|
976
|
+
),
|
|
977
|
+
)
|
|
978
|
+
|
|
979
|
+
with _isolate_ledger(tmp_path):
|
|
980
|
+
gh_release.main(
|
|
981
|
+
project_file=project_file,
|
|
982
|
+
workspace_num=23,
|
|
983
|
+
workspace_dir=str(workspace_dir),
|
|
984
|
+
workflow_name="gh-acme/widget",
|
|
985
|
+
cl_name=None,
|
|
986
|
+
)
|
|
987
|
+
|
|
988
|
+
out = capsys.readouterr().out
|
|
989
|
+
assert "released=true" in out
|
|
990
|
+
assert get_claimed_workspaces(project_file) == []
|
|
991
|
+
assert read_occupant_record(str(workspace_dir)) is None
|
|
992
|
+
|
|
993
|
+
|
|
994
|
+
def test_gh_release_step_skips_on_handoff(
|
|
995
|
+
tmp_path: Path, capsys: pytest.CaptureFixture[str]
|
|
996
|
+
) -> None:
|
|
997
|
+
runner_pid = os.getppid()
|
|
998
|
+
project_file = _write_project_file(
|
|
999
|
+
tmp_path,
|
|
1000
|
+
running_claims=[WorkspaceClaim(23, "gh-acme/widget", None, pid=runner_pid)],
|
|
1001
|
+
)
|
|
1002
|
+
workspace_dir = tmp_path / "widget_23"
|
|
1003
|
+
workspace_dir.mkdir()
|
|
1004
|
+
write_occupant_record(
|
|
1005
|
+
str(workspace_dir),
|
|
1006
|
+
new_occupant_record(
|
|
1007
|
+
pid=runner_pid,
|
|
1008
|
+
workflow="gh-acme/widget",
|
|
1009
|
+
project="gh_acme__widget",
|
|
1010
|
+
workspace_num=23,
|
|
1011
|
+
),
|
|
1012
|
+
)
|
|
1013
|
+
artifacts = tmp_path / "artifacts"
|
|
1014
|
+
artifacts.mkdir()
|
|
1015
|
+
(artifacts / ".sase_monitor_pending").write_text("{}", encoding="utf-8")
|
|
1016
|
+
|
|
1017
|
+
with (
|
|
1018
|
+
_isolate_ledger(tmp_path),
|
|
1019
|
+
patch.dict(os.environ, {"SASE_ARTIFACTS_DIR": str(artifacts)}),
|
|
1020
|
+
):
|
|
1021
|
+
gh_release.main(
|
|
1022
|
+
project_file=project_file,
|
|
1023
|
+
workspace_num=23,
|
|
1024
|
+
workspace_dir=str(workspace_dir),
|
|
1025
|
+
workflow_name="gh-acme/widget",
|
|
1026
|
+
cl_name=None,
|
|
1027
|
+
)
|
|
1028
|
+
|
|
1029
|
+
out = capsys.readouterr().out
|
|
1030
|
+
assert "released=false" in out
|
|
1031
|
+
assert "skip_reason=handoff" in out
|
|
1032
|
+
assert [claim.workspace_num for claim in get_claimed_workspaces(project_file)] == [
|
|
1033
|
+
23
|
|
1034
|
+
]
|
|
1035
|
+
occupant = read_occupant_record(str(workspace_dir))
|
|
1036
|
+
assert occupant is not None
|
|
1037
|
+
assert occupant.pid == runner_pid
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|