From c9780c882211fa740270f1f3f6210c05f532a8fc Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Wed, 21 Oct 2026 10:06:57 +0200 Subject: [PATCH] docs: add one BIOS from the browser A browser upload into bios/ lands on a fork and opens the pull request, and CI already hashes the file and names its folder. CONTRIBUTING asked for a fork, a clone, five packages and the whole suite, and promised a PR comment that a fork's read-only token cannot post. The issue chooser links the upload page. --- .github/ISSUE_TEMPLATE/config.yml | 5 +++ CONTRIBUTING.md | 27 ++++++++++++---- scripts/generate_readme.py | 30 +++++++++++++---- tests/test_contributing_text.py | 53 +++++++++++++++++++++++++++++++ 4 files changed, 103 insertions(+), 12 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/config.yml diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..b5b61442 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: true +contact_links: + - name: Add a BIOS file + url: https://github.com/Abdess/retrobios/upload/main/bios + about: Upload the file into bios/ from the browser. GitHub opens the pull request, and CI checks the file and names the folder of its system. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4860f55e..06870fb9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,10 +2,21 @@ ## Add a BIOS file -1. Fork this repository -2. Place the file in `bios/Manufacturer/Console/filename` -3. Variants (alternate hashes for the same file): `bios/Manufacturer/Console/.variants/` -4. Open a pull request. Its hashes are checked automatically and reported in a comment +One file needs no clone and no local setup: + +1. [Upload it into `bios/`](https://github.com/Abdess/retrobios/upload/main/bios) + from the browser, 25 MB at most per file. GitHub writes it to a fork and + opens the pull request. +2. CI hashes it and looks it up in every platform list and emulator profile. + For a file it recognises, it names the folder holding the other files of its + system. The report is in the summary of the pull request's Validation run. +3. The file can be moved to that folder in the same pull request. A file whose + hash differs from the one already held under its name goes to that folder's + `.variants/`. + +From a clone, the file goes to `bios/Manufacturer/Console/filename`, and +`python scripts/validate_pr.py path/to/file` names that folder for a file still +outside `bios/`. A file over the browser's 25 MB limit goes in that way. The [dump provenance](https://abdess.github.io/retrobios/provenance/) page lists catalogued dumps still missing from the collection, with their hashes. A file matching one of those is @@ -43,7 +54,9 @@ Full walkthrough: [profiling guide](https://abdess.github.io/retrobios/wiki/prof ## Before opening a PR -The checks CI runs on a pull request (Python 3.12 or newer): +A pull request that only adds files under `bios/` needs none of this: the +validation above is its check. For code, profiles or platform files, these are +the checks CI runs on a pull request (Python 3.12 or newer): ```bash pip install pyyaml "jsonschema[format-nongpl]" markdown \ @@ -62,7 +75,9 @@ in `dist/`, which is why maintainers run it before a release. CI computes SHA1/MD5/CRC32 for every new file, checks them against the platform configs, validates the YAML against the schemas, confronts each added profile -with its upstream source, runs the test suite, and posts a report on the PR. +with its upstream source and runs the test suite. The BIOS report goes to the +summary of the Validation run, and also to a comment when the branch lives in +this repository: a fork's pull request runs with a read-only token. Contributors who add platform support are credited in the README, on the documentation site, and in the BIOS packs. diff --git a/scripts/generate_readme.py b/scripts/generate_readme.py index 4f4dd4e1..f99b9f67 100644 --- a/scripts/generate_readme.py +++ b/scripts/generate_readme.py @@ -250,6 +250,9 @@ def format_size(size: int) -> str: SITE_URL = "https://abdess.github.io/retrobios/" REPO_PATH = "../.." REPO = "Abdess/retrobios" +# GitHub's "Add file > Upload files" page for bios/: a browser upload by +# someone without write access lands on a fork and opens a pull request. +UPLOAD_URL = f"https://github.com/{REPO}/upload/main/bios" def _existing_contributor_block(readme_path: str = "README.md") -> list[str]: @@ -714,10 +717,21 @@ def contributing_text( ## Add a BIOS file -1. Fork this repository -2. Place the file in `bios/Manufacturer/Console/filename` -3. Variants (alternate hashes for the same file): `bios/Manufacturer/Console/.variants/` -4. Open a pull request. Its hashes are checked automatically and reported in a comment +One file needs no clone and no local setup: + +1. [Upload it into `bios/`]({UPLOAD_URL}) + from the browser, 25 MB at most per file. GitHub writes it to a fork and + opens the pull request. +2. CI hashes it and looks it up in every platform list and emulator profile. + For a file it recognises, it names the folder holding the other files of its + system. The report is in the summary of the pull request's Validation run. +3. The file can be moved to that folder in the same pull request. A file whose + hash differs from the one already held under its name goes to that folder's + `.variants/`. + +From a clone, the file goes to `bios/Manufacturer/Console/filename`, and +`python scripts/validate_pr.py path/to/file` names that folder for a file still +outside `bios/`. A file over the browser's 25 MB limit goes in that way. The [dump provenance]({link("provenance")}) page lists catalogued dumps still missing from the collection, with their hashes. A file matching one of those is @@ -755,7 +769,9 @@ Full walkthrough: [profiling guide]({link("wiki/profiling")}). ## Before opening a PR -The checks CI runs on a pull request (Python 3.12 or newer): +A pull request that only adds files under `bios/` needs none of this: the +validation above is its check. For code, profiles or platform files, these are +the checks CI runs on a pull request (Python 3.12 or newer): ```bash pip install pyyaml "jsonschema[format-nongpl]" markdown \\ @@ -774,7 +790,9 @@ in `dist/`, which is why maintainers run it before a release. CI computes SHA1/MD5/CRC32 for every new file, checks them against the platform configs, validates the YAML against the schemas, confronts each added profile -with its upstream source, runs the test suite, and posts a report on the PR. +with its upstream source and runs the test suite. The BIOS report goes to the +summary of the Validation run, and also to a comment when the branch lives in +this repository: a fork's pull request runs with a read-only token. Contributors who add platform support are credited in the README, {site_words}, and in the BIOS packs. diff --git a/tests/test_contributing_text.py b/tests/test_contributing_text.py index 1f72f67d..3803722a 100644 --- a/tests/test_contributing_text.py +++ b/tests/test_contributing_text.py @@ -83,5 +83,58 @@ class BeforeOpeningAPullRequest(unittest.TestCase): self.assertIn(f'"{spec}"', text) +class OneFileThroughTheBrowser(unittest.TestCase): + """Adding one BIOS asked for a fork, a 5.5 GB clone, five pip packages, + the data directories and the whole suite, and promised a PR comment that + a fork's read-only token cannot post. The browser upload into bios/ and + the CI report already did the work.""" + + def test_the_guide_and_the_issue_chooser_offer_the_upload(self): + import yaml + + text = generate_readme.generate_contributing() + section = text.split("## Add a BIOS file", 1)[1].split("\n## ", 1)[0] + self.assertIn(generate_readme.UPLOAD_URL, section) + self.assertNotIn("Fork this repository", section) + self.assertNotIn("reported in a comment", text) + chooser = yaml.safe_load( + (REPO_ROOT / ".github" / "ISSUE_TEMPLATE" / "config.yml").read_text(encoding="utf-8") + ) + self.assertIn(generate_readme.UPLOAD_URL, [link["url"] for link in chooser["contact_links"]]) + + def test_ci_comments_only_on_branches_of_this_repository(self): + workflow = (REPO_ROOT / ".github" / "workflows" / "validate.yml").read_text(encoding="utf-8") + self.assertIn("github.event.pull_request.head.repo.full_name == github.repository", workflow) + self.assertIn('>> "$GITHUB_STEP_SUMMARY"', workflow) + self.assertIn("summary of the Validation run", generate_readme.generate_contributing()) + + def test_an_upload_at_the_bios_root_is_told_its_folder(self): + import os + import tempfile + + import validate_pr + + scratch = REPO_ROOT / "tmp" / "tests" + scratch.mkdir(parents=True, exist_ok=True) + with tempfile.TemporaryDirectory(dir=scratch) as directory: + (Path(directory) / "bios").mkdir() + (Path(directory) / "bios" / "boot.rom").write_bytes(b"boot") + from common import compute_hashes + + sha1 = compute_hashes(str(Path(directory) / "bios" / "boot.rom"))["sha1"] + hashes = {"sha1": {sha1}, "folders": {sha1: {"bios/Maker/Console/"}}} + cwd = os.getcwd() + os.chdir(directory) + try: + result = validate_pr.validate_file("bios/boot.rom", None, hashes) + finally: + os.chdir(cwd) + self.assertTrue(result.passed) + self.assertTrue(any( + "bios/ root" in message and "`bios/Maker/Console/`" in message + for _status, message in result.checks + )) + + if __name__ == "__main__": unittest.main()