blob: d7c12c6eee7903bb27955f97cf2addfb61a80812 [file] [log] [blame]
# Copyright 2021 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Ensure the MILESTONE file in integration.git is up-to-date."""
from PB.go.chromium.org.luci.buildbucket.proto import common as common_pb2
from PB.recipe_engine.result import RawResult
from PB.recipes.fuchsia.release.milestone_roller import InputProperties
PYTHON_VERSION_COMPATIBILITY = "PY3"
DEPS = [
"fuchsia/auto_roller",
"fuchsia/jiri",
"fuchsia/release",
"fuchsia/status_check",
"recipe_engine/file",
"recipe_engine/path",
"recipe_engine/properties",
"recipe_engine/step",
]
PROPERTIES = InputProperties
COMMIT_MESSAGE = """[roll] Roll MILESTONE from {current} to {target}"""
def RunSteps(api, props):
with api.step.nest("checkout"):
api.jiri.init()
api.jiri.import_manifest(props.manifest, props.remote, name=props.project)
api.jiri.update(run_hooks=False)
project_dir = api.path["start_dir"].join(*props.project.split("/"))
with api.step.nest("resolve target milestone") as presentation:
branches = api.release.get_branches(repo_path=project_dir, remotes=True)
if not branches:
return RawResult(
summary_markdown="%s does not have any release branches" % props.remote,
status=common_pb2.FAILURE,
)
# The target milestone is always 1 ahead of the latest milestone branch.
target_milestone = 1 + (
max(api.release.get_milestone_from_branch(b) for b in branches)
)
current_milestone = api.release.get_major_number(repo_path=project_dir)
if current_milestone == target_milestone:
api.step.empty("nothing to roll", step_text="milestone up-to-date")
return api.auto_roller.nothing_to_roll()
# If the target milestone isn't equal to or exactly 1 greater than the
# current milestone, either the MILESTONE file and/or the latest
# milestone branch are invalid. Raise an exception and do not roll.
if current_milestone + 1 != target_milestone:
return RawResult(
summary_markdown="invalid milestone numbers: target milestone "
"%d is not an increment of current milestone %d"
% (target_milestone, current_milestone),
status=common_pb2.INFRA_FAILURE,
)
api.release.write_major_number(target_milestone, repo_path=project_dir)
if props.milestone_branches_path:
configured_branches = api.file.read_json(
"read milestone branch config",
project_dir.join(props.milestone_branches_path),
test_data=["f1"],
)
# If the milestone branch config file doesn't already contain the
# current milestone branch, append it to the file.
current_milestone_branch = "f%d" % current_milestone
if current_milestone_branch not in configured_branches:
api.file.write_json(
"write milestone branch config",
project_dir.join(props.milestone_branches_path),
configured_branches + ["f%d" % current_milestone],
)
api.step(
"generate configs",
[project_dir.join(props.config_generator_path)],
)
change = api.auto_roller.attempt_roll(
props.roll_options,
repo_dir=project_dir,
commit_message=COMMIT_MESSAGE.format(
current=current_milestone, target=target_milestone
),
)
return api.auto_roller.raw_result(change)
def GenTests(api):
default_props = api.properties(
project="integration",
manifest="minimal",
remote="https://fuchsia.googlesource.com/integration",
milestone_branches_path="config/milestone_branches.json",
config_generator_path="config/generator.sh",
roll_options=api.auto_roller.Options(
remote="https://fuchsia.googlesource.com/integration",
),
)
yield api.status_check.test("no_branches", status="failure") + default_props
yield api.status_check.test("roll") + api.release.get_branches(
["releases/foo", "releases/f1", "releases/f2"],
nesting="resolve target milestone",
) + api.release.get_major_number(
2, nesting="resolve target milestone"
) + api.auto_roller.success() + default_props
yield api.status_check.test("nothing_to_roll") + api.release.get_branches(
["releases/foo", "releases/f1"],
nesting="resolve target milestone",
) + api.release.get_major_number(
2, nesting="resolve target milestone"
) + default_props
yield api.status_check.test(
"invalid_milestone_numbers", status="infra_failure"
) + api.release.get_branches(
["releases/foo", "releases/f1"],
nesting="resolve target milestone",
) + api.release.get_major_number(
5, nesting="resolve target milestone"
) + default_props