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
4 changes: 4 additions & 0 deletions shipitscript/src/shipitscript/data/config_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@
"type": "object",
"required": [
"mark_as_shipped_schema_file",
"mark_as_merged_schema_file",
"taskcluster_scope_prefix",
"shipit_instance"
],
"properties": {
"mark_as_shipped_schema_file": {
"type": "string"
},
"mark_as_merged_schema_file": {
"type": "string"
},
"taskcluster_scope_prefix": {
"type": "string"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"title": "Taskcluster shipit mark-as-merged task schema",
"type": "object",
"properties": {
"dependencies": {
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": {
"type": "string"
}
},
"scopes": {
"type": "array",
"minItems": 2,
"uniqueItems": true,
"items": {
"type": "string"
}
},
"payload": {
"type": "object",
"properties": {
"automation_id": {
"type": "integer"
}
},
"required": ["automation_id"],
"additionalProperties": false
}
},
"required": ["dependencies", "scopes", "payload"]
}
10 changes: 10 additions & 0 deletions shipitscript/src/shipitscript/script.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ def mark_as_shipped_action(context):
ship_actions.mark_as_shipped_v2(context.ship_it_instance_config, release_name)


def mark_as_merged_action(context):
"""Action to mark a merge automation as complete"""
automation_id = context.task["payload"]["automation_id"]

log.info("Marking the merge automation as complete ...")
ship_actions.mark_as_merged(context.ship_it_instance_config, automation_id)


def create_new_release_action(context):
"""Determine if there is a shippable release and create it if so in Shipit"""
payload = context.task["payload"]
Expand Down Expand Up @@ -109,6 +117,7 @@ def update_product_channel_version_action(context):
# ACTION_MAP {{{1
ACTION_MAP = {
"mark-as-shipped": mark_as_shipped_action,
"mark-as-merged": mark_as_merged_action,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you consider making a single action called "mark-completed" or something that can handle both? Or is that not really viable due to how releases vs merges are handled in shipit?

"create-new-release": create_new_release_action,
"update-product-channel-version": update_product_channel_version_action,
}
Expand All @@ -123,6 +132,7 @@ def get_default_config():
"work_dir": os.path.join(parent_dir, "work_dir"),
"verbose": False,
"mark_as_shipped_schema_file": os.path.join(data_dir, "mark_as_shipped_task_schema.json"),
"mark_as_merged_schema_file": os.path.join(data_dir, "mark_as_merged_task_schema.json"),
"create_new_release_schema_file": os.path.join(data_dir, "create_new_release_task_schema.json"),
}

Expand Down
7 changes: 7 additions & 0 deletions shipitscript/src/shipitscript/ship_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,13 @@ def mark_as_shipped_v2(shipit_config, release_name):
check_release_has_values_v2(release_api, release_name, headers, status="shipped")


def mark_as_merged(shipit_config, automation_id):
release_api, headers = get_shipit_api_instance(shipit_config)

log.info("Marking merge automation as complete...")
release_api.complete_merge_automation(automation_id, headers=headers)


def get_product_channel_version(shipit_config, product, channel):
release_api, headers = get_shipit_api_instance(shipit_config)
log.info(f"Getting the current version of {product} {channel}...")
Expand Down
9 changes: 9 additions & 0 deletions shipitscript/src/shipitscript/shipitapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,12 @@ def update_product_channel_version(self, product, channel, version, headers=None
except Exception:
log.error(f"Caught error while getting version for {product} {channel}!", exc_info=True)
raise

def complete_merge_automation(self, automation_id, headers={}):
"""Method to map over the PATCH /merge-automation/{automation_id} API in shipit

Parameters:
* automation_id
"""
resp = self._request(api_endpoint=f"/merge-automation/{automation_id}", method="PATCH", data="", headers=headers).content
return resp
1 change: 1 addition & 0 deletions shipitscript/src/shipitscript/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
# SCHEMA_MAP {{{1
SCHEMA_MAP = {
"mark-as-shipped": "mark_as_shipped_schema_file",
"mark-as-merged": "mark_as_merged_schema_file",
"create-new-release": "create_new_release_schema_file",
"update-product-channel-version": "update_product_channel_version_schema_file",
}
Expand Down
5 changes: 4 additions & 1 deletion shipitscript/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
@pytest.fixture
def context():
context = Context()
context.config = {"mark_as_shipped_schema_file": os.path.join(os.path.dirname(shipitscript.__file__), "data", "mark_as_shipped_task_schema.json")}
context.config = {
"mark_as_shipped_schema_file": os.path.join(os.path.dirname(shipitscript.__file__), "data", "mark_as_shipped_task_schema.json"),
"mark_as_merged_schema_file": os.path.join(os.path.dirname(shipitscript.__file__), "data", "mark_as_merged_task_schema.json"),
}
context.config["shipit_instance"] = {
"scope": "project:releng:ship-it:server:dev",
"api_root_v2": "http://some-ship-it.url/v2",
Expand Down
23 changes: 23 additions & 0 deletions shipitscript/tests/test_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,28 @@ async def test_mark_as_shipped(context, monkeypatch, scopes):
)


@pytest.mark.parametrize("scopes", (["project:releng:ship-it:action:mark-as-merged", "project:releng:ship-it:server:dev"],))
@pytest.mark.asyncio
async def test_mark_as_merged(context, monkeypatch, scopes):
context.task["scopes"] = scopes
context.task["payload"] = {"automation_id": 123}

mark_as_merged_mock = MagicMock()
monkeypatch.setattr(ship_actions, "mark_as_merged", mark_as_merged_mock)

await script.async_main(context)
mark_as_merged_mock.assert_called_with(
{
"scope": scopes[-1],
"api_root_v2": "http://some-ship-it.url/v2",
"timeout_in_seconds": 1,
"taskcluster_client_id": "some-id",
"taskcluster_access_token": "some-token",
},
123,
)


@pytest.mark.parametrize(
"task,raises",
(
Expand Down Expand Up @@ -79,6 +101,7 @@ def test_get_default_config():
"work_dir": os.path.join(parent_dir, "work_dir"),
"verbose": False,
"mark_as_shipped_schema_file": os.path.join(data_dir, "mark_as_shipped_task_schema.json"),
"mark_as_merged_schema_file": os.path.join(data_dir, "mark_as_merged_task_schema.json"),
"create_new_release_schema_file": os.path.join(data_dir, "create_new_release_task_schema.json"),
}

Expand Down
20 changes: 20 additions & 0 deletions shipitscript/tests/test_ship_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,23 @@ def test_mark_as_shipped_v2(monkeypatch, timeout, expected_timeout):
release_instance_mock.update_status.assert_called_with(
"Firefox-59.0b1-build1", status="shipped", headers={"X-Forwarded-Proto": "https", "X-Forwarded-Port": "80"}
)


@pytest.mark.parametrize("timeout, expected_timeout", ((1, 1), ("10", 10), (None, 60)))
def test_mark_as_merged(monkeypatch, timeout, expected_timeout):
ReleaseClassMock = MagicMock()
release_instance_mock = MagicMock()
ReleaseClassMock.side_effect = lambda *args, **kwargs: release_instance_mock
monkeypatch.setattr(shipitscript.ship_actions, "Release_V2", ReleaseClassMock)

ship_it_instance_config = {"taskcluster_client_id": "some-id", "taskcluster_access_token": "some-token", "api_root_v2": "http://some.ship-it.tld/api/root"}
if timeout is not None:
ship_it_instance_config["timeout_in_seconds"] = timeout
automation_id = 123

shipitscript.ship_actions.mark_as_merged(ship_it_instance_config, automation_id)

ReleaseClassMock.assert_called_with(
taskcluster_client_id="some-id", taskcluster_access_token="some-token", api_root="http://some.ship-it.tld/api/root", timeout=expected_timeout
)
release_instance_mock.complete_merge_automation.assert_called_with(123, headers={"X-Forwarded-Proto": "https", "X-Forwarded-Port": "80"})
11 changes: 11 additions & 0 deletions shipitscript/tests/test_shipitapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,17 @@ def __init__(self):
# make sure we don't modify the passed headers dictionary in the methods
assert headers == {"X-Test": "yes"}

# test that complete_merge_automation calls the right URL
headers = {"X-Test": "yes"}
ret = release.complete_merge_automation(123, headers=headers)
ret_json = json.loads(ret)
assert ret_json["test"] is True
correct_url = "https://www.apiroot.com/merge-automation/123"
release.session.request.assert_called_with(data="", headers=mock.ANY, method="PATCH", timeout=mock.ANY, verify=mock.ANY, url=correct_url)
api_call_count += 1
assert release.session.request.call_count == api_call_count
assert headers == {"X-Test": "yes"}

# test that exception raised if error, and retry api call
release.session.request.return_value.status_code = 400
with pytest.raises(requests.exceptions.HTTPError):
Expand Down