|
| 1 | +#!/usr/bin/env python3 |
| 2 | +""" |
| 3 | +Announces the Fenix beta cut in #mobile-android-team on desktop merge day. |
| 4 | +
|
| 5 | +Run daily by .github/workflows/fenix-beta-cut-slack.yml. It reads the current |
| 6 | +Nightly's schedule and posts only when today is that version's merge day, so it is |
| 7 | +safe to run every day of the year. |
| 8 | +
|
| 9 | +The run is deliberately scheduled ahead of the merge. The version bump |
| 10 | +lands during merge day itself, and once it has, "nightly" answers with the next |
| 11 | +major, whose merge day is a fortnight away. Asking before the merge gets the version |
| 12 | +that is merging today. |
| 13 | +
|
| 14 | +Requires the SLACK_WEBHOOK_URL environment variable (set from the |
| 15 | +MOBILE_ANDROID_TEAM_SLACK_WEBHOOK repo secret in the workflow, named for the |
| 16 | +#mobile-android-team channel it posts to). |
| 17 | +
|
| 18 | +Env vars for testing: |
| 19 | + DRY_RUN=1 print the message instead of posting it. Accepts |
| 20 | + 1/true/yes/on to enable and 0/false/no/off or empty to |
| 21 | + disable; anything else is an error rather than a guess. |
| 22 | + TEST_DATE=Y-m-d pretend today is this date, to exercise a merge day that |
| 23 | + isn't today (e.g. 2026-08-27) |
| 24 | +""" |
| 25 | +import os |
| 26 | +import sys |
| 27 | +from datetime import datetime |
| 28 | + |
| 29 | +from lib.env import env_flag |
| 30 | +from lib.schedule import fetch_schedule, parse_date, today as utc_today |
| 31 | +from lib.slack import post_to_slack |
| 32 | + |
| 33 | +# Slack has no list markdown — a literal bullet character is how you get a list. |
| 34 | +MESSAGE = ( |
| 35 | + "*Fenix Beta Cut Time*\n" |
| 36 | + "Today is the <https://whattrainisitnow.com/release/?version={version}|FX{version}> " |
| 37 | + "merge day. Later today, release management will merge main to beta, and then bump main to " |
| 38 | + "{next_version}.\n" |
| 39 | + "• Who's responsible? Check <https://www.whoisdoingwhat.dev/|here> to see which " |
| 40 | + "squad is assigned.\n" |
| 41 | + "• Taking on the starting the nightly Fx{next_version} development cycle? Please " |
| 42 | + "leave a message here to let others know.\n" |
| 43 | + "• Need instructions? Find them <https://firefox-source-docs.mozilla.org/mobile/" |
| 44 | + "android/fenix/release-checklist.html|here>." |
| 45 | +) |
| 46 | + |
| 47 | + |
| 48 | +def main() -> int: |
| 49 | + dry_run = env_flag("DRY_RUN") |
| 50 | + webhook_url = os.environ.get("SLACK_WEBHOOK_URL") |
| 51 | + if not webhook_url and not dry_run: |
| 52 | + print("SLACK_WEBHOOK_URL is not set — nothing to do.", file=sys.stderr) |
| 53 | + return 1 |
| 54 | + |
| 55 | + test_date = os.environ.get("TEST_DATE") |
| 56 | + if test_date: |
| 57 | + today = datetime.strptime(test_date, "%Y-%m-%d").date() |
| 58 | + print(f"TEST MODE: pretending today is {today}") |
| 59 | + else: |
| 60 | + today = utc_today() |
| 61 | + |
| 62 | + schedule = fetch_schedule("nightly") |
| 63 | + merge_day = parse_date(schedule["merge_day"]) |
| 64 | + if today != merge_day: |
| 65 | + print(f"{today}: not merge day (next one is {merge_day}). Nothing to post.") |
| 66 | + return 0 |
| 67 | + |
| 68 | + # "156.0" -> 156: the message talks about the major, not the build. |
| 69 | + version = int(schedule["version"].split(".")[0]) |
| 70 | + text = MESSAGE.format(version=version, next_version=version + 1) |
| 71 | + |
| 72 | + if dry_run: |
| 73 | + print(f"DRY RUN — would post:\n{text}") |
| 74 | + return 0 |
| 75 | + |
| 76 | + post_to_slack(webhook_url, text) |
| 77 | + print(f"{today}: posted the Fenix beta cut announcement for Firefox {version}.") |
| 78 | + return 0 |
| 79 | + |
| 80 | + |
| 81 | +if __name__ == "__main__": |
| 82 | + raise SystemExit(main()) |
0 commit comments