Something went wrong. Try again.
A Forgejo action that submits a new version of a program to the JCOllie winget source as a pull request.
Something went wrong. Try again.
6.8 kB · 170 lines
Python
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171# SPDX-FileCopyrightText: © 2026 Jeffrey C. Ollie <jeff@ocjtech.us># SPDX-License-Identifier: MIT
import base64import unittest
import winget_submit as ws
_X64 = "https://git.jcollie.dev/jeff/thing/releases/download/v1.0.0/thing-x86_64-windows.exe"_ARM64 = "https://git.jcollie.dev/jeff/thing/releases/download/v1.0.0/thing-aarch64-windows.exe"
_ENVIRON = { "GITHUB_SERVER_URL": "https://git.jcollie.dev", "GITHUB_REPOSITORY": "jeff/thing", "GITHUB_REF": "refs/tags/v1.0.0", "GITHUB_RUN_NUMBER": "42",}
def _inputs(**changes) -> ws.Inputs: values = dict( identifier="JCOllie.Thing", version="1.0.0", installers={"x64": _X64}, product_codes={}, release_notes_url="", release_date="", token="secret", dry_run=False, ) values.update(changes) return ws.Inputs(**values)
class ParseInstallers(unittest.TestCase): def test_one_per_line(self): self.assertEqual( {"x64": _X64, "arm64": _ARM64}, ws.parse_installers(f"x64 {_X64}\n\n arm64 {_ARM64} \n"), )
def test_malformed_lines_are_refused(self): for text in (f"x64={_X64}", "x64", f"x64 {_X64} extra"): with self.subTest(text=text), self.assertRaisesRegex(ws.SubmitError, "line 1"): ws.parse_installers(text)
def test_repeated_architecture_is_refused(self): with self.assertRaisesRegex(ws.SubmitError, "x64 is given more than once"): ws.parse_installers(f"x64 {_X64}\nx64 {_ARM64}\n")
def test_none_is_refused(self): with self.assertRaisesRegex(ws.SubmitError, "at least one"): ws.parse_installers("\n \n")
class ParseProductCodes(unittest.TestCase): _CODE = "{0F1E2D3C-4B5A-6978-8796-A5B4C3D2E1F0}"
def test_optional(self): self.assertEqual({}, ws.parse_product_codes("")) self.assertEqual({}, ws.parse_product_codes("\n \n"))
def test_one_per_line(self): self.assertEqual({"x64": self._CODE}, ws.parse_product_codes(f" x64 {self._CODE}\n"))
def test_malformed_and_repeated_lines_are_refused(self): with self.assertRaisesRegex(ws.SubmitError, "product-codes line 1: expected '<architecture> <code>'"): ws.parse_product_codes(f"x64={self._CODE}") with self.assertRaisesRegex(ws.SubmitError, "product-codes line 2: x64 is given more than once"): ws.parse_product_codes(f"x64 {self._CODE}\nx64 {self._CODE}\n")
class ReadInputs(unittest.TestCase): def environ(self, **changes): environ = { "WINGET_SUBMIT_IDENTIFIER": "JCOllie.Thing", "WINGET_SUBMIT_VERSION": " 1.0.0 ", "WINGET_SUBMIT_INSTALLERS": f"x64 {_X64}\n", "WINGET_SUBMIT_TOKEN": "secret", "WINGET_SUBMIT_DRY_RUN": "false", } environ.update(changes) return environ
def test_reads_and_trims(self): inputs = ws.read_inputs(self.environ()) self.assertEqual(_inputs(), inputs)
def test_reads_product_codes(self): code = "{0F1E2D3C-4B5A-6978-8796-A5B4C3D2E1F0}" inputs = ws.read_inputs(self.environ(WINGET_SUBMIT_PRODUCT_CODES=f"x64 {code}\n")) self.assertEqual({"x64": code}, inputs.product_codes)
def test_required(self): for name in ("IDENTIFIER", "VERSION"): with self.subTest(name=name), self.assertRaisesRegex(ws.SubmitError, "is required"): ws.read_inputs(self.environ(**{f"WINGET_SUBMIT_{name}": ""}))
def test_token_is_needed_except_for_a_dry_run(self): with self.assertRaisesRegex(ws.SubmitError, "token is required"): ws.read_inputs(self.environ(WINGET_SUBMIT_TOKEN="")) inputs = ws.read_inputs(self.environ(WINGET_SUBMIT_TOKEN="", WINGET_SUBMIT_DRY_RUN="true")) self.assertTrue(inputs.dry_run)
def test_dry_run_must_be_a_boolean(self): with self.assertRaisesRegex(ws.SubmitError, "dry-run"): ws.read_inputs(self.environ(WINGET_SUBMIT_DRY_RUN="yes"))
class Naming(unittest.TestCase): def test_branch_and_title(self): self.assertEqual("submit/JCOllie.Thing/1.0.0", ws.branch_name("JCOllie.Thing", "1.0.0")) self.assertEqual("JCOllie.Thing 1.0.0", ws.title("JCOllie.Thing", "1.0.0"))
class Body(unittest.TestCase): def test_links_release_run_and_source_version(self): text = ws.body(_inputs(), "0.9.0", _ENVIRON) self.assertIn("- Release: https://git.jcollie.dev/jeff/thing/releases/tag/v1.0.0\n", text) self.assertIn("- Opened by: https://git.jcollie.dev/jeff/thing/actions/runs/42\n", text) self.assertIn("- Copied from: 0.9.0\n", text)
def test_release_notes_url_is_the_release_link(self): text = ws.body(_inputs(release_notes_url="https://example.invalid/notes"), "0.9.0", _ENVIRON) self.assertIn("- Release: https://example.invalid/notes\n", text)
def test_no_release_link_without_a_tag(self): text = ws.body(_inputs(), "0.9.0", {**_ENVIRON, "GITHUB_REF": "refs/heads/main"}) self.assertNotIn("Release:", text)
def test_outside_a_workflow(self): text = ws.body(_inputs(), "0.9.0", {}) self.assertNotIn("Release:", text) self.assertNotIn("Opened by:", text) self.assertIn("- Copied from: 0.9.0\n", text)
class GitAuthentication(unittest.TestCase): def test_token_goes_in_an_extra_header(self): env = ws.git_auth_environment("secret", "winget-bot") self.assertEqual("1", env["GIT_CONFIG_COUNT"]) self.assertEqual("http.https://git.jcollie.dev/.extraHeader", env["GIT_CONFIG_KEY_0"]) self.assertEqual( "Authorization: Basic " + base64.b64encode(b"winget-bot:secret").decode(), env["GIT_CONFIG_VALUE_0"], )
def test_no_token_no_header(self): self.assertEqual({}, ws.git_auth_environment("", "anyone"))
class OpenPullRequest(unittest.TestCase): @staticmethod def pull(ref, repository="jeff/winget-pkgs", number=1): return {"number": number, "head": {"ref": ref, "repo": {"full_name": repository}}}
def test_finds_the_branch(self): pulls = [self.pull("other", number=1), self.pull("submit/JCOllie.Thing/1.0.0", number=2)] self.assertEqual(2, ws.open_pull_request_for(pulls, "submit/JCOllie.Thing/1.0.0")["number"])
def test_ignores_a_fork_with_the_same_branch(self): pulls = [self.pull("submit/JCOllie.Thing/1.0.0", repository="someone/winget-pkgs")] self.assertIsNone(ws.open_pull_request_for(pulls, "submit/JCOllie.Thing/1.0.0"))
def test_none(self): self.assertIsNone(ws.open_pull_request_for([], "submit/JCOllie.Thing/1.0.0"))
if __name__ == "__main__": unittest.main()