From 90459495ff5ca2303985fee31093c6092db1716e Mon Sep 17 00:00:00 2001 From: "Michael S. Molina" <70410625+michael-s-molina@users.noreply.github.com> Date: Thu, 2 Jun 2022 10:07:57 -0300 Subject: [PATCH] docs: Updates release scripts and docs (#20231) * chore: Updates release scripts and docs * Adds default receiver --- RELEASING/README.md | 43 +++--- RELEASING/email_templates/announce.j2 | 2 +- RELEASING/email_templates/result_pmc.j2 | 2 +- RELEASING/email_templates/vote_pmc.j2 | 2 +- .../{send_email.py => generate_email.py} | 137 ++---------------- 5 files changed, 36 insertions(+), 150 deletions(-) rename RELEASING/{send_email.py => generate_email.py} (53%) diff --git a/RELEASING/README.md b/RELEASING/README.md index e48728d1b..470c890ba 100644 --- a/RELEASING/README.md +++ b/RELEASING/README.md @@ -85,7 +85,6 @@ virtualenv venv source venv/bin/activate ``` - In addition, we recommend using the [`cherrytree`](https://pypi.org/project/cherrytree/) tool for automating cherry picking, as it will help speed up the release process. To install `cherrytree` and other dependencies that are required for the release process, run the following commands: @@ -105,19 +104,21 @@ the wrong files/using wrong names. There's a script to help you set correctly al necessary environment variables. Change your current directory to `superset/RELEASING` and execute the `set_release_env.sh` script with the relevant parameters: - Usage (MacOS/ZSH): + ```bash cd RELEASING source set_release_env.sh ``` Usage (BASH): + ```bash . set_release_env.sh ``` Example: + ```bash source set_release_env.sh 1.5.1rc1 myid@apache.org ``` @@ -151,6 +152,7 @@ that belong to the MAJOR.MINOR version. The MAJOR.MINOR branch is normally a "cut" from a specific point in time from the master branch. When creating the initial minor release (e.g. 1.5.0), create a new branch: + ```bash git checkout master git pull @@ -195,7 +197,6 @@ by adding the `--no-dry-run` flag (`-nd` for short): cherrytree bake -r apache/superset -m master -l v${SUPERSET_GITHUB_BRANCH} -nd ${SUPERSET_GITHUB_BRANCH} ``` - #### Resolving conflicts If there are conflicts, you can issue the following command to apply all cherries up until the conflict automatically, and then @@ -246,6 +247,7 @@ python changelog.py --previous_version 1.4 --current_version ${SUPERSET_GITHUB_B You can get a list of pull requests with labels started with blocking, risk, hold, revert and security by using the parameter `--risk`. Example: + ```bash python changelog.py --previous_version 0.37 --current_version 0.38 changelog --access_token {GITHUB_TOKEN} --risk ``` @@ -287,6 +289,10 @@ git tag ${SUPERSET_VERSION_RC} git push origin ${SUPERSET_VERSION_RC} ``` +### Create a release on Github + +After submitting the tag, follow the steps [here](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository) to create the release. Use the vote email text as the content for the release description. Make sure to check the "This is a pre-release" checkbox for release canditates. You can check previous releases if you need an example. + ## Preparing the release candidate The first step of preparing an Apache Release is packaging a release candidate @@ -303,13 +309,14 @@ the tag and create a signed source tarball from it: Note that `make_tarball.sh`: - By default, the script assumes you have already executed an SVN checkout to `$HOME/svn/superset_dev`. -This can be overridden by setting `SUPERSET_SVN_DEV_PATH` environment var to a different svn dev directory + This can be overridden by setting `SUPERSET_SVN_DEV_PATH` environment var to a different svn dev directory - Will refuse to craft a new release candidate if a release already exists on your local svn dev directory - Will check `package.json` version number and fails if it's not correctly set ### Build and test the created source tarball To build and run the **local copy** of the recently created tarball: + ```bash # Build and run a release candidate tarball ./test_run_tarball.sh local @@ -331,6 +338,7 @@ svn update ### Build and test from SVN source tarball To build and run the recently created tarball **from SVN**: + ```bash # Build and run a release candidate tarball ./test_run_tarball.sh @@ -339,6 +347,7 @@ To build and run the recently created tarball **from SVN**: ``` ### Voting + Now you're ready to start the [VOTE] thread. Here's an example of a previous release vote thread: https://lists.apache.org/thread.html/e60f080ebdda26896214f7d3d5be1ccadfab95d48fbe813252762879@ @@ -347,17 +356,10 @@ To easily send a voting request to Superset community, still on the `superset/RE ```bash # Note: use Superset's virtualenv -(venv)$ python send_email.py vote_pmc +(venv)$ python generate_email.py vote_pmc ``` -The script will interactively ask for extra information so it can authenticate on the Apache Email Relay. -The release version and release candidate number are fetched from the previously set environment variables. - -``` -Sender email (ex: user@apache.org): your_apache_email@apache.org -Apache username: your_apache_user -Apache password: your_apache_password -``` +The script will generate the email text that should be sent to dev@superset.apache.org using an email client. The release version and release candidate number are fetched from the previously set environment variables. Once 3+ binding votes (by PMC members) have been cast and at least 72 hours have past, you can post a [RESULT] thread: @@ -367,23 +369,20 @@ To easily send the result email, still on the `superset/RELEASING` directory: ```bash # Note: use Superset's virtualenv -python send_email.py result_pmc +python generate_email.py result_pmc ``` The script will interactively ask for extra information needed to fill out the email template. Based on the voting description, it will generate a passing, non passing or non conclusive email. -here's an example: +Here's an example: ``` -Sender email (ex: user@apache.org): your_apache_email@apache.org -Apache username: your_apache_user -Apache password: your_apache_password A List of people with +1 binding vote (ex: Max,Grace,Krist): Daniel,Alan,Max,Grace A List of people with +1 non binding vote (ex: Ville): Ville A List of people with -1 vote (ex: John): ``` -Following the result thread, yet another [VOTE] thread should be +The script will generate the email text that should be sent to dev@superset.apache.org using an email client. The release version and release candidate number are fetched from the previously set environment variables. ### Validating a release @@ -392,6 +391,7 @@ https://www.apache.org/info/verification.html ## Publishing a successful release Upon a successful vote, you'll have to copy the folder into the non-"dev/" folder. + ```bash cp -r ~/svn/superset_dev/${SUPERSET_VERSION_RC}/ ~/svn/superset/${SUPERSET_VERSION}/ cd ~/svn/superset/ @@ -403,6 +403,7 @@ svn update ``` Then tag the final release: + ```bash # Go to the root directory of the repo, e.g. `~/src/superset` cd ~/src/superset/ @@ -434,9 +435,11 @@ Once it's all done, an [ANNOUNCE] thread announcing the release to the dev@ mail ```bash # Note use Superset's virtualenv -python send_email.py announce +python generate_email.py announce ``` +The script will generate the email text that should be sent to dev@superset.apache.org using an email client. The release version is fetched from the previously set environment variables. + ### GitHub Release Finally, so the GitHub UI reflects the latest release, you should create a release from the diff --git a/RELEASING/email_templates/announce.j2 b/RELEASING/email_templates/announce.j2 index 80038630d..5d5b2f67a 100644 --- a/RELEASING/email_templates/announce.j2 +++ b/RELEASING/email_templates/announce.j2 @@ -17,7 +17,7 @@ under the License. -#} To: {{ receiver_email }} -From: {{ sender_email }} + Subject: [ANNOUNCE] Apache {{ project_name }} version {{ version }} Released Hello Community, diff --git a/RELEASING/email_templates/result_pmc.j2 b/RELEASING/email_templates/result_pmc.j2 index be8804752..37b7eeda5 100644 --- a/RELEASING/email_templates/result_pmc.j2 +++ b/RELEASING/email_templates/result_pmc.j2 @@ -17,7 +17,7 @@ under the License. -#} To: {{ receiver_email }} -From: {{ sender_email }} + Subject: [RESULT] [VOTE] Release Apache {{ project_name }} {{ version }} based on Superset {{ version_rc }} Thanks to everyone that participated. The vote to release diff --git a/RELEASING/email_templates/vote_pmc.j2 b/RELEASING/email_templates/vote_pmc.j2 index 3b2cc1363..a6ebda72c 100644 --- a/RELEASING/email_templates/vote_pmc.j2 +++ b/RELEASING/email_templates/vote_pmc.j2 @@ -17,7 +17,7 @@ under the License. -#} To: {{ receiver_email }} -From: {{ sender_email }} + Subject: [VOTE] Release Apache {{ project_name }} {{ version }} based on Superset {{ version_rc }} Hello {{ project_name }} Community, diff --git a/RELEASING/send_email.py b/RELEASING/generate_email.py similarity index 53% rename from RELEASING/send_email.py rename to RELEASING/generate_email.py index a4b4a4496..92536670c 100755 --- a/RELEASING/send_email.py +++ b/RELEASING/generate_email.py @@ -15,9 +15,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # -import smtplib -import ssl -from typing import Any, Dict, List, Optional +from typing import Any, Dict, List from click.core import Context @@ -30,9 +28,7 @@ try: except ModuleNotFoundError: exit("Click is a required dependency for this script") - -SMTP_PORT = 587 -SMTP_SERVER = "mail-relay.apache.org" +RECEIVER_EMAIL = "dev@superset.apache.org" PROJECT_NAME = "Superset" PROJECT_MODULE = "superset" PROJECT_DESCRIPTION = "Apache Superset is a modern, enterprise-ready business intelligence web application" @@ -44,25 +40,6 @@ def string_comma_to_list(message: str) -> List[str]: return [element.strip() for element in message.split(",")] -def send_email( - smtp_server: str, - smpt_port: int, - username: str, - password: str, - sender_email: str, - receiver_email: str, - message: str, -) -> None: - """ - Send a simple text email (SMTP) - """ - context = ssl.create_default_context() - with smtplib.SMTP(smtp_server, smpt_port) as server: - server.starttls(context=context) - server.login(username, password) - server.sendmail(sender_email, receiver_email, message) - - def render_template(template_file: str, **kwargs: Any) -> str: """ Simple render template based on named parameters @@ -75,122 +52,49 @@ def render_template(template_file: str, **kwargs: Any) -> str: return template.render(kwargs) -def inter_send_email( - username: str, password: str, sender_email: str, receiver_email: str, message: str -) -> None: - print("--------------------------") - print("SMTP Message") - print("--------------------------") - print(message) - print("--------------------------") - confirm = input("Is the Email message ok? (yes/no): ") - if confirm not in ("Yes", "yes", "y"): - exit("Exit by user request") - - try: - send_email( - SMTP_SERVER, - SMTP_PORT, - username, - password, - sender_email, - receiver_email, - message, - ) - print("Email sent successfully") - except smtplib.SMTPAuthenticationError: - exit("SMTP User authentication error, Email not sent!") - except Exception as e: - exit(f"SMTP exception {e}") - - class BaseParameters(object): def __init__( self, - email: str, - username: str, - password: str, version: str, version_rc: str, ) -> None: - self.email = email - self.username = username - self.password = password self.version = version self.version_rc = version_rc self.template_arguments: Dict[str, Any] = {} def __repr__(self) -> str: - return f"Apache Credentials: {self.email}/{self.username}/{self.version}/{self.version_rc}" + return f"Apache Credentials: {self.version}/{self.version_rc}" @click.group() @click.pass_context -@click.option( - "--apache_email", - prompt="Apache Email", - help="Your Apache email this will be used for SMTP From", -) -@click.option( - "--apache_username", prompt="Apache username", help="Your LDAP Apache username" -) -@click.option( - "--apache_password", - prompt="Apache password", - hide_input=True, - help="Your LDAP Apache password", -) @click.option("--version", envvar="SUPERSET_VERSION") @click.option("--version_rc", envvar="SUPERSET_VERSION_RC") def cli( ctx: Context, - apache_email: str, - apache_username: str, - apache_password: str, version: str, version_rc: str, ) -> None: """Welcome to releasing send email CLI interface!""" - base_parameters = BaseParameters( - apache_email, apache_username, apache_password, version, version_rc - ) + base_parameters = BaseParameters(version, version_rc) + base_parameters.template_arguments["receiver_email"] = RECEIVER_EMAIL base_parameters.template_arguments["project_name"] = PROJECT_NAME base_parameters.template_arguments["project_module"] = PROJECT_MODULE base_parameters.template_arguments["project_description"] = PROJECT_DESCRIPTION base_parameters.template_arguments["version"] = base_parameters.version base_parameters.template_arguments["version_rc"] = base_parameters.version_rc - base_parameters.template_arguments["sender_email"] = base_parameters.email ctx.obj = base_parameters @cli.command("vote_pmc") -@click.option( - "--receiver_email", - default="dev@superset.apache.org", - type=str, - prompt="The receiver email (To:)", -) @click.pass_obj -def vote_pmc(base_parameters: BaseParameters, receiver_email: str) -> None: +def vote_pmc(base_parameters: BaseParameters) -> None: template_file = "email_templates/vote_pmc.j2" - base_parameters.template_arguments["receiver_email"] = receiver_email message = render_template(template_file, **base_parameters.template_arguments) - inter_send_email( - base_parameters.username, - base_parameters.password, - base_parameters.template_arguments["sender_email"], - base_parameters.template_arguments["receiver_email"], - message, - ) + print(message) @cli.command("result_pmc") -@click.option( - "--receiver_email", - default="dev@superset.apache.org", - type=str, - prompt="The receiver email (To:)", -) @click.option( "--vote_bindings", default="", @@ -219,14 +123,12 @@ def vote_pmc(base_parameters: BaseParameters, receiver_email: str) -> None: @click.pass_obj def result_pmc( base_parameters: BaseParameters, - receiver_email: str, vote_bindings: str, vote_nonbindings: str, vote_negatives: str, vote_thread: str, ) -> None: template_file = "email_templates/result_pmc.j2" - base_parameters.template_arguments["receiver_email"] = receiver_email base_parameters.template_arguments["vote_bindings"] = string_comma_to_list( vote_bindings ) @@ -238,34 +140,15 @@ def result_pmc( ) base_parameters.template_arguments["vote_thread"] = vote_thread message = render_template(template_file, **base_parameters.template_arguments) - inter_send_email( - base_parameters.username, - base_parameters.password, - base_parameters.template_arguments["sender_email"], - base_parameters.template_arguments["receiver_email"], - message, - ) + print(message) @cli.command("announce") -@click.option( - "--receiver_email", - default="dev@superset.apache.org", - type=str, - prompt="The receiver email (To:)", -) @click.pass_obj -def announce(base_parameters: BaseParameters, receiver_email: str) -> None: +def announce(base_parameters: BaseParameters) -> None: template_file = "email_templates/announce.j2" - base_parameters.template_arguments["receiver_email"] = receiver_email message = render_template(template_file, **base_parameters.template_arguments) - inter_send_email( - base_parameters.username, - base_parameters.password, - base_parameters.template_arguments["sender_email"], - base_parameters.template_arguments["receiver_email"], - message, - ) + print(message) cli()