blob: e0c224006dad943119f3a36cb52723331fee5a0f [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 platform version in fuchsia.git is up-to-date.
The platform version should always be one ahead of the latest milestone branch's
milestone number.
"""
import json
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.platform_version_roller import InputProperties
DEPS = [
"fuchsia/auto_roller",
"fuchsia/build",
"fuchsia/checkout",
"fuchsia/git",
"fuchsia/git_checkout",
"fuchsia/gitiles",
"fuchsia/release",
"fuchsia/sso",
"fuchsia/status_check",
"recipe_engine/context",
"recipe_engine/properties",
"recipe_engine/step",
]
PROPERTIES = InputProperties
COMMIT_MESSAGE = """[roll] Update platform version from {current} to {target}"""
def RunSteps(api, props):
# This should be a minimal checkout only so that we can read the state of
# the integration repository's branches.
with api.step.nest("checkout integration"):
integration_dir, _ = api.git_checkout(api.sso.sso_to_https(props.remote))
with api.step.nest("resolve target platform version"), api.context(
cwd=integration_dir
):
api.git.fetch(all_remotes=True)
branches = api.release.get_branches(repo_path=integration_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 API level is always 1 ahead of the latest milestone
# branch's milestone number.
target_platform_version = 1 + (
max(api.release.get_milestone_from_branch(b) for b in branches)
)
with api.step.nest("resolve current platform version"):
# Use the Gitiles API to resolve the platform version, as this is much
# faster than doing a full checkout. A full checkout will be performed
# later if we realize that an update is needed.
file_content = api.gitiles.fetch(
"fuchsia.googlesource.com",
"fuchsia",
"build/config/fuchsia/platform_version.json",
).decode()
current_platform_version = json.loads(file_content)["current_fuchsia_api_level"]
if current_platform_version == target_platform_version:
api.step.empty("nothing to roll", step_text="platform version up-to-date")
return api.auto_roller.nothing_to_roll()
# If the target platform version isn't equal to or exactly 1 greater
# than the current platform version, either the current platform version
# and/or the latest milestone branch are invalid. Raise an exception and
# do not roll.
if current_platform_version + 1 != target_platform_version:
return RawResult(
summary_markdown="invalid platform versions: target platform "
"version %d is not an increment of the current platform "
"version %d" % (target_platform_version, current_platform_version),
status=common_pb2.INFRA_FAILURE,
)
# At this point we've determined that we need to attempt a roll, so perform
# a full checkout.
checkout = api.checkout.fuchsia_with_options(
manifest=props.manifest,
remote=props.remote,
)
# Build Fuchsia to generate the golden files for API level N.
build_results = api.build.with_options(
checkout=checkout, fint_params_path=props.fint_params_path
)
# Run update_platform_version.py which bumps the platform version and updates the golden
# files used for compatibility testing
# TODO Drop the explict call to update_platform_version.py once single GN target is implemented.
with api.context(cwd=checkout.root_dir):
api.step(
"update platform version",
[
build_results.gn_results.tool("python3"),
checkout.root_dir.join(
"scripts",
"versioning",
"update_platform_version.py",
),
"--fuchsia-api-level",
target_platform_version,
],
)
change = api.auto_roller.attempt_roll(
props.roll_options,
repo_dir=checkout.root_dir,
commit_message=COMMIT_MESSAGE.format(
current=current_platform_version, target=target_platform_version
),
)
return api.auto_roller.raw_result(change)
def GenTests(api):
default_props = api.properties(
project="integration",
manifest="flower",
remote="https://fuchsia.googlesource.com/integration",
fint_params_path="fint_params/platform-version-roller.textproto",
roll_options=api.auto_roller.Options(
remote="https://fuchsia.googlesource.com/fuchsia",
),
)
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 platform version",
) + api.auto_roller.success() + api.gitiles.fetch(
"resolve current platform version.fetch",
'{"current_fuchsia_api_level": 2}',
) + default_props
yield api.status_check.test("nothing_to_roll") + api.release.get_branches(
["releases/foo", "releases/f1"],
nesting="resolve target platform version",
) + api.gitiles.fetch(
"resolve current platform version.fetch", '{"current_fuchsia_api_level": 2}'
) + default_props
yield api.status_check.test(
"invalid_platform_version", status="infra_failure"
) + api.release.get_branches(
["releases/foo", "releases/f1"],
nesting="resolve target platform version",
) + api.gitiles.fetch(
"resolve current platform version.fetch",
'{"current_fuchsia_api_level": 5}',
) + default_props