mirror of
https://github.com/saphid/frame-control.git
synced 2026-10-15 01:01:29 +02:00
There `bash` is the WSL launcher (no distribution on GitHub's runners), so the step couldn't run; it only ever runs on ubuntu-latest. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
107 lines
4.8 KiB
Python
107 lines
4.8 KiB
Python
"""The "Create the draft release" step of .github/workflows/release.yml, taken out of
|
|
the workflow and run with bash (as Actions runs it) against a stand-in gh
|
|
(tests/fakegh/gh): a new draft's id comes straight from the POST even when the
|
|
release list doesn't show it yet (v0.4.2's first run), a rerun reuses the draft
|
|
found by tag_name, and a tag that isn't on GitHub stops it. Nothing here talks to
|
|
GitHub.
|
|
|
|
Run: python3 -m unittest discover -s tests
|
|
"""
|
|
import sandbox # noqa: F401 (first: keeps tests off real data and services)
|
|
import json
|
|
import os
|
|
import shutil
|
|
import subprocess
|
|
import tempfile
|
|
import textwrap
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parent.parent
|
|
WORKFLOW = ROOT / ".github" / "workflows" / "release.yml"
|
|
FAKEGH = ROOT / "tests" / "fakegh"
|
|
STEP = "- name: Create the draft release"
|
|
|
|
|
|
def step_script():
|
|
"""The step's `run: |` block, dedented."""
|
|
lines = WORKFLOW.read_text().splitlines()
|
|
i = next(n for n, line in enumerate(lines) if line.strip() == STEP)
|
|
while lines[i].strip() != "run: |":
|
|
i += 1
|
|
indent = len(lines[i]) - len(lines[i].lstrip())
|
|
body = []
|
|
for line in lines[i + 1:]:
|
|
if line.strip() and len(line) - len(line.lstrip()) <= indent:
|
|
break
|
|
body.append(line)
|
|
return textwrap.dedent("\n".join(body)).strip() + "\n"
|
|
|
|
|
|
def release(rid, tag_name, name="Frame Control 9.8.7", draft=True):
|
|
return {"id": rid, "tag_name": tag_name, "name": name, "draft": draft, "assets": []}
|
|
|
|
|
|
# The step only runs on ubuntu-latest. On Windows `bash` is often the WSL launcher
|
|
# (with no distribution on GitHub's runners), not a bash that can run tests/fakegh.
|
|
@unittest.skipUnless(os.name != "nt" and shutil.which("bash") and shutil.which("jq"),
|
|
"needs a POSIX bash and jq (for gh --jq); the step runs on ubuntu only")
|
|
class DraftStep(unittest.TestCase):
|
|
def run_step(self, releases, tags="v9.8.7", tag="v9.8.7"):
|
|
d = Path(tempfile.mkdtemp())
|
|
(d / "step.sh").write_text(step_script())
|
|
(d / "releases.json").write_text(json.dumps(releases))
|
|
env = dict(os.environ, PATH="%s:%s" % (FAKEGH, os.environ["PATH"]),
|
|
FAKEGH_RELEASES=str(d / "releases.json"), FAKEGH_TAGS=tags,
|
|
FAKEGH_LOG=str(d / "log"), GITHUB_REF_NAME=tag, GH_REPO="saphid/frame-control")
|
|
p = subprocess.run(["bash", "--noprofile", "--norc", "-eo", "pipefail", str(d / "step.sh")],
|
|
env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
|
universal_newlines=True, timeout=30)
|
|
log = [json.loads(line) for line in (d / "log").read_text().splitlines()] if (d / "log").exists() else []
|
|
return p, log
|
|
|
|
def posts(self, log):
|
|
return [c for c in log if c[1:4] == ["-X", "POST", "repos/saphid/frame-control/releases"]]
|
|
|
|
def patches(self, log):
|
|
return [c for c in log if c[1:3] == ["-X", "PATCH"]]
|
|
|
|
def test_new_draft_uses_the_id_the_post_returns(self):
|
|
# The list doesn't show the fresh draft (it never does in the fake): v0.4.2's case.
|
|
p, log = self.run_step([])
|
|
self.assertEqual(p.returncode, 0, p.stderr + p.stdout)
|
|
[post] = self.posts(log)
|
|
for f in ("tag_name=v9.8.7", "name=Frame Control 9.8.7", "draft=true"):
|
|
self.assertIn(f, post)
|
|
self.assertIn(["api", "repos/saphid/frame-control/git/ref/tags/v9.8.7"], log)
|
|
[patch] = self.patches(log)
|
|
self.assertEqual(patch[3], "repos/saphid/frame-control/releases/9001")
|
|
self.assertIn("tag_name=v9.8.7", patch)
|
|
self.assertIn("release 9001 tag_name v9.8.7", p.stdout)
|
|
self.assertTrue(all(c[0] == "api" for c in log)) # never `gh release ...`
|
|
|
|
def test_a_rerun_reuses_the_draft_with_the_tag(self):
|
|
p, log = self.run_step([release(7, "v9.8.6", "Frame Control 9.8.6"), release(42, "v9.8.7")])
|
|
self.assertEqual(p.returncode, 0, p.stderr + p.stdout)
|
|
self.assertEqual(self.posts(log), [])
|
|
[patch] = self.patches(log)
|
|
self.assertEqual(patch[3], "repos/saphid/frame-control/releases/42")
|
|
|
|
def test_other_releases_alone_mean_a_new_draft(self):
|
|
p, log = self.run_step([release(7, "v9.8.6", "Frame Control 9.8.6", draft=False),
|
|
release(8, "v9.8.70", "Frame Control 9.8.70")])
|
|
self.assertEqual(p.returncode, 0, p.stderr + p.stdout)
|
|
self.assertEqual(len(self.posts(log)), 1)
|
|
self.assertEqual(self.patches(log)[0][3], "repos/saphid/frame-control/releases/9001")
|
|
|
|
def test_stops_when_the_tag_is_not_on_github(self):
|
|
p, log = self.run_step([], tags="")
|
|
self.assertNotEqual(p.returncode, 0)
|
|
self.assertIn("tag v9.8.7 isn't on GitHub", p.stderr)
|
|
self.assertEqual(self.posts(log), [])
|
|
self.assertEqual(self.patches(log), [])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|