Skip to content

Commit

Permalink
Release Automation [Milestone 3]: Added automation for wrapping up th…
Browse files Browse the repository at this point in the history
…e release (oppia#7779)

* Add automation for generating release updates mail

* Add automation for wrapping up the release

* Update methods for updating configs, add test

* Restore reverted file

* Fix coverage

* Address review comments

* Fix tests

* Address review comments

* Address review comments

* Address review comments

* Fix test
  • Loading branch information
ankita240796 authored and nithusha21 committed Oct 25, 2019
1 parent 4f1cf3e commit 0882e43
Show file tree
Hide file tree
Showing 27 changed files with 1,488 additions and 109 deletions.
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@
/core/templates/dev/head/services/contextual/DocumentAttributeCustomizationService.ts @YashJipkate
/core/templates/dev/head/services/contextual/MetaTagCustomizationService.ts @YashJipkate
/core/templates/dev/head/services/TranslationFileHashLoaderService.ts @DubeySandeep
/release_constants.py @ankita240796 @nithusha21 @DubeySandeep @seanlip


# Miscellaneous.
Expand Down
1 change: 1 addition & 0 deletions core/tests/release_sources/UPDATED_AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
Alice <[email protected]>
Alison <[email protected]>
Bob <[email protected]>
Casie <[email protected]>
Jessica <[email protected]>
Paul <[email protected]>
Quent <[email protected]>
Expand Down
5 changes: 5 additions & 0 deletions core/tests/release_sources/feconf.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,8 @@ CURRENT_COLLECTION_SCHEMA_VERSION = 4

# The current version of story contents dict in the story schema.
CURRENT_STORY_CONTENTS_SCHEMA_VERSION = 1

INCOMING_EMAILS_DOMAIN_NAME = ''
ADMIN_EMAIL_ADDRESS = '[email protected]'
SYSTEM_EMAIL_ADDRESS = '[email protected]'
NOREPLY_EMAIL_ADDRESS = '[email protected]'
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
EXTRA_KEY = 'extra'
INCOMING_EMAILS_DOMAIN_NAME = '[email protected]'
ADMIN_EMAIL_ADDRESS = '[email protected]'
SYSTEM_EMAIL_ADDRESS = '[email protected]'
NOREPLY_EMAIL_ADDRESS = '[email protected]'
5 changes: 5 additions & 0 deletions core/tests/release_sources/invalid_feconf_updates.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
INVALID_KEY: 'invalid'
INCOMING_EMAILS_DOMAIN_NAME = '[email protected]'
ADMIN_EMAIL_ADDRESS = '[email protected]'
SYSTEM_EMAIL_ADDRESS = '[email protected]'
NOREPLY_EMAIL_ADDRESS = '[email protected]'
12 changes: 12 additions & 0 deletions core/tests/release_sources/invalid_release_mail_message.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Hi all,

The main changes in this release are [Add main changes].

Please welcome Alice for whom this release marks their first contribution to Oppia!

Thanks to Bob and Paul, our returning contributors who made this release possible.

Finally, I'd like to thank [Add names of release testers] for their help with pre-release testing, bug-fixing and QA, as well as Tom for leading the QA team for this release.

Thanks,
Ruth
1 change: 1 addition & 0 deletions core/tests/release_sources/release_summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ This indicates that a migration may be needed
### New Authors:
* Alice <[email protected]>
* Bob <[email protected]>
* Casie <[email protected]>
* Quent <[email protected]>
* Zoe <[email protected]>

Expand Down
4 changes: 4 additions & 0 deletions core/tests/release_sources/valid_feconf_updates.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
INCOMING_EMAILS_DOMAIN_NAME = 'oppia.org'
ADMIN_EMAIL_ADDRESS = '[email protected]'
SYSTEM_EMAIL_ADDRESS = '[email protected]'
NOREPLY_EMAIL_ADDRESS = '[email protected]'
12 changes: 12 additions & 0 deletions core/tests/release_sources/valid_release_mail_message.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Hi all,

The main changes in this release are release testing.

Please welcome Alice for whom this release marks their first contribution to Oppia!

Thanks to Bob and Paul, our returning contributors who made this release possible.

Finally, I'd like to thank Smith for their help with pre-release testing, bug-fixing and QA, as well as Tom for leading the QA team for this release.

Thanks,
Ruth
4 changes: 0 additions & 4 deletions feconf.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,6 @@
# Whether to unconditionally log info messages.
DEBUG = False

# The path for generating release_summary.md file for the current release.
RELEASE_SUMMARY_FILEPATH = os.path.join(
os.getcwd(), os.pardir, 'release_summary.md')

# When DEV_MODE is true check that we are running in development environment.
# The SERVER_SOFTWARE environment variable does not exist in Travis, hence the
# need for an explicit check.
Expand Down
38 changes: 38 additions & 0 deletions release_constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# coding: utf-8
#
# Copyright 2019 The Oppia Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS-IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Stores various constants for Oppia release."""

from __future__ import absolute_import # pylint: disable=import-only-modules
from __future__ import unicode_literals # pylint: disable=import-only-modules

import os

# Affirmative user confirmations.
AFFIRMATIVE_CONFIRMATIONS = ['y', 'ye', 'yes']

# PyGithub can fetch milestone only by using the milestone number. Milestones
# are numbered sequentially as they are created and the number remains fixed.
# The number for blocking_bugs milestone is 39 which is used to fetch this
# milestone.
BLOCKING_BUG_MILESTONE_NUMBER = 39

LABEL_FOR_CURRENT_RELEASE_PRS = 'PR: for current release'
LABEL_FOR_RELEASED_PRS = 'PR: released'

# The path for generating release_summary.md file for the current release.
RELEASE_SUMMARY_FILEPATH = os.path.join(
os.getcwd(), os.pardir, 'release_summary.md')
44 changes: 43 additions & 1 deletion scripts/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@
from __future__ import unicode_literals # pylint: disable=import-only-modules

import contextlib
import getpass
import os
import re
import socket
import subprocess

import python_utils
import release_constants

RELEASE_BRANCH_NAME_PREFIX = 'release-'
CURR_DIR = os.path.abspath(os.getcwd())
Expand Down Expand Up @@ -148,7 +151,7 @@ def is_current_branch_a_release_branch():
bool. Whether the current branch is a release branch.
"""
current_branch_name = get_current_branch_name()
return current_branch_name.startswith(RELEASE_BRANCH_NAME_PREFIX)
return bool(re.match(r'release-\d+\.\d+\.\d+$', current_branch_name))


def verify_current_branch_name(expected_branch_name):
Expand Down Expand Up @@ -266,6 +269,45 @@ def install_npm_library(library_name, version, path):
'yarn', 'add', '%s@%s' % (library_name, version)])


def ask_user_to_confirm(message):
"""Asks user to perform a task and confirm once they are done.
Args:
message: str. The message which specifies the task user has
to do.
"""
while True:
python_utils.PRINT(
'******************************************************')
python_utils.PRINT(message)
python_utils.PRINT('Confirm once you are done by entering y/ye/yes.\n')
answer = python_utils.INPUT().lower()
if answer in release_constants.AFFIRMATIVE_CONFIRMATIONS:
return


def get_personal_access_token():
""""Returns the personal access token for the GitHub id of user.
Returns:
str. The personal access token for the GitHub id of user.
Raises:
Exception: Personal access token is None.
"""
personal_access_token = getpass.getpass(
prompt=(
'Please provide personal access token for your github ID. '
'You can create one at https://github.com/settings/tokens: '))

if personal_access_token is None:
raise Exception(
'No personal access token provided, please set up a personal '
'access token at https://github.com/settings/tokens and re-run '
'the script')
return personal_access_token


class CD(python_utils.OBJECT):
"""Context manager for changing the current working directory."""

Expand Down
28 changes: 28 additions & 0 deletions scripts/common_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from __future__ import unicode_literals # pylint: disable=import-only-modules

import contextlib
import getpass
import http.server
import os
import shutil
Expand Down Expand Up @@ -347,3 +348,30 @@ def _mock_subprocess_call(unused_command):

with self.swap(subprocess, 'call', _mock_subprocess_call):
common.install_npm_library('library_name', 'version', 'path')

def test_ask_user_to_confirm(self):
def mock_input():
return 'Y'
with self.swap(python_utils, 'INPUT', mock_input):
common.ask_user_to_confirm('Testing')

def test_get_personal_access_token_with_valid_token(self):
# pylint: disable=unused-argument
def mock_getpass(prompt):
return 'token'
# pylint: enable=unused-argument
with self.swap(getpass, 'getpass', mock_getpass):
self.assertEqual(common.get_personal_access_token(), 'token')

def test_get_personal_access_token_with_token_as_none(self):
# pylint: disable=unused-argument
def mock_getpass(prompt):
return None
# pylint: enable=unused-argument
getpass_swap = self.swap(getpass, 'getpass', mock_getpass)
with getpass_swap, self.assertRaisesRegexp(
Exception,
'No personal access token provided, please set up a personal '
'access token at https://github.com/settings/tokens and re-run '
'the script'):
common.get_personal_access_token()
3 changes: 2 additions & 1 deletion scripts/create_topological_sort_of_all_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ def main():


# The 'no coverage' pragma is used as this line is un-testable. This is because
# it will only be called when build.py is used as a script.
# it will only be called when create_topological_sort_of_all_services.py
# is used as a script.
if __name__ == '__main__': # pragma: no cover
main()
3 changes: 2 additions & 1 deletion scripts/cut_release_branch.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import sys

import python_utils
import release_constants

from . import common

Expand Down Expand Up @@ -168,7 +169,7 @@ def _execute_branch_cut():
python_utils.PRINT(
'Please confirm: are Travis checks passing on develop? (y/n) ')
answer = python_utils.INPUT().lower()
if answer in ['y', 'ye', 'yes']:
if answer in release_constants.AFFIRMATIVE_CONFIRMATIONS:
break
elif answer:
python_utils.PRINT(
Expand Down
3 changes: 2 additions & 1 deletion scripts/deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import subprocess

import python_utils
import release_constants

from . import common
from . import gcloud_adapter
Expand Down Expand Up @@ -189,7 +190,7 @@ def check_errors_in_a_page(url_to_check, msg_to_confirm):
'PLEASE CONFIRM: %s See %s '
'(y/n)' % (msg_to_confirm, url_to_check))
answer = python_utils.INPUT().lower()
if answer in ['y', 'ye', 'yes']:
if answer in release_constants.AFFIRMATIVE_CONFIRMATIONS:
return True
elif answer:
return False
Expand Down
Loading

0 comments on commit 0882e43

Please sign in to comment.