This repository was archived by the owner on Apr 26, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Extend the release script to wait for GitHub Actions to finish and to be usable as a guide for the whole process. #13483
Merged
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
155a609
Split out underlying functions so that they are callable
reivilibre b7efe5d
Add a command for waiting for the actions to complete
reivilibre 74ec208
Note that the blog post and tweets exist
reivilibre 437ba66
Add 'full' command that does everything from start to finish
reivilibre 358024a
Newsfile
reivilibre 3072ff2
Extend help text to mention the full command
reivilibre e89d840
Shuffle order around
reivilibre 54a0e49
TODO debs ready automation
reivilibre 2078dc9
Use GH_TOKEN for checking workflows if we have one
reivilibre 9ff4981
Make gh_token not required
reivilibre a0b9236
Merge branch 'develop' into rei/release_script_full
reivilibre File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Extend the release script to wait for GitHub Actions to finish and to be usable as a guide for the whole process. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,10 +18,12 @@ | |
""" | ||
|
||
import glob | ||
import json | ||
import os | ||
import re | ||
import subprocess | ||
import sys | ||
import time | ||
import urllib.request | ||
from os import path | ||
from tempfile import TemporaryDirectory | ||
|
@@ -71,25 +73,32 @@ def cli() -> None: | |
|
||
./scripts-dev/release.py tag | ||
|
||
# ... wait for assets to build ... | ||
# wait for assets to build, either manually or with: | ||
./scripts-dev/release.py wait-for-actions | ||
|
||
./scripts-dev/release.py publish | ||
|
||
./scripts-dev/release.py upload | ||
|
||
# Optional: generate some nice links for the announcement | ||
|
||
./scripts-dev/release.py merge-back | ||
|
||
# Optional: generate some nice links for the announcement | ||
./scripts-dev/release.py announce | ||
|
||
Alternatively, `./scripts-dev/release.py full` will do all the above | ||
as well as guiding you through the manual steps. | ||
|
||
If the env var GH_TOKEN (or GITHUB_TOKEN) is set, or passed into the | ||
`tag`/`publish` command, then a new draft release will be created/published. | ||
""" | ||
|
||
|
||
@cli.command() | ||
def prepare() -> None: | ||
_prepare() | ||
|
||
|
||
def _prepare() -> None: | ||
"""Do the initial stages of creating a release, including creating release | ||
branch, updating changelog and pushing to GitHub. | ||
""" | ||
|
@@ -284,6 +293,10 @@ def prepare() -> None: | |
@cli.command() | ||
@click.option("--gh-token", envvar=["GH_TOKEN", "GITHUB_TOKEN"]) | ||
def tag(gh_token: Optional[str]) -> None: | ||
_tag(gh_token) | ||
|
||
|
||
def _tag(gh_token: Optional[str]) -> None: | ||
"""Tags the release and generates a draft GitHub release""" | ||
|
||
# Make sure we're in a git repo. | ||
|
@@ -374,6 +387,10 @@ def tag(gh_token: Optional[str]) -> None: | |
@cli.command() | ||
@click.option("--gh-token", envvar=["GH_TOKEN", "GITHUB_TOKEN"], required=True) | ||
def publish(gh_token: str) -> None: | ||
_publish(gh_token) | ||
|
||
|
||
def _publish(gh_token: str) -> None: | ||
"""Publish release on GitHub.""" | ||
|
||
# Make sure we're in a git repo. | ||
|
@@ -411,6 +428,10 @@ def publish(gh_token: str) -> None: | |
|
||
@cli.command() | ||
def upload() -> None: | ||
_upload() | ||
|
||
|
||
def _upload() -> None: | ||
"""Upload release to pypi.""" | ||
|
||
current_version = get_package_version() | ||
|
@@ -479,8 +500,75 @@ def _merge_into(repo: Repo, source: str, target: str) -> None: | |
repo.remote().push() | ||
|
||
|
||
@cli.command() | ||
@click.option("--gh-token", envvar=["GH_TOKEN", "GITHUB_TOKEN"], required=False) | ||
def wait_for_actions(gh_token: Optional[str]) -> None: | ||
_wait_for_actions(gh_token) | ||
|
||
|
||
def _wait_for_actions(gh_token: Optional[str]) -> None: | ||
# Find out the version and tag name. | ||
current_version = get_package_version() | ||
tag_name = f"v{current_version}" | ||
|
||
# Authentication is optional on this endpoint, | ||
# but use a token if we have one to reduce the chance of being rate-limited. | ||
url = f"https://api.github.com/repos/matrix-org/synapse/actions/runs?branch={tag_name}" | ||
headers = {"Accept": "application/vnd.github+json"} | ||
if gh_token is not None: | ||
headers["authorization"] = f"token {gh_token}" | ||
req = urllib.request.Request(url, headers=headers) | ||
|
||
time.sleep(10 * 60) | ||
while True: | ||
time.sleep(5 * 60) | ||
response = urllib.request.urlopen(req) | ||
resp = json.loads(response.read()) | ||
|
||
if len(resp["workflow_runs"]) == 0: | ||
continue | ||
|
||
if all( | ||
workflow["status"] != "in_progress" for workflow in resp["workflow_runs"] | ||
): | ||
success = ( | ||
workflow["status"] == "completed" for workflow in resp["workflow_runs"] | ||
) | ||
if success: | ||
_notify("Workflows successful. You can now continue the release.") | ||
else: | ||
_notify("Workflows failed.") | ||
click.confirm("Continue anyway?", abort=True) | ||
|
||
break | ||
|
||
|
||
def _notify(message: str) -> None: | ||
# Send a bell character. Most terminals will play a sound or show a notification | ||
# for this. | ||
click.echo(f"\a{message}") | ||
|
||
# Try and run notify-send, but don't raise an Exception if this fails | ||
# (This is best-effort) | ||
# TODO Support other platforms? | ||
subprocess.run( | ||
[ | ||
"notify-send", | ||
"--app-name", | ||
"Synapse Release Script", | ||
"--expire-time", | ||
"3600000", | ||
message, | ||
] | ||
) | ||
|
||
|
||
@cli.command() | ||
def merge_back() -> None: | ||
_merge_back() | ||
|
||
|
||
def _merge_back() -> None: | ||
"""Merge the release branch back into the appropriate branches. | ||
All branches will be automatically pulled from the remote and the results | ||
will be pushed to the remote.""" | ||
|
@@ -519,6 +607,10 @@ def merge_back() -> None: | |
|
||
@cli.command() | ||
def announce() -> None: | ||
_announce() | ||
|
||
|
||
def _announce() -> None: | ||
"""Generate markdown to announce the release.""" | ||
|
||
current_version = get_package_version() | ||
|
@@ -548,10 +640,56 @@ def announce() -> None: | |
- #homeowners:matrix.org (Synapse Announcements), bumping the version in the topic | ||
- #synapse:matrix.org (Synapse Admins), bumping the version in the topic | ||
- #synapse-dev:matrix.org | ||
- #synapse-package-maintainers:matrix.org""" | ||
- #synapse-package-maintainers:matrix.org | ||
|
||
Ask the designated people to do the blog and tweets.""" | ||
) | ||
|
||
|
||
@cli.command() | ||
@click.option("--gh-token", envvar=["GH_TOKEN", "GITHUB_TOKEN"], required=True) | ||
def full(gh_token: str) -> None: | ||
click.echo("1. If this is a security release, read the security wiki page.") | ||
click.echo("2. Check for any release blockers before proceeding.") | ||
click.echo(" https://github.com/matrix-org/synapse/labels/X-Release-Blocker") | ||
|
||
click.confirm("Ready?", abort=True) | ||
|
||
click.echo("\n*** prepare ***") | ||
_prepare() | ||
|
||
click.echo("Deploy to matrix.org and ensure that it hasn't fallen over.") | ||
click.echo("Remember to silence the alerts to prevent alert spam.") | ||
click.confirm("Deployed?", abort=True) | ||
|
||
click.echo("\n*** tag ***") | ||
_tag(gh_token) | ||
|
||
click.echo("\n*** wait for actions ***") | ||
_wait_for_actions(gh_token) | ||
|
||
click.echo("\n*** publish ***") | ||
_publish(gh_token) | ||
|
||
click.echo("\n*** upload ***") | ||
_upload() | ||
|
||
click.echo("\n*** merge back ***") | ||
_merge_back() | ||
|
||
click.echo("\nUpdate the Debian repository") | ||
click.confirm("Started updating Debian repository?", abort=True) | ||
|
||
click.echo("\nWait for all release methods to be ready.") | ||
# Docker should be ready because it was done by the workflows earlier | ||
# PyPI should be ready because we just ran upload(). | ||
# TODO Automatically poll until the Debs have made it to packages.matrix.org | ||
click.confirm("Debs ready?", abort=True) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should be able to poll for the debs too There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suppose we can hit e.g. https://packages.matrix.org/debian/pool/main/m/matrix-synapse-py3/matrix-synapse-py3_1.66.0%2Bbuster1.dsc etc until it exists if that's what you mean? |
||
|
||
click.echo("\n*** announce ***") | ||
_announce() | ||
|
||
|
||
def get_package_version() -> version.Version: | ||
version_string = subprocess.check_output(["poetry", "version", "--short"]).decode( | ||
"utf-8" | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.