| # Copyright 2023 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. |
| |
| """ |
| Mirror release version from a source repository to a destination repository. |
| This is a workaround for tag mirroring limitations in Copybara with respect to |
| our release infrastructure. |
| """ |
| |
| 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.mirror_version import InputProperties |
| |
| DEPS = [ |
| "fuchsia/git", |
| "fuchsia/git_checkout", |
| "fuchsia/release", |
| "recipe_engine/context", |
| "recipe_engine/properties", |
| "recipe_engine/raw_io", |
| "recipe_engine/step", |
| ] |
| |
| PROPERTIES = InputProperties |
| |
| MIRROR_FOOTER_PREFIX = "GitOrigin-RevId: " |
| |
| |
| def RunSteps(api, props): |
| # Checkout the source repository at HEAD; the build input isn't expected to |
| # correspond to the source repository. |
| src_checkout, _ = api.git_checkout(props.src_remote) |
| |
| # The build input is expected to contain a Gitiles commit corresponding to |
| # the destination repository. |
| dest_checkout, dest_rev = api.git_checkout(props.dest_remote) |
| |
| # A mirrored commit is always expected to have GitOrigin-RevId in its last |
| # line. If not, then it's not a mirrored commit, and we have nothing to do. |
| with api.context(cwd=dest_checkout): |
| msg = api.git.get_commit_message(commit=dest_rev) |
| mirror_footer_line = next( |
| (line for line in msg.split("\n") if line.startswith(MIRROR_FOOTER_PREFIX)), |
| None, |
| ) |
| if not mirror_footer_line: |
| return RawResult( |
| summary_markdown="Not a mirorred commit: no work to do.", |
| status=common_pb2.SUCCESS, |
| ) |
| |
| # Ensure tags are visible. |
| with api.context(cwd=src_checkout): |
| api.git.fetch("origin", tags=True) |
| |
| with api.step.nest("resolve release version"): |
| src_rev = mirror_footer_line.removeprefix(MIRROR_FOOTER_PREFIX) |
| release_version = api.release.ref_to_release_version( |
| src_rev, |
| src_checkout, |
| ) |
| if not release_version: |
| return RawResult( |
| summary_markdown="Mirrored commit is not a release version: no work to do.", |
| status=common_pb2.SUCCESS, |
| ) |
| |
| with api.step.nest("mirror release version"): |
| with api.context(cwd=dest_checkout): |
| api.git.tag(release_version.tag_name) |
| api.git.push( |
| f"refs/tags/{release_version.tag_name}", |
| dryrun=props.dry_run, |
| ) |
| return RawResult( |
| summary_markdown=f"Mirrored {release_version.tag_name}.", |
| status=common_pb2.SUCCESS, |
| ) |
| |
| |
| def GenTests(api): |
| yield ( |
| api.test("basic") |
| + api.properties( |
| src_remote="https://fuchsia.googlesource.com/src", |
| dest_remote="https://fuchsia.googlesource.com/dest", |
| ) |
| + api.step_data( |
| "get commit msg", |
| api.raw_io.stream_output_text(f"[foo] bar\n{MIRROR_FOOTER_PREFIX}sha1"), |
| ) |
| + api.release.ref_to_release_version( |
| "releases/0.20991231.0.1", |
| nesting="resolve release version", |
| ) |
| ) |
| yield ( |
| api.test("not_a_mirrored_commit") |
| + api.properties( |
| src_remote="https://fuchsia.googlesource.com/src", |
| dest_remote="https://fuchsia.googlesource.com/dest", |
| ) |
| + api.step_data( |
| "get commit msg", |
| api.raw_io.stream_output_text("[foo] bar"), |
| ) |
| ) |
| yield ( |
| api.test("not_a_release_version") |
| + api.properties( |
| src_remote="https://fuchsia.googlesource.com/src", |
| dest_remote="https://fuchsia.googlesource.com/dest", |
| ) |
| + api.step_data( |
| "get commit msg", |
| api.raw_io.stream_output_text(f"[foo] bar\n{MIRROR_FOOTER_PREFIX}sha1"), |
| ) |
| ) |