docs: Updates release scripts and docs (#20231)
* chore: Updates release scripts and docs * Adds default receiver
This commit is contained in:
parent
d4f320f2a0
commit
90459495ff
|
|
@ -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 <SUPERSET_RC_VERSION> <PGP_KEY_FULLNAME>
|
||||
```
|
||||
|
||||
Usage (BASH):
|
||||
|
||||
```bash
|
||||
. set_release_env.sh <SUPERSET_RC_VERSION> <PGP_KEY_FULLNAME>
|
||||
```
|
||||
|
||||
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@<dev.superset.apache.org>
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
under the License.
|
||||
-#}
|
||||
To: {{ receiver_email }}
|
||||
From: {{ sender_email }}
|
||||
|
||||
Subject: [ANNOUNCE] Apache {{ project_name }} version {{ version }} Released
|
||||
|
||||
Hello Community,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
Loading…
Reference in New Issue