chore: move release command and scripts back to root (#329)

authored by zzstoatzz.io and committed by GitHub c8da6be0 66505c5b

+1 -5
backend/justfile
··· 27 27 28 28 # show current migration status 29 29 migrate-status: 30 - uv run alembic current 31 - 32 - # create a github release (triggers production deployment) 33 - release: 34 - ./scripts/release 30 + uv run alembic current
backend/scripts/backfill_atproto_records.py scripts/backfill_atproto_records.py
backend/scripts/backfill_image_urls.py scripts/backfill_image_urls.py
backend/scripts/copy_r2_buckets.py scripts/copy_r2_buckets.py
backend/scripts/delete_track.py scripts/delete_track.py
backend/scripts/generate_audio_sample.py scripts/generate_audio_sample.py
backend/scripts/migrate_atproto_namespace.py scripts/migrate_atproto_namespace.py
backend/scripts/migrate_images_to_new_buckets.py scripts/migrate_images_to_new_buckets.py
backend/scripts/migrate_r2_bucket.py scripts/migrate_r2_bucket.py
-122
backend/scripts/release
··· 1 - #!/usr/bin/env -S uv run --script --quiet 2 - # /// script 3 - # requires-python = ">=3.12" 4 - # dependencies = [] 5 - # /// 6 - """create a github release using timestamp-based versioning 7 - 8 - version format: YYYY.MMDD.HHMMSS (e.g., 2025.1106.134523) 9 - 10 - usage: 11 - just release 12 - ./scripts/release 13 - """ 14 - 15 - import subprocess 16 - import sys 17 - from datetime import UTC, datetime 18 - 19 - 20 - def main() -> int: 21 - """create release with timestamp version.""" 22 - # ensure we're on main branch 23 - result = subprocess.run( 24 - ["git", "branch", "--show-current"], 25 - capture_output=True, 26 - text=True, 27 - check=True, 28 - ) 29 - current_branch = result.stdout.strip() 30 - 31 - if current_branch != "main": 32 - print(f"❌ must be on main branch (currently on {current_branch})") 33 - return 1 34 - 35 - # ensure working directory is clean 36 - result = subprocess.run( 37 - ["git", "status", "--porcelain"], 38 - capture_output=True, 39 - text=True, 40 - check=True, 41 - ) 42 - if result.stdout.strip(): 43 - print("❌ working directory has uncommitted changes") 44 - return 1 45 - 46 - # ensure we're up to date with remote 47 - subprocess.run(["git", "fetch"], capture_output=True, check=True) 48 - result = subprocess.run( 49 - ["git", "rev-list", "HEAD..@{u}"], 50 - capture_output=True, 51 - text=True, 52 - check=True, 53 - ) 54 - if result.stdout.strip(): 55 - print("❌ local branch is behind remote - please pull first") 56 - return 1 57 - 58 - # check if there are backend changes since last release 59 - result = subprocess.run( 60 - ["gh", "release", "list", "--limit", "1"], 61 - capture_output=True, 62 - text=True, 63 - check=True, 64 - ) 65 - if result.stdout.strip(): 66 - last_release = result.stdout.split()[0] 67 - 68 - # check for backend changes since last release 69 - result = subprocess.run( 70 - ["git", "log", f"{last_release}..HEAD", "--oneline", "--", "src/backend/"], 71 - capture_output=True, 72 - text=True, 73 - check=True, 74 - ) 75 - 76 - if not result.stdout.strip(): 77 - print("❌ no backend changes since last release") 78 - print(f" last release: {last_release}") 79 - print(" only frontend/docs changes do not require a backend release") 80 - return 1 81 - 82 - version = datetime.now(UTC).strftime("%Y.%m%d.%H%M%S") 83 - 84 - # print banner using figlet 85 - subprocess.run(["figlet", "-f", "small", "plyr.fm"], check=False) 86 - print("───────────────────────────") 87 - print(f"release {version}") 88 - print("target production") 89 - print("───────────────────────────") 90 - 91 - # create release - gh will auto-generate notes from commits 92 - subprocess.run( 93 - [ 94 - "gh", 95 - "release", 96 - "create", 97 - version, 98 - "--title", 99 - version, 100 - "--generate-notes", 101 - ], 102 - check=True, 103 - ) 104 - 105 - print(f"\n✓ release {version} created") 106 - print("✓ production backend deployment starting...") 107 - 108 - # merge main -> production-fe to trigger frontend deployment 109 - print("\n🔄 updating production-fe branch...") 110 - subprocess.run(["git", "fetch", "origin"], check=True) 111 - subprocess.run(["git", "checkout", "production-fe"], check=True) 112 - subprocess.run(["git", "merge", "main", "--ff-only"], check=True) 113 - subprocess.run(["git", "push", "origin", "production-fe"], check=True) 114 - subprocess.run(["git", "checkout", "main"], check=True) 115 - 116 - print("✓ production frontend deployment starting...") 117 - 118 - return 0 119 - 120 - 121 - if __name__ == "__main__": 122 - sys.exit(main())
backend/scripts/run_migration.py scripts/run_migration.py
backend/scripts/simulate_broken_tracks.py scripts/simulate_broken_tracks.py
backend/scripts/smoke_test_staging.py scripts/smoke_test_staging.py
backend/scripts/test-transcoder.sh scripts/test-transcoder.sh
+5 -1
justfile
··· 23 23 changelog: 24 24 @git log $(git describe --tags --abbrev=0)..HEAD --pretty=format:'%C(yellow)%h%Creset %C(blue)%ad%Creset %C(green)%s%Creset %C(dim)- %an%Creset' --date=relative 25 25 26 + # create a github release (triggers production deployment) 27 + release: 28 + ./scripts/release 29 + 26 30 # deploy frontend only (promote remote main to production-fe branch) 27 31 release-frontend-only: 28 32 git fetch origin main 29 - git push origin origin/main:production-fe 33 + git push origin origin/main:production-fe
+122
scripts/release
··· 1 + #!/usr/bin/env -S uv run --script --quiet 2 + # /// script 3 + # requires-python = ">=3.12" 4 + # dependencies = [] 5 + # /// 6 + """create a github release using timestamp-based versioning 7 + 8 + version format: YYYY.MMDD.HHMMSS (e.g., 2025.1106.134523) 9 + 10 + usage: 11 + just release 12 + ./scripts/release 13 + """ 14 + 15 + import subprocess 16 + import sys 17 + from datetime import UTC, datetime 18 + 19 + 20 + def main() -> int: 21 + """create release with timestamp version.""" 22 + # ensure we're on main branch 23 + result = subprocess.run( 24 + ["git", "branch", "--show-current"], 25 + capture_output=True, 26 + text=True, 27 + check=True, 28 + ) 29 + current_branch = result.stdout.strip() 30 + 31 + if current_branch != "main": 32 + print(f"❌ must be on main branch (currently on {current_branch})") 33 + return 1 34 + 35 + # ensure working directory is clean 36 + result = subprocess.run( 37 + ["git", "status", "--porcelain"], 38 + capture_output=True, 39 + text=True, 40 + check=True, 41 + ) 42 + if result.stdout.strip(): 43 + print("❌ working directory has uncommitted changes") 44 + return 1 45 + 46 + # ensure we're up to date with remote 47 + subprocess.run(["git", "fetch"], capture_output=True, check=True) 48 + result = subprocess.run( 49 + ["git", "rev-list", "HEAD..@{u}"], 50 + capture_output=True, 51 + text=True, 52 + check=True, 53 + ) 54 + if result.stdout.strip(): 55 + print("❌ local branch is behind remote - please pull first") 56 + return 1 57 + 58 + # check if there are backend changes since last release 59 + result = subprocess.run( 60 + ["gh", "release", "list", "--limit", "1"], 61 + capture_output=True, 62 + text=True, 63 + check=True, 64 + ) 65 + if result.stdout.strip(): 66 + last_release = result.stdout.split()[0] 67 + 68 + # check for backend changes since last release 69 + result = subprocess.run( 70 + ["git", "log", f"{last_release}..HEAD", "--oneline", "--", "backend/src/backend/"], 71 + capture_output=True, 72 + text=True, 73 + check=True, 74 + ) 75 + 76 + if not result.stdout.strip(): 77 + print("❌ no backend changes since last release") 78 + print(f" last release: {last_release}") 79 + print(" only frontend/docs changes do not require a backend release") 80 + return 1 81 + 82 + version = datetime.now(UTC).strftime("%Y.%m%d.%H%M%S") 83 + 84 + # print banner using figlet 85 + subprocess.run(["figlet", "-f", "small", "plyr.fm"], check=False) 86 + print("───────────────────────────") 87 + print(f"release {version}") 88 + print("target production") 89 + print("───────────────────────────") 90 + 91 + # create release - gh will auto-generate notes from commits 92 + subprocess.run( 93 + [ 94 + "gh", 95 + "release", 96 + "create", 97 + version, 98 + "--title", 99 + version, 100 + "--generate-notes", 101 + ], 102 + check=True, 103 + ) 104 + 105 + print(f"\n✓ release {version} created") 106 + print("✓ production backend deployment starting...") 107 + 108 + # merge main -> production-fe to trigger frontend deployment 109 + print("\n🔄 updating production-fe branch...") 110 + subprocess.run(["git", "fetch", "origin"], check=True) 111 + subprocess.run(["git", "checkout", "production-fe"], check=True) 112 + subprocess.run(["git", "merge", "main", "--ff-only"], check=True) 113 + subprocess.run(["git", "push", "origin", "production-fe"], check=True) 114 + subprocess.run(["git", "checkout", "main"], check=True) 115 + 116 + print("✓ production frontend deployment starting...") 117 + 118 + return 0 119 + 120 + 121 + if __name__ == "__main__": 122 + sys.exit(main())