Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion landoscript/src/landoscript/actions/version_bump.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import json
import logging
import os.path
import re
import typing
from dataclasses import dataclass

Expand Down Expand Up @@ -30,6 +31,12 @@
"mail/config/version_display.txt",
)

# Standalone browser extensions live at browser/extensions/<name>/manifest.json and are
# version bumped independently of the Gecko/Firefox version. Their commit messages call out
# the extension name so they're distinguishable from a Gecko version bump, which has broader
# implications. See bug 2068060.
_EXTENSION_MANIFEST_RE = re.compile(r"^browser/extensions/(?P<name>[^/]+)/manifest\.json$")


@dataclass(frozen=True)
class VersionBumpInfo:
Expand Down Expand Up @@ -59,6 +66,7 @@ async def run(
are discouraged, and should be avoided if at all possible."""

diffs = []
bumped_files = set()

for version_bump_info in version_bump_infos:
next_version = version_bump_info.next_version
Expand Down Expand Up @@ -102,6 +110,7 @@ async def run(
log.info(f"{file}: successfully bumped! new contents are:")
log_file_contents(modified)

bumped_files.add(file)
diffs.append(diff_contents(orig, modified, file))

if not diffs:
Expand All @@ -121,13 +130,35 @@ def extract_path(diff_text):
log_file_contents(diff)

# version bumps always ignore a closed tree
commitmsg = "Automatic version bump NO BUG a=release CLOSED TREE"
component = extension_component(bumped_files)
commitmsg = f"Automatic {component}version bump NO BUG a=release CLOSED TREE"
if dontbuild:
commitmsg += " DONTBUILD"

return [create_commit_action(commitmsg, diff)]


def extension_component(bumped_files: set[str]) -> str:
"""Return a commit message component naming the standalone extension(s) being bumped.

If every bumped file is a standalone browser extension manifest, return the extension
name(s) so the commit reads e.g. ``Automatic newtab version bump ...`` or, for a mix of
extensions, ``Automatic newtab, webcompat version bump ...``. Otherwise (a Gecko version
bump, or a mix that includes non-extension files) return an empty string for the generic
message.
"""
names = set()
for file in bumped_files:
match = _EXTENSION_MANIFEST_RE.match(file)
if not match:
return ""
names.add(match.group("name"))

if names:
return f"{', '.join(sorted(names))} "
return ""


def get_cur_and_next_version(filename, orig_contents, next_version, munge_next_version):
if filename.endswith("/manifest.json"):
cur = parse_manifest_version(orig_contents)
Expand Down
67 changes: 65 additions & 2 deletions landoscript/tests/test_version_bump.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ async def test_json_manifest_bump(aioresponses, github_installation_responses, c
["version_bump"],
assert_func=lambda req: assert_success(
req,
["Automatic version bump", "NO BUG", "a=release", "CLOSED TREE"],
["Automatic newtab version bump", "NO BUG", "a=release", "CLOSED TREE"],
{MANIFEST_FILE: f' "version": "{initial_version}"'},
{MANIFEST_FILE: f' "version": "{expected_version}"'},
),
Expand Down Expand Up @@ -484,8 +484,71 @@ async def test_webcompat_manifest_bump(aioresponses, github_installation_respons
["version_bump"],
assert_func=lambda req: assert_success(
req,
["Automatic version bump", "NO BUG", "a=release", "CLOSED TREE"],
["Automatic webcompat version bump", "NO BUG", "a=release", "CLOSED TREE"],
{WEBCOMPAT_MANIFEST: ' "version": "151.0.0"'},
{WEBCOMPAT_MANIFEST: ' "version": "151.1.0"'},
),
)


@pytest.mark.asyncio
async def test_multiple_extension_manifest_bump(aioresponses, github_installation_responses, context):
payload = {
"actions": ["version_bump"],
"lando_repo": "repo_name",
"version_bump_info": {
"files": [NEWTAB_MANIFEST, WEBCOMPAT_MANIFEST],
"next_version": "151.1.0",
},
}
setup_github_graphql_responses(
aioresponses,
get_files_payload({NEWTAB_MANIFEST: _manifest("151.0.0"), WEBCOMPAT_MANIFEST: _manifest("151.0.0")}),
)
await run_test(
aioresponses,
github_installation_responses,
context,
payload,
["version_bump"],
assert_func=lambda req: assert_success(
req,
# both extensions are named, sorted, in a single message
["Automatic newtab, webcompat version bump", "NO BUG", "a=release", "CLOSED TREE"],
{NEWTAB_MANIFEST: ' "version": "151.0.0"', WEBCOMPAT_MANIFEST: ' "version": "151.0.0"'},
{NEWTAB_MANIFEST: ' "version": "151.1.0"', WEBCOMPAT_MANIFEST: ' "version": "151.1.0"'},
),
)


@pytest.mark.asyncio
async def test_extension_and_browser_version_bump(aioresponses, github_installation_responses, context):
# A bump that mixes an extension manifest with a browser version file is not a
# standalone extension bump, so it falls back to the generic commit message.
VERSION_FILE = "browser/config/version.txt"
payload = {
"actions": ["version_bump"],
"lando_repo": "repo_name",
"version_bump_info": {
"files": [VERSION_FILE, NEWTAB_MANIFEST],
"next_version": "135.0",
},
}
setup_github_graphql_responses(
aioresponses,
get_files_payload({VERSION_FILE: "134.0", NEWTAB_MANIFEST: _manifest("134.0")}),
)
await run_test(
aioresponses,
github_installation_responses,
context,
payload,
["version_bump"],
assert_func=lambda req: assert_success(
req,
# generic message: the extension name is not called out
["Automatic version bump", "NO BUG", "a=release", "CLOSED TREE"],
{VERSION_FILE: "134.0", NEWTAB_MANIFEST: ' "version": "134.0"'},
{VERSION_FILE: "135.0", NEWTAB_MANIFEST: ' "version": "135.0"'},
),
)