Skip to content

Commit

Permalink
fix(relpro): set 'version' parameter
Browse files Browse the repository at this point in the history
Tasks like `mark-as-shipped` expect a version parameter to exist. This
is supposed to be set by the release-promotion action, but I neglected
to add this.

Typically we just assume that there's a file called `version.txt` at the
root of the repo, but this PR implements a new `version-parser` key in
config.yml. This defaults to a parser that reads `version.txt`, but can
be used to point to a custom function in case we want to support storing
the version in other locations.

This function takes the parameters as input so that it can make
decisions around what version to return. For example, in
`mozilla-vpn-client`, there are two distinct products that can be
shipped (client and addons). This will allow them to determine a version
based on things like the `shipping-phase`.
  • Loading branch information
ahal committed Jan 24, 2024
1 parent cd91a1e commit 727fff6
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 3 deletions.
7 changes: 7 additions & 0 deletions src/mozilla_taskgraph/actions/release_promotion.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from taskgraph.decision import taskgraph_decision
from taskgraph.parameters import Parameters
from taskgraph.taskgraph import TaskGraph
from taskgraph.util.python_path import find_object
from taskgraph.util.taskcluster import get_artifact
from taskgraph.util.taskgraph import (
find_decision_task,
Expand Down Expand Up @@ -126,6 +127,12 @@ def release_promotion_action(parameters, graph_config, input, task_group_id, tas
parameters["shipping_phase"] = input["release_promotion_flavor"]
parameters["tasks_for"] = "action"

version_parser_objpath = "mozilla_taskgraph.version:default_parser"
if "version-parser" in graph_config:
version_parser_objpath = graph_config["version-parser"]
version_func = find_object(version_parser_objpath)
parameters["version"] = version_func(parameters)

# make parameters read-only
parameters = Parameters(**parameters)

Expand Down
14 changes: 14 additions & 0 deletions src/mozilla_taskgraph/config.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from textwrap import dedent

from taskgraph import config as tg
from voluptuous import Optional

Expand All @@ -8,5 +10,17 @@
Optional("release-format"): str,
Optional("scope-prefix"): str,
},
Optional(
"version-parser",
description=dedent(
"""
Python path of the form ``<module>:<obj>`` pointing to a
function that takes a set of parameters as input and returns
the version string to use for release tasks.
Defaults to ``mozilla_taskgraph.version:default_parser``.
""".lstrip()
),
): str,
}
)
12 changes: 12 additions & 0 deletions src/mozilla_taskgraph/version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import os

from taskgraph.util.vcs import get_repository

here = os.path.abspath(os.path.dirname(__file__))


def default_parser(params):
repo_root = get_repository(here).path

with open(os.path.join(repo_root, "version.txt")) as f:
return f.read().strip()
40 changes: 40 additions & 0 deletions test/actions/test_release_promotion.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import sys
from itertools import count

import pytest
Expand All @@ -14,6 +15,12 @@ def enable():
enable_action("release-promotion")


@pytest.fixture(scope="session", autouse=True)
def mock_version(session_mocker):
m = session_mocker.patch("mozilla_taskgraph.version.default_parser")
m.return_value = "1.0.0"


@pytest.fixture
def setup(responses, parameters):
tc_url = liburl.test_root_url()
Expand Down Expand Up @@ -85,6 +92,7 @@ def test_release_promotion(parameters, setup, run_action, datadir):
"shipping_phase": "promote",
"target_tasks_method": "target_promote",
"tasks_for": "action",
"version": "1.0.0",
}
)

Expand All @@ -93,6 +101,36 @@ def test_release_promotion(parameters, setup, run_action, datadir):
assert_call(datadir, mock, expected_params)


def test_release_promotion_custom_version_parser(
parameters, setup, run_action, datadir, make_graph_config
):
setup()
expected_params = parameters.copy()
expected_params.update(
{
"build_number": 2,
"do_not_optimize": [],
"existing_tasks": {"a": 0, "b": 1},
"optimize_target_tasks": True,
"shipping_phase": "promote",
"target_tasks_method": "target_promote",
"tasks_for": "action",
"version": "99",
}
)

graph_config = make_graph_config(
extra_config={"version-parser": "testver:fake_version"}
)
input = {"build_number": "2", "release_promotion_flavor": "promote"}
try:
sys.path.insert(0, str(datadir))
mock = run_action("release-promotion", parameters, input, graph_config)
finally:
sys.path.pop(0)
assert_call(datadir, mock, expected_params)


def test_release_promotion_combine_previous_graphs(
parameters, setup, run_action, datadir
):
Expand Down Expand Up @@ -126,6 +164,7 @@ def test_release_promotion_combine_previous_graphs(
"shipping_phase": "ship",
"target_tasks_method": "target_ship",
"tasks_for": "action",
"version": "1.0.0",
}
)

Expand Down Expand Up @@ -157,6 +196,7 @@ def test_release_promotion_rebuild_kinds(parameters, setup, run_action, datadir)
"shipping_phase": "promote",
"target_tasks_method": "target_promote",
"tasks_for": "action",
"version": "1.0.0",
}
)

Expand Down
21 changes: 18 additions & 3 deletions test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ def datadir():
return here / "data"


@pytest.fixture(scope="session")
def repo_root():
return here.parent


@pytest.fixture(scope="session")
def make_graph_config(datadir):
def inner(root_dir=None, extra_config=None):
Expand Down Expand Up @@ -86,7 +91,7 @@ def parameters():
"target_tasks_method": "test_method",
"tasks_for": "hg-push",
"try_mode": None,
"version": "1.0.0",
"version": "",
}
)

Expand Down Expand Up @@ -133,20 +138,30 @@ def run_action(mocker, monkeypatch, graph_config):
# cause failures in other tests.
monkeypatch.setattr(create, "testing", True)
monkeypatch.setattr(tc_util, "testing", True)
root_dir = graph_config.root_dir

def inner(name, parameters, input):
def inner(name, parameters, input, graph_config=None):
m = mocker.patch.object(release_promotion, "taskgraph_decision")
m.return_value = lambda *args, **kwargs: (args, kwargs)

gc_mock = None
if graph_config:
gc_mock = mocker.patch("taskgraph.actions.registry.load_graph_config")
gc_mock.return_value = graph_config

trigger_action_callback(
task_group_id="group-id",
task_id=None,
input=input,
callback=name,
parameters=parameters,
root=graph_config.root_dir,
root=root_dir,
test=True,
)

if gc_mock:
gc_mock.reset()

return m

return inner
Expand Down
2 changes: 2 additions & 0 deletions test/data/testver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
def fake_version(params):
return "99"
11 changes: 11 additions & 0 deletions test/test_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from unittest.mock import mock_open, patch

from mozilla_taskgraph.version import default_parser


def test_default_parser(repo_root):
version = "1.0.0"

with patch("mozilla_taskgraph.version.open", mock_open(read_data=version)) as m:
assert default_parser({}) == version
m.assert_called_with(str(repo_root / "version.txt"))

0 comments on commit 727fff6

Please sign in to comment.