|
22 | 22 | import sys |
23 | 23 | import tempfile |
24 | 24 | import time |
| 25 | +import webbrowser |
25 | 26 | from pathlib import Path |
26 | 27 |
|
27 | 28 | # Try to import tomllib (Python 3.11+) or fall back to tomli |
@@ -246,6 +247,92 @@ def edit_content(content: str, description: str = 'content') -> str | None: |
246 | 247 | pass |
247 | 248 |
|
248 | 249 |
|
| 250 | +def prompt_yes_no(question: str, default: bool = True) -> bool: |
| 251 | + """Prompt user for yes/no input with a default value. |
| 252 | +
|
| 253 | + Args: |
| 254 | + question: The question to ask the user |
| 255 | + default: Default value (True for yes, False for no) |
| 256 | +
|
| 257 | + Returns: |
| 258 | + True for yes, False for no |
| 259 | + """ |
| 260 | + prompt_suffix = '[Y/n]' if default else '[y/N]' |
| 261 | + prompt = f'{question} {prompt_suffix}: ' |
| 262 | + |
| 263 | + while True: |
| 264 | + response = input(prompt).strip().lower() |
| 265 | + |
| 266 | + if not response: |
| 267 | + return default |
| 268 | + |
| 269 | + if response in ('y', 'yes'): |
| 270 | + return True |
| 271 | + elif response in ('n', 'no'): |
| 272 | + return False |
| 273 | + else: |
| 274 | + print('Please answer y or n') |
| 275 | + |
| 276 | + |
| 277 | +def execute_commit_and_push(new_version: str) -> bool: |
| 278 | + """Execute git commit and push commands. |
| 279 | +
|
| 280 | + Args: |
| 281 | + new_version: The new version being released |
| 282 | +
|
| 283 | + Returns: |
| 284 | + True if successful, False otherwise |
| 285 | + """ |
| 286 | + commit_msg = f'Prepare for v{new_version} release' |
| 287 | + |
| 288 | + try: |
| 289 | + # Execute git commit |
| 290 | + status(f'π Committing changes: {commit_msg}') |
| 291 | + result = subprocess.run( |
| 292 | + ['git', 'commit', '-m', commit_msg], |
| 293 | + capture_output=True, |
| 294 | + text=True, |
| 295 | + ) |
| 296 | + |
| 297 | + if result.returncode != 0: |
| 298 | + print(f'β Error committing changes: {result.stderr}', file=sys.stderr) |
| 299 | + return False |
| 300 | + |
| 301 | + status('β
Changes committed successfully') |
| 302 | + |
| 303 | + # Execute git push |
| 304 | + status('π Pushing to remote repository...') |
| 305 | + result = subprocess.run( |
| 306 | + ['git', 'push'], |
| 307 | + capture_output=True, |
| 308 | + text=True, |
| 309 | + ) |
| 310 | + |
| 311 | + if result.returncode != 0: |
| 312 | + print(f'β Error pushing changes: {result.stderr}', file=sys.stderr) |
| 313 | + return False |
| 314 | + |
| 315 | + status('β
Changes pushed successfully') |
| 316 | + return True |
| 317 | + |
| 318 | + except Exception as e: |
| 319 | + print(f'β Unexpected error: {e}', file=sys.stderr) |
| 320 | + return False |
| 321 | + |
| 322 | + |
| 323 | +def open_actions_page() -> None: |
| 324 | + """Open the GitHub Actions page in the default web browser.""" |
| 325 | + actions_url = 'https://github.com/singlestore-labs/sqlalchemy-singlestoredb/actions' |
| 326 | + status(f'π Opening GitHub Actions page: {actions_url}') |
| 327 | + |
| 328 | + try: |
| 329 | + webbrowser.open(actions_url) |
| 330 | + status('β
Browser opened successfully') |
| 331 | + except Exception as e: |
| 332 | + print(f'β οΈ Could not open browser: {e}', file=sys.stderr) |
| 333 | + print(f' Please visit: {actions_url}', file=sys.stderr) |
| 334 | + |
| 335 | + |
249 | 336 | def prepare_whatsnew_content(new_version: str, summary: str) -> str: |
250 | 337 | """Prepare the content for the new release section.""" |
251 | 338 | today = datetime.date.today() |
@@ -428,11 +515,30 @@ def main() -> None: |
428 | 515 | print('=' * 50, file=sys.stderr) |
429 | 516 | print(f'π Version bump completed successfully in {total_elapsed:.1f}s!', file=sys.stderr) |
430 | 517 | print(f'π Version: {current_version} β {new_version}', file=sys.stderr) |
431 | | - print('π Next steps:', file=sys.stderr) |
432 | | - print(' π git commit -m "Prepare for v{} release" && git push'.format(new_version), file=sys.stderr) |
433 | | - print(' π Run Smoke test <https://github.com/singlestore-labs/sqlalchemy-singlestoredb/actions/workflows/smoke-test.yml>', file=sys.stderr) |
434 | | - print(' π Run Coverage tests <https://github.com/singlestore-labs/sqlalchemy-singlestoredb/actions/workflows/coverage.yml>', file=sys.stderr) |
435 | | - print(' π Run resources/create_release.py', file=sys.stderr) |
| 518 | + print('', file=sys.stderr) |
| 519 | + |
| 520 | + # Prompt user to commit and push |
| 521 | + if prompt_yes_no('Do you want to commit and push now?', default=True): |
| 522 | + print('', file=sys.stderr) |
| 523 | + if execute_commit_and_push(new_version): |
| 524 | + print('', file=sys.stderr) |
| 525 | + open_actions_page() |
| 526 | + print('', file=sys.stderr) |
| 527 | + print('π Next steps:', file=sys.stderr) |
| 528 | + print(' π Run Coverage tests <https://github.com/singlestore-labs/sqlalchemy-singlestoredb/actions/workflows/coverage.yml>', file=sys.stderr) |
| 529 | + print(' π Run Smoke test <https://github.com/singlestore-labs/sqlalchemy-singlestoredb/actions/workflows/smoke-test.yml>', file=sys.stderr) |
| 530 | + print(' π Run resources/create_release.py', file=sys.stderr) |
| 531 | + else: |
| 532 | + print('', file=sys.stderr) |
| 533 | + print('β οΈ Commit/push failed. Please manually run:', file=sys.stderr) |
| 534 | + print(' π git commit -m "Prepare for v{} release" && git push'.format(new_version), file=sys.stderr) |
| 535 | + else: |
| 536 | + print('', file=sys.stderr) |
| 537 | + print('π Next steps:', file=sys.stderr) |
| 538 | + print(' π git commit -m "Prepare for v{} release" && git push'.format(new_version), file=sys.stderr) |
| 539 | + print(' π Run Coverage tests <https://github.com/singlestore-labs/sqlalchemy-singlestoredb/actions/workflows/coverage.yml>', file=sys.stderr) |
| 540 | + print(' π Run Smoke test <https://github.com/singlestore-labs/sqlalchemy-singlestoredb/actions/workflows/smoke-test.yml>', file=sys.stderr) |
| 541 | + print(' π Run resources/create_release.py', file=sys.stderr) |
436 | 542 |
|
437 | 543 |
|
438 | 544 | if __name__ == '__main__': |
|
0 commit comments