diff --git a/docs/release.md b/docs/release.md index 93c99e2..4db18e3 100644 --- a/docs/release.md +++ b/docs/release.md @@ -21,7 +21,7 @@ The build workflow packages and uploads `SimStore.app.tar.bz2` and `release.json Both publication workflows use the `simstore-releases` concurrency group with a multiple-run queue. Stable drafts can be retried, while an already published stable release cannot have its assets overwritten by the publisher. A delayed build cannot replace a newer nightly. The nightly's package and metadata are uploaded before its version index. -Release descriptions retain the Terminal installation command and the instruction against downloading the archive through a browser. The command uses the release's own tag, including stable tags. Nightly publishing refreshes the index in the same workflow; it does not depend on a second release event generated by `GITHUB_TOKEN`. +Release descriptions direct existing users to SimStore → Check for Updates… and provide a Terminal command for a first installation or manual reinstall. The command stays on one line, uses the release's own tag including stable tags, and removes the temporary archive after extraction. The description warns against downloading through a browser. Nightly publishing refreshes the index in the same workflow; it does not depend on a second release event generated by `GITHUB_TOKEN`. To create a stable release, choose the next version and tag the tested main commit: diff --git a/scripts/release.py b/scripts/release.py index a6d1d92..8def4ed 100644 --- a/scripts/release.py +++ b/scripts/release.py @@ -112,13 +112,14 @@ def assemble_index(nightly: Release, stable: list[Release]) -> dict[str, object] def release_notes(repo: str, tag: str) -> str: command = ( - 'rm -rf /tmp/SimStore.app && ' f'curl -fL https://github.com/{repo}/releases/download/{tag}/{ARCHIVE} ' f'-o /tmp/{ARCHIVE} && rm -rf ~/Applications/SimStore.app && ' - f'mkdir -p ~/Applications && tar -xjf /tmp/{ARCHIVE} -C ~/Applications' + f'mkdir -p ~/Applications && tar -xjf /tmp/{ARCHIVE} -C ~/Applications && ' + f'rm -f /tmp/{ARCHIVE}' ) return ( - 'Execute the command in Terminal to install this version:\n\n' + 'If SimStore is already installed, choose SimStore → Check for Updates… in the app.\n\n' + 'To install SimStore for the first time or reinstall it manually, run this command in Terminal:\n\n' f'```sh\n{command}\n```\n\nDo NOT download by clicking the link below.\n' ) diff --git a/tests/test_release.py b/tests/test_release.py index 3768cc9..e4e83b8 100644 --- a/tests/test_release.py +++ b/tests/test_release.py @@ -210,12 +210,17 @@ def test_invalid_release_fields_and_installation_instructions(self) -> None: path = self.work / METADATA write_json(path, {**valid, field: value}) Release.read(path) - notes = release_notes('example/simstore', '0.1.0') - command = notes.split('```sh\n')[1].split('\n```')[0] - self.assertNotIn('\n', command) - self.assertIn('/releases/download/0.1.0/SimStore.app.tar.bz2', command) - self.assertTrue(command.startswith('rm -rf /tmp/SimStore.app && curl')) - self.assertTrue(notes.endswith('Do NOT download by clicking the link below.\n')) + for tag in ('latest', '0.1.0'): + with self.subTest(tag=tag): + notes = release_notes('example/simstore', tag) + command = notes.split('```sh\n')[1].split('\n```')[0] + self.assertIn('SimStore → Check for Updates…', notes) + self.assertIn('first time or reinstall it manually', notes) + self.assertNotIn('\n', command) + self.assertIn(f'/releases/download/{tag}/{ARCHIVE}', command) + self.assertTrue(command.startswith('curl -fL ')) + self.assertTrue(command.endswith(f'&& rm -f /tmp/{ARCHIVE}')) + self.assertTrue(notes.endswith('Do NOT download by clicking the link below.\n')) if __name__ == '__main__':