Repository: oppia/oppia

Issue:
Fix the release script
We have a release script in `scripts/release_info.py` which summarizes the commits which happened since the last release. Since we changed the release process, this script no longer works.

The new release process works like:
1. A release branch (named `release-x.x.x` is made off of `develop`)
2. Possibly more commits from develop (made after the release branch is cut) will be cherry-picked onto the release branch
3. When the release is finalized, the tip of the release branch is tagged.

What should happen is:
When the release info script is run, it should get a list of all commits on the current branch that do not appear on the last release branch (this is currently not working), and then summarize these (this is working as expected).

cc @seanlip @tjiang11 


Discussion:
Can you tell me what the previous release process was like so that I can compare the two, figure out the differences and decide how to write the code for the new process?
Hi @palash25, sure! What used to happen was that we would do the following during a release:
- Check out a release branch from develop
- Make a bunch of fixes to the release branch, while develop happily continues to evolve on its own
- Just before releasing: create the changelog etc. for the release by running the release info script
- Tag the release branch
- Merge the release branch into master

So, the release script would just look at all commits since the last tag and generate a list of commits that have been made since then. I think this is no longer correct, though. Does this answer your question?

Also, @wxyxinyu -- please could you double-check my answer and make corrections if needed? (@wxyxinyu has the most knowledge of Oppia's release process, having coordinated it for at least the past year.)
@seanlip the only difference I see with the two processes is that you didn't mention cherry picking commits from the develop branch onto the release branch for the older old release process. So correct me if I'm wrong we only need to add a cherry picking function to the release script to make it compatible with the new release process right? Also do we tag the release branch before or after we create the changelog by running the script?
the main difference is that, we used to merge the release branch back into develop after we were done making release-related changes. what's happening with the release script now is that the `_gather_logs` function is picking up all the changes since we changed the release process.

we tag the release branch after running the script
Also, I don't think we need a cherry-picking function? The release script isn't meant to do the release steps, it's just to help with generating the changelog/authors for the release. So, it looks like we just need to fix the `_gather_logs` function in the release script to actually only get the commits which are not on the last release branch but are on develop

Resolving patch:
diff --git a/scripts/release_info.py b/scripts/release_info.py
--- a/scripts/release_info.py
+++ b/scripts/release_info.py
@@ -24,7 +24,8 @@
 import subprocess
 import sys
 
-GIT_CMD_GET_CURRENT_VERSION = 'git describe --abbrev=0'
+GIT_CMD_GET_TAGS = 'git tag'
+GIT_CMD_GET_LCA_WITH_DEVELOP = 'git merge-base develop %s'
 GIT_CMD_GET_LOGS_FORMAT_STRING = (
     'git log -z --no-color --pretty=format:%H{0}%aN{0}%aE{0}%B {1}..{2}')
 GIT_CMD_DIFF_NAMES_ONLY_FORMAT_STRING = 'git diff --name-only %s %s'
@@ -74,6 +75,29 @@ def _run_cmd(cmd_str):
     return subprocess.check_output(cmd_str.split(' ')).strip()
 
 
+def _get_current_version_tag():
+    """Retrieves the most recent version tag.
+
+    Returns:
+        (str): The most recent version tag.
+    """
+    tags = _run_cmd(GIT_CMD_GET_TAGS).splitlines()
+    return tags[-1]
+
+
+def _get_base_commit_with_develop(reference):
+    """Retrieves the commit hash common between the develop branch and the
+    specified reference commit.
+
+    Args:
+        reference (str): Tag, Branch, or commit hash of reference commit.
+
+    Returns:
+        (str): The common commit hash.
+    """
+    return _run_cmd(GIT_CMD_GET_LCA_WITH_DEVELOP % reference)
+
+
 def _gather_logs(start, stop='HEAD'):
     """Gathers the logs between the start and endpoint.
 
@@ -191,8 +215,9 @@ def _check_storage_models(current_release):
 def main():
     """Collects necessary info and dumps it to disk."""
     with ChangedBranch('develop'):
-        current_release = _run_cmd(GIT_CMD_GET_CURRENT_VERSION)
-        logs = _gather_logs(current_release)
+        current_release = _get_current_version_tag()
+        base_commit = _get_base_commit_with_develop(current_release)
+        logs = _gather_logs(base_commit)
         issue_links = _extract_issues(logs)
         feconf_version_changes = _check_versions(current_release)
         setup_changes = _check_setup_scripts(current_release)


Test patch: