Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 64965cff authored by Corey Bryant's avatar Corey Bryant
Browse files

Add merge scripts

The merge scripts help with merge automation. They need to be run
by a human at this point to ensure any conflicts can be handled
manually.

The scripts were used with the 11.0b1 merge of main->beta,
and have not yet been used on a merge of beta->release. They will
likely need further updates after the next merge of beta->release
is performed.
parent 411c7ed4
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -3,3 +3,7 @@
*.bat eol=crlf
*.eml eol=crlf
*.jar binary

app-k9mail/build.gradle.kts merge=merge_gradle
app-thunderbird/build.gradle.kts merge=merge_gradle
app-k9mail/src/main/res/raw/changelog_master.xml merge=ours
+45 −9
Original line number Diff line number Diff line
@@ -139,20 +139,56 @@ Learn more on the [milestones page](https://github.com/thunderbird/thunderbird-a

## Merge Process

Merges are performed with the `git merge` command:

```sh
git checkout beta
git merge main
```

This approach enables various benefits, including:
The merge process enables various benefits, including:

- Carrying forward main branch history to beta, and beta branch history to release.
- No branch history is lost.
- Git tags are retained in git log.
- Git tags are retained in the git log.
- Files/code that is unique per branch can remain that way (e.g. notes files such as changelog_master.xml, version codes).

The following steps are taken when merging main into beta:
1. Lock the main branch with the 'CLOSED TREE (main)' ruleset
2. Send a message to the #tb-mobile-dev:mozilla.org matrix channel to let them know:
- You will be performing the merge from main into beta
- The main branch is locked and cannot be changed during the merge
- You will let them know when the merge is complete and main is re-opened
3. Review merge results and ensure correctness
4. Ensure feature flags are following the rules
5. Push the merge
6. Submit a pull request that increments the version in main
7. Open a new milestone for the new version on github
8. Once the version increment is merged into main, unlock the branch
9. Send a message to the #tb-mobile-dev:mozilla.org channel to notify of merge completion and that main is re-opened

The following steps are taken when merging beta into release:
1. Send a message to the #tb-mobile-dev:mozilla.org matrix channel to let them know:
- You will be performing the merge from beta into release
- You will let them know when the merge is complete
2. Review merge results and ensure correctness
3. Ensure feature flags are following the rules
4. Push the merge
5. Close the milestone for the version that was previously in release
6. Send a message to the #tb-mobile-dev:mozilla.org channel to notify of merge completion

Merges are performed with the `do_merge.sh` script.

The following will merge main into beta:
`scripts/ci/merges/do_merge.sh beta`

And the following will merge beta into release:
`scripts/ci/merges/do_merge.sh release`

Be sure to review merge results and ensure correctness before pushing to the repository.

Files of particular importance are:

- app-k9mail/build.gradle.kts
- app-thunderbird/build.gradle.kts
- app-k9mail/src/main/res/raw/changelog_master.xml

These build.gradle.kts files must be handled as described in "Merge Days" section above. This is part of the do_merge.sh automation.
The app-k9mail/src/main/res/raw/changelog_master.xml should not include any beta notes in the release branch.

## Branch Uplifts

If the urgency of a fix requires it to be included in the Beta or Release channel before the next merge, the uplift process is followed. If possible, uplifts should be avoided and patches should “ride the train” instead, following the merge day cycle.
+79 −0
Original line number Diff line number Diff line
#!/bin/bash

# This script is used to perform merges of main->beta and beta->release.
# Be sure to review merge results and ensure correctness before pushing
# to the repository.
# To merge into beta: do_merge.sh beta
# To merge into release: do_merge.sh release

if [ "$#" -lt 1 ]; then
  echo "Usage: $0 <into-branch>"
  exit 1
fi

into_branch=$1
from_branch="main"
if [ "${into_branch}" = "release" ]; then
  from_branch="beta"
fi

echo "Before merging ${from_branch} into ${into_branch} please confirm that you have:"
if [ "${into_branch}" = "beta" ]; then
  echo "1) Locked the main branch with the 'CLOSED TREE (main)' ruleset"
  echo "2) Sent a message to the #tb-mobile-dev:mozilla.org matrix channel to let them know:"
  echo "   - You will be performing the merge from main into beta"
  echo "   - The main branch is locked and cannot be changed during the merge"
  echo "   - You will let them know when the merge is complete and main is re-opened"
else
  echo "1) Sent a message to the #tb-mobile-dev:mozilla.org matrix channel to let them know"
  echo "   - You will be performing the merge from beta into release"
  echo "   - You will let them know when the merge is complete"
fi
read -p "Continue with merge? [y/N]: " answer
answer=${answer,,}
if [[ "$answer" == "y" || "$answer" == "yes" ]]; then
  echo "Merging ${from_branch} into ${into_branch}"
else
  exit 1
fi
echo

set -ex
git checkout ${into_branch}
git pull
git config merge.ours.driver true
git config merge.merge_gradle.driver "python3 scripts/ci/merges/merge_gradle.py %A %B"
set +e
git merge "origin/${from_branch}"
ret=$?
set +x

if [ "${from_branch}" = "beta" ]; then
  if [ -e "app-thunderbird/src/beta/res/raw/changelog_master.xml" ]; then
    set -ex
    git rm --force app-thunderbird/src/beta/res/raw/changelog_master.xml
    set +ex
  fi
fi

echo
if [ "$ret" -eq 0 ]; then
  echo "Merge succeeded. Next steps:"
  echo "1) Review merge results and ensure correctness"
  echo "2) Ensure feature flags are following the rules"
  echo "3) Push the merge"
  if [ "${into_branch}" = "beta" ]; then
      echo "4) Submit a pull request that increments the version in main"
      echo "5) Open a new milestone for the new version on github"
      echo "6) Once the version increment is merged into main, unlock the branch"
      echo "7) Send a message to the #tb-mobile-dev:mozilla.org channel to notify of merge completion and that main is re-opened"
  else
      echo "4) Close the milestone for the version that was previously in release"
      echo "5) Send a message to the #tb-mobile-dev:mozilla.org channel to notify of merge completion"
  fi
else
  echo "Merge failed. Next steps:"
  echo "1) Fix conflicts"
  echo "2) Add fixed files with: git add"
  echo "3) Continue the merge with: git merge --continue"
fi
+75 −0
Original line number Diff line number Diff line
#!/usr/bin/env python3

import re
import shutil
import subprocess
import sys

ours = sys.argv[1]
theirs = sys.argv[2]


def get_current_branch():
    result = subprocess.run(
        ["git", "rev-parse", "--abbrev-ref", "HEAD"],
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        text=True,
    )
    if result.returncode:
        raise SystemExit(f"Git error: {result.stderr.strip()}")
    return result.stdout.strip()


def find_matching_line(file_path, search_term):
    """Finds and returns the first line containing search term in file."""
    with open(file_path, "r") as file:
        for line in file:
            if re.search(search_term, line):
                return line
    return None


def replace_matching_line(file_path, search_term, new_line):
    """Finds matching line in file and replaces it with new_line."""
    with open(file_path, "r") as file:
        lines = file.readlines()

    with open(file_path, "w") as file:
        for line in lines:
            if re.search(search_term, line):
                file.write(new_line)
            else:
                file.write(line)


branch = get_current_branch()

search_term = "com.fsck.k9"
is_k9 = find_matching_line(ours, search_term)

search_term = "net.thunderbird.android"
is_thunderbird = find_matching_line(ours, search_term)

search_term = r"versionCode = "
found_line = find_matching_line(ours, search_term)

shutil.copyfile(theirs, ours)

if found_line:
    replace_matching_line(ours, search_term, found_line)
else:
    raise SystemExit(f"Search term '{search_term}' not found in ours file.")

if branch == "beta":
    if is_k9:
        search_term = r"versionNameSuffix = \"a1\""
    else:
        search_term = r"versionNameSuffix = \"b[1-9]\""
    found_line = find_matching_line(theirs, search_term)
    if found_line:
        if "b1" not in found_line:
            new_line = "{}{}\n".format(found_line.split("=")[0], '= "b1"')
            replace_matching_line(ours, search_term, new_line)
    else:
        raise SystemExit(f"Search term '{search_term}' not found in theirs file.")