-
Notifications
You must be signed in to change notification settings - Fork 221
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create a release promotion action #5501
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
# This Source Code Form is subject to the terms of the Mozilla Public | ||
# License, v. 2.0. If a copy of the MPL was not distributed with this | ||
# file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
|
||
from taskgraph.actions.registry import register_callback_action | ||
from taskgraph.decision import taskgraph_decision | ||
from taskgraph.parameters import Parameters | ||
from taskgraph.taskgraph import TaskGraph | ||
from taskgraph.util.taskcluster import get_artifact | ||
from taskgraph.util.taskgraph import ( | ||
find_decision_task, | ||
find_existing_tasks_from_previous_kinds, | ||
) | ||
|
||
RELEASE_PROMOTION_PROJECTS = ( | ||
"https://github.com/mozilla/application-services", | ||
"https://github.com/mozilla-releng/staging-application-services", | ||
) | ||
|
||
|
||
@register_callback_action( | ||
name="release-promotion", | ||
title="Release Promotion", | ||
symbol="${input.release_promotion_flavor}", | ||
description="Promote or ship the an application-services release.", | ||
generic=False, | ||
order=500, | ||
context=[], | ||
available=lambda p: p["head_repository"] in RELEASE_PROMOTION_PROJECTS, | ||
schema=lambda graph_config: { | ||
"type": "object", | ||
"properties": { | ||
"release_promotion_flavor": { | ||
"type": "string", | ||
"description": "The flavor of release promotion to perform.", | ||
"default": "promote", | ||
"enum": sorted(graph_config["release-promotion"]["flavors"]), | ||
}, | ||
"do_not_optimize": { | ||
"type": "array", | ||
"description": ( | ||
"Optional: a list of labels to avoid optimizing out " | ||
"of the graph (to force a rerun)." | ||
), | ||
"items": { | ||
"type": "string", | ||
}, | ||
}, | ||
"rebuild_kinds": { | ||
"type": "array", | ||
"description": ( | ||
"Optional: an array of kinds to ignore from the previous " | ||
"graph(s)." | ||
), | ||
"items": { | ||
"type": "string", | ||
}, | ||
}, | ||
"previous_graph_ids": { | ||
"type": "array", | ||
"description": ( | ||
"Optional: an array of taskIds of decision or action " | ||
"tasks from the previous graph(s) to use to populate " | ||
"our `previous_graph_kinds`." | ||
), | ||
"items": { | ||
"type": "string", | ||
}, | ||
}, | ||
}, | ||
"required": [ | ||
"release_promotion_flavor", | ||
], | ||
}, | ||
) | ||
def release_promotion_action(parameters, graph_config, input, task_group_id, task_id): | ||
release_promotion_flavor = input["release_promotion_flavor"] | ||
promotion_config = graph_config["release-promotion"]["flavors"][ | ||
release_promotion_flavor | ||
] | ||
|
||
target_tasks_method = promotion_config["target-tasks-method"].format( | ||
project=parameters["project"] | ||
) | ||
rebuild_kinds = input.get("rebuild_kinds") or promotion_config.get( | ||
"rebuild-kinds", [] | ||
) | ||
do_not_optimize = input.get("do_not_optimize") or promotion_config.get( | ||
"do-not-optimize", [] | ||
) | ||
|
||
# make parameters read-write | ||
parameters = dict(parameters) | ||
# Build previous_graph_ids from ``previous_graph_ids`` or ``revision``. | ||
previous_graph_ids = input.get("previous_graph_ids") | ||
if not previous_graph_ids: | ||
previous_graph_ids = [find_decision_task(parameters, graph_config)] | ||
|
||
# Download parameters from the first decision task | ||
parameters = get_artifact(previous_graph_ids[0], "public/parameters.yml") | ||
|
||
# Download and combine full task graphs from each of the | ||
# previous_graph_ids. Sometimes previous relpro action tasks will add | ||
# tasks that didn't exist in the first full_task_graph, so combining them | ||
# is important. The rightmost graph should take precedence in the case of | ||
# conflicts. | ||
combined_full_task_graph = {} | ||
for graph_id in previous_graph_ids: | ||
full_task_graph = get_artifact(graph_id, "public/full-task-graph.json") | ||
combined_full_task_graph.update(full_task_graph) | ||
_, combined_full_task_graph = TaskGraph.from_json(combined_full_task_graph) | ||
parameters["existing_tasks"] = find_existing_tasks_from_previous_kinds( | ||
combined_full_task_graph, previous_graph_ids, rebuild_kinds | ||
) | ||
parameters["do_not_optimize"] = do_not_optimize | ||
parameters["target_tasks_method"] = target_tasks_method | ||
|
||
# When doing staging releases, we still want to re-use tasks from previous | ||
# graphs. | ||
parameters["optimize_target_tasks"] = True | ||
parameters["shipping_phase"] = input["release_promotion_flavor"] | ||
parameters["tasks_for"] = "action" | ||
|
||
# make parameters read-only | ||
parameters = Parameters(**parameters) | ||
|
||
taskgraph_decision({"root": graph_config.root_dir}, parameters=parameters) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ | |
from taskgraph.transforms.base import TransformSequence | ||
|
||
transforms = TransformSequence() | ||
alerts = TransformSequence() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is there an implicit logic for a transform wrappers if the wrapper is called There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess I could have pulled that out into a new transforms file, but I was feeling a bit lazy. Not opposed to doing so if folks want |
||
|
||
@transforms.add | ||
def deps_complete_script(config, tasks): | ||
|
@@ -51,14 +52,19 @@ def convert_dependencies(config, tasks): | |
] | ||
yield task | ||
|
||
@alerts.add | ||
@transforms.add | ||
def add_alert_routes(config, tasks): | ||
""" | ||
Add routes to alert channels when this task fails. | ||
""" | ||
for task in tasks: | ||
task.setdefault('routes', []) | ||
alerts = task.pop("alerts", {}) | ||
if config.params["level"] != "3": | ||
yield task | ||
continue | ||
|
||
task.setdefault('routes', []) | ||
for name, value in alerts.items(): | ||
if name not in ("slack-channel", "email", "pulse", "matrix-room"): | ||
raise KeyError("Unknown alert type: {}".format(name)) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
base_ref: origin/main | ||
base_repository: https://github.com/mozilla-releng/application-services | ||
base_rev: c7b530d61ea8dd4a6dd2d876c4f05a7066dfee5f | ||
branch-build: {} | ||
build_date: 1683647278 | ||
build_number: 1 | ||
do_not_optimize: [] | ||
enable_always_target: true | ||
existing_tasks: | ||
Build summary task: YEuUOoVbRNeGKtOvBJlInQ | ||
build-docker-image-linux: CD--BKGXRAOfpGJviIxY6w | ||
fetch-go-1.14.4: LUCoOzsCTTeWJgSSDszEvg | ||
fetch-resource-monitor: OYpix6V9TIS_CUBv8zEf-Q | ||
lint-detekt: CipDmbrkQH2ccXSGtrStZA | ||
lint-ktlint: ckD6DYUOQleJp7ng7OmfZA | ||
module-build-autofill: X5xdPX1KSE232byWlLK2_Q | ||
module-build-crashtest: VYYDYqGBTzS8d16X3ZB-yQ | ||
module-build-errorsupport: Nf8WFWLhRGK9fKVebJkn4w | ||
module-build-full-megazord: VvBgm9H8TPKAuO11b-alwQ | ||
module-build-fxaclient: NfhMA9mSQQ-wl1h9t-G5cQ | ||
module-build-httpconfig: O5rztTUjT32bBWjMyKpcRA | ||
module-build-logins: OQfCHW4_QTq4ZaYKRz84rA | ||
module-build-native-support: J-h6f8zAQOCnzf0NnCtWbA | ||
module-build-nimbus: KL2gtWC3RMKMbWa2zhMLuw | ||
module-build-places: CjxF6i5XTUuue3N6hur76A | ||
module-build-push: Eb1ryYa0TQas2d6L8shrKg | ||
module-build-rust-log-forwarder: PavZP7KCQUa6eIiH7rcguw | ||
module-build-rustlog: DzsCxDB2RfmjXjSb9sXUcg | ||
module-build-sync15: c-mAP_Z5Tt-jep2NqUVEPQ | ||
module-build-syncmanager: aO_QpDq_RoOcNf56oxDtug | ||
module-build-tabs: d_M2TbtARdeqZdNuLDGMxA | ||
module-build-tooling-nimbus-gradle: OfsUfpFkTRiSJIsPbA0cTA | ||
toolchain-android: Tf8GiXQBSpOIpg0KqSmR8Q | ||
toolchain-desktop-linux: FXqdOHj-Q72AiSvjQiiXYw | ||
toolchain-desktop-macos: VfWl6da-QYaF_Xch88tjdA | ||
toolchain-linux64-resource-monitor: M5U6TKbGSSSfzJoSGNEh5g | ||
toolchain-macosx64-resource-monitor: MawQ-sNYSVieeRo9djQk8Q | ||
toolchain-robolectric: Z9JODYylR0Wjw2GzzaclTg | ||
toolchain-rust: XwjhfYmLSMytDOulmyxM0g | ||
filters: | ||
- target_tasks_method | ||
- branch-build | ||
head_ref: refs/heads/main | ||
head_repository: https://github.com/mozilla-releng/application-services | ||
head_rev: c7b530d61ea8dd4a6dd2d876c4f05a7066dfee5f | ||
head_tag: '' | ||
level: '1' | ||
moz_build_date: '20230509154758' | ||
next_version: null | ||
optimize_strategies: null | ||
optimize_target_tasks: true | ||
owner: user@example.com | ||
project: application-services | ||
pushdate: 0 | ||
pushlog_id: '0' | ||
repository_type: git | ||
shipping_phase: promote | ||
target_tasks_method: promote | ||
tasks_for: action | ||
version: null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this mean that we'll run the
promote
tasks again in theship
phase or will they be cached somehow?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They'll typically be optimized out thanks to
existing_tasks
; this allows e.g. skippingpromote
and runningship
directly without tasks going missing.