blob: 465603a8060d12bcccc2118e4534d2625f21ef62 [file] [log] [blame]
Andrew McRae0809eb52020-06-18 00:13:36 +10001#!/bin/bash
2# Copyright 2020 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5#
Andrew McRae0809eb52020-06-18 00:13:36 +10006# Script to update base firmware in a program's config, and then
7# regenerate the configs of projects that are part of the program.
8# Also updates the firmware manifest, and uploads all of the changes
9# for review.
10#
11# Usage:
Andrew McRae7c9655c2020-06-22 15:09:54 +100012# ./update_program_fw --board=program --release=NNNNN [ --reviewer=reviewer ]
13# [ --project=proj... ]
Andrew McRae0809eb52020-06-18 00:13:36 +100014# E.g:
Andrew McRae7c9655c2020-06-22 15:09:54 +100015# ./update_program_fw --board=puff --release=13291 --reviewer=amcrae@google.com
Andrew McRae0809eb52020-06-18 00:13:36 +100016#
Andrew McRae7c9655c2020-06-22 15:09:54 +100017CONTRIB_DIR=$(dirname "$(readlink -f "$0")")
18. "${CONTRIB_DIR}/common.sh" || exit 1
19
20FLAGS_HELP="
21Command to update the firmware version for a board.
22
23Updates the master_version firmware configuration for a board's
24master configuration (program.star) and for selected projects
25that include the master configuration.
26
27If no projects are specified, all projects for that board are selected.
Andrew McRaef96cd602020-06-23 23:06:19 +100028An optional skip list can be specified to skip selected boards.
Andrew McRae7c9655c2020-06-22 15:09:54 +100029
30The configurations for the selected projects are regenerated,
31and the firmware manifest are updated for the projects.
32
33The necessary CLs for these changes are created and uploaded for review.
34An optional reviewer can be specified to send all the CLs to.
35"
36# Flags
37DEFINE_string board "${DEFAULT_BOARD}" "Which board (program) the firmware is for" b
38DEFINE_integer release 0 "The firmware release to update to" r
39DEFINE_string project "${DEFAULT_PROJECT}" "Which projects this release is for (defaults to all)" p
Andrew McRae3b94aaf2020-06-25 15:28:18 +100040DEFINE_string bug "none" "The bug to reference in the CL e.g b:12345"
Andrew McRaef96cd602020-06-23 23:06:19 +100041DEFINE_string skip "${DEFAULT_SKIP}" "Skip these projects" s
Andrew McRae7c9655c2020-06-22 15:09:54 +100042DEFINE_string reviewer "${DEFAULT_REVIEWER}" "The reviewer to send the CLs to (optional)"
43
44# Parse command line
45FLAGS "$@" || exit 1
46eval set -- "${FLAGS_ARGV}"
47set -e
48
49# Script must be run inside the chroot.
50assert_inside_chroot
Andrew McRae0809eb52020-06-18 00:13:36 +100051#
52# Variables
53#
Andrew McRae7c9655c2020-06-22 15:09:54 +100054PATH="${PATH}:${GCLIENT_ROOT}/src/config/bin"
Andrew McRae0809eb52020-06-18 00:13:36 +100055DIGITS="[1-9][0-9][0-9][0-9][0-9]"
Andrew McRae0809eb52020-06-18 00:13:36 +100056BRANCH=""
Andrew McRae0809eb52020-06-18 00:13:36 +100057PROGRAM_CL=""
58PROGRAM="program.star"
Andrew McRae3b94aaf2020-06-25 15:28:18 +100059BASENAME=$(basename "$0")
60COMMAND="${BASENAME} $@"
Andrew McRae0809eb52020-06-18 00:13:36 +100061#
62# Common functions
63#
64cleanup() {
Andrew McRae7c9655c2020-06-22 15:09:54 +100065 if [[ -d "${TEMPDIR}" ]]; then
66 rm -rf "${TEMPDIR}"
Andrew McRae0809eb52020-06-18 00:13:36 +100067 fi
Andrew McRae0809eb52020-06-18 00:13:36 +100068}
69#
70# Abort the update, and clean up branches and CLs
71#
72abort() {
Andrew McRae0809eb52020-06-18 00:13:36 +100073 CLS=$(gerrit -i --raw search "owner:me status:open hashtag:${BRANCH}")
74 if [[ -n "${CLS}" ]]; then
75 echo "Abandoning uploaded CLs"
Andrew McRaef96cd602020-06-23 23:06:19 +100076 for cl in ${CLS}; do
77 gerrit -i abandon "${cl}"
78 done
Andrew McRae0809eb52020-06-18 00:13:36 +100079 fi
Andrew McRae7c9655c2020-06-22 15:09:54 +100080 "cros_workon-${FLAGS_board}" stop "chromeos-base/chromeos-firmware-${FLAGS_board}"
81 "cros_workon-${FLAGS_board}" stop "chromeos-base/chromeos-config-bsp-${FLAGS_board}-private"
Andrew McRae0809eb52020-06-18 00:13:36 +100082 repo abandon "${BRANCH}"
Andrew McRae7c9655c2020-06-22 15:09:54 +100083 die "$*"
Andrew McRae0809eb52020-06-18 00:13:36 +100084}
85#
86# Extract a CL number from the file containing
87# the output of repo upload
88#
89getcl() {
90 CL=$(grep -o "https://chrome-internal-review.googlesource.com/c/chromeos/$1/+/[0-9][0-9]*" "$2")
91 if [[ -z "${CL}" ]]; then
92 cat "$2"
93 abort CL number not found in repo upload output
94 fi
95 echo "${CL}" | grep -o "[0-9][0-9]*"
96}
97#
98# If not on this branch, start a branch
99#
100branch() {
101 if ! (git branch --show-current | grep -q "${BRANCH}"); then
102 repo start "${BRANCH}"
103 else
104 echo "${BRANCH} already exists, skipping repo start"
105 fi
106}
107#
108# Return true if repo has changes.
109changed() {
110 [[ -n $(git status -s) ]]
111}
112#
113# Add a Cq-Depend line to a commit.
Andrew McRae0809eb52020-06-18 00:13:36 +1000114#
115amend() {
Andrew McRaef96cd602020-06-23 23:06:19 +1000116 git log -1 --pretty=%B > "${TEMPDIR}/amend-msg"
117 sed -i "/^Change-Id/ i ${1}" "${TEMPDIR}/amend-msg"
118 git commit -q --amend -F "${TEMPDIR}/amend-msg"
119}
120#
121# Return true if $1 is in list $2
122#
123in_list() {
124 for S in ${2}; do
125 if [[ "$1" == "${S}" ]]; then
126 return 0
127 fi
128 done
129 return 1
Andrew McRae0809eb52020-06-18 00:13:36 +1000130}
131#
132# Validate arguments
133#
Andrew McRae7c9655c2020-06-22 15:09:54 +1000134if [[ -z "${FLAGS_board}" ]]; then
135 die "-b or --board required."
136fi
137if [[ -z "${FLAGS_release}" ]]; then
138 die "-r or --release required."
Andrew McRae0809eb52020-06-18 00:13:36 +1000139fi
140#
141# Program must exist as a directory
142#
Andrew McRae7c9655c2020-06-22 15:09:54 +1000143PROGDIR="${GCLIENT_ROOT}/src/program/${FLAGS_board}"
Andrew McRae0809eb52020-06-18 00:13:36 +1000144if [[ ! -d "${PROGDIR}" ]]; then
Andrew McRae7c9655c2020-06-22 15:09:54 +1000145 die "${FLAGS_board} is not a valid program (${PROGDIR} missing)"
Andrew McRae0809eb52020-06-18 00:13:36 +1000146fi
147# Release must be a 5 digit number
Andrew McRae7c9655c2020-06-22 15:09:54 +1000148if [[ ! "${FLAGS_release}" =~ ^${DIGITS}$ ]]; then
Andrew McRaef96cd602020-06-23 23:06:19 +1000149 die "release must be a 5 digit number"
Andrew McRae0809eb52020-06-18 00:13:36 +1000150fi
Andrew McRaef96cd602020-06-23 23:06:19 +1000151# Use a common git branch name.
152BRANCH="update_${FLAGS_board}_fw_${FLAGS_release}"
Andrew McRae0809eb52020-06-18 00:13:36 +1000153#
Andrew McRae7c9655c2020-06-22 15:09:54 +1000154# Build the project list.
Andrew McRaef96cd602020-06-23 23:06:19 +1000155# If no projects are specified, use all in the programs directory.
Andrew McRae0809eb52020-06-18 00:13:36 +1000156#
Andrew McRaef96cd602020-06-23 23:06:19 +1000157if [[ -z "${FLAGS_project}" ]]; then
Andrew McRae7c9655c2020-06-22 15:09:54 +1000158 BDIR="${GCLIENT_ROOT}/src/project/${FLAGS_board}"
Andrew McRaef96cd602020-06-23 23:06:19 +1000159 cd "${BDIR}"
160 mapfile -t PROJLIST < <(ls)
161else
162 IFS=',' read -r -a PROJLIST <<< "${FLAGS_project}"
Andrew McRae0809eb52020-06-18 00:13:36 +1000163fi
Andrew McRae7c9655c2020-06-22 15:09:54 +1000164#
Andrew McRaef96cd602020-06-23 23:06:19 +1000165# Filter out the projects that are to be skipped.
166#
167if [[ -n "${FLAGS_skip}" ]]; then
168 PROJECTS=()
169 IFS=',' read -r -a SKIP_ARRAY <<< "${FLAGS_skip}"
170 SKIPPED="${SKIP_ARRAY[*]}"
171 for P in "${PROJLIST[@]}"; do
172 if ! (in_list "${P}" "${SKIPPED}"); then
173 PROJECTS+=("${P}")
174 fi
175 done
176else
177 PROJECTS=("${PROJLIST[@]}")
178fi
179#
180# Validate project list and file locations.
Andrew McRae7c9655c2020-06-22 15:09:54 +1000181#
182for P in "${PROJECTS[@]}"; do
183 PDIR="${GCLIENT_ROOT}/src/project/${FLAGS_board}/${P}"
184 if [[ ! -d "${PDIR}" ]]; then
185 die "${P} is not a valid project (${PDIR} missing)"
186 fi
187done
Andrew McRaef96cd602020-06-23 23:06:19 +1000188# Validate project overlay location
189OVERLAY="${GCLIENT_ROOT}/src/private-overlays/overlay-${FLAGS_board}-private/chromeos-base/chromeos-firmware-${FLAGS_board}"
190if [[ ! -d "${OVERLAY}" ]]; then
191 die "${OVERLAY}: invalid directory"
192fi
193# Validate ebuild file
194EB9999="chromeos-firmware-${FLAGS_board}-9999.ebuild"
195if [[ ! -f "${OVERLAY}/${EB9999}" ]]; then
196 die "${OVERLAY}/${EB9999}: missing file"
197fi
198# Make sure dev/contrib is accessible
199DEVCONTRIB="${GCLIENT_ROOT}/src/platform/dev/contrib"
200if [[ ! -d "${DEVCONTRIB}" ]]; then
201 die "${DEVCONTRIB}: invalid directory"
202fi
Andrew McRae7c9655c2020-06-22 15:09:54 +1000203#
204# Create a temp directory.
205TEMPDIR=$(mktemp -d -t fw-XXXXXXXXXX)
Andrew McRae7c9655c2020-06-22 15:09:54 +1000206
207trap "exit 1" HUP INT PIPE QUIT TERM
208trap 'cleanup' EXIT
209
Andrew McRae0809eb52020-06-18 00:13:36 +1000210#
211# Update the firmware version in the program config
212# From now on, all errors should invoke 'abort'
Andrew McRae7c9655c2020-06-22 15:09:54 +1000213# so that the branches and CLs are cleaned up on exit.
Andrew McRae0809eb52020-06-18 00:13:36 +1000214#
Andrew McRaef96cd602020-06-23 23:06:19 +1000215cd "${PROGDIR}"
Andrew McRae7c9655c2020-06-22 15:09:54 +1000216echo "Updating ${PROGRAM} for board ${FLAGS_board}"
Andrew McRae0809eb52020-06-18 00:13:36 +1000217branch
Andrew McRae7c9655c2020-06-22 15:09:54 +1000218sed "/^ *major_version = ${DIGITS}$/s/${DIGITS}/${FLAGS_release}/" "${PROGRAM}" > "${TEMPDIR}/new-${PROGRAM}"
Andrew McRae0809eb52020-06-18 00:13:36 +1000219#
220# Verify that only 1-5 characters have changed.
221#
222DIFF=$(cmp -l "${PROGRAM}" "${TEMPDIR}/new-${PROGRAM}" | wc -l)
223if [[ "${DIFF}" -gt 5 ]]; then
224 diff "${PROGRAM}" "new-${TEMPDIR}/${PROGRAM}"
225 abort "${PROGDIR}/${PROGRAM} update error"
Andrew McRae0809eb52020-06-18 00:13:36 +1000226fi
227#
228# If program config has changed, create a CL.
229#
230if [[ "${DIFF}" -ne 0 ]]; then
231 cp "${TEMPDIR}/new-${PROGRAM}" "${PROGRAM}"
232 git add .
Andrew McRaef96cd602020-06-23 23:06:19 +1000233 git commit -q -F - <<EOF
Andrew McRae7c9655c2020-06-22 15:09:54 +1000234${FLAGS_board}: Update firmware to ${FLAGS_release}
Andrew McRae0809eb52020-06-18 00:13:36 +1000235
Andrew McRae3b94aaf2020-06-25 15:28:18 +1000236Autogenerated by: ${COMMAND}
237
238BUG=${FLAGS_bug}
Andrew McRae7c9655c2020-06-22 15:09:54 +1000239TEST=FAFT tests on ${FLAGS_board}
Andrew McRae0809eb52020-06-18 00:13:36 +1000240EOF
Andrew McRaef96cd602020-06-23 23:06:19 +1000241 if ! repo upload -y "--ht=${BRANCH}" --cbr . > "${TEMPDIR}/upload.output" 2>&1 ;then
242 cat "${TEMPDIR}/upload.output"
243 abort "repo upload failed"
244 fi
Andrew McRae7c9655c2020-06-22 15:09:54 +1000245 PROGRAM_CL=$(getcl "program/${FLAGS_board}" "${TEMPDIR}/upload.output")
Andrew McRae0809eb52020-06-18 00:13:36 +1000246fi
247#
248# Now walk through the projects and regenerate the configs.
249# Create and upload a CL and capture the CL number and project directory
250# if the project has changed.
251#
252PROJ_CLS=()
253PROJ_DIRS=()
Andrew McRae7c9655c2020-06-22 15:09:54 +1000254for PROJ in "${PROJECTS[@]}"; do
255 echo "Updating configs for project ${PROJ}"
256 PDIR="${GCLIENT_ROOT}/src/project/${FLAGS_board}/${PROJ}"
Andrew McRaef96cd602020-06-23 23:06:19 +1000257 cd "${PDIR}"
Andrew McRae0809eb52020-06-18 00:13:36 +1000258 branch
259 ./config.star || abort "Generate config failed for ${PROJ}"
260 check_config > "${TEMPDIR}/check_config-${PROJ}.output" || abort "check_config failed for ${PROJ}"
261 #
262 # Check if any files changed.
263 #
264 if changed; then
Andrew McRaef96cd602020-06-23 23:06:19 +1000265 echo "Creating CL for changes to project ${PROJ}"
Andrew McRae0809eb52020-06-18 00:13:36 +1000266 git add .
Andrew McRaef96cd602020-06-23 23:06:19 +1000267 git commit -q -F - <<EOF
Andrew McRae7c9655c2020-06-22 15:09:54 +1000268${PROJ}: Update firmware to ${FLAGS_release}
Andrew McRaef96cd602020-06-23 23:06:19 +1000269
Andrew McRae3b94aaf2020-06-25 15:28:18 +1000270Autogenerated by: ${COMMAND}
271
272BUG=${FLAGS_bug}
Andrew McRae7c9655c2020-06-22 15:09:54 +1000273TEST=FAFT tests on ${FLAGS_board}
Andrew McRae0809eb52020-06-18 00:13:36 +1000274EOF
Andrew McRaef96cd602020-06-23 23:06:19 +1000275 if ! repo upload -y "--ht=${BRANCH}" --cbr . > "${TEMPDIR}/upload.${PROJ}.output" 2>&1 ;then
276 cat "${TEMPDIR}/upload.${PROJ}.output"
277 abort "repo upload failed"
278 fi
Andrew McRae7c9655c2020-06-22 15:09:54 +1000279 P_CL=$(getcl "project/${FLAGS_board}/${PROJ}" "${TEMPDIR}/upload.${PROJ}.output")
Andrew McRae0809eb52020-06-18 00:13:36 +1000280 PROJ_CLS+=("${P_CL}")
281 PROJ_DIRS+=("${PDIR}")
282 fi
283done
284#
285# Create a Cq-Depend line with all the project CLs
286#
287if [[ -n "${PROJ_CLS[*]}" ]];then
288 SEP=" "
289 PROG_CQD="Cq-Depend:"
290 for CL in "${PROJ_CLS[@]}"; do
291 PROG_CQD="${PROG_CQD}${SEP}chrome-internal:${CL}"
292 SEP=", "
293 done
294 #
Andrew McRaef96cd602020-06-23 23:06:19 +1000295 # If a program CL exists, add the Cq-Depend line to it.
Andrew McRae0809eb52020-06-18 00:13:36 +1000296 #
Andrew McRaef96cd602020-06-23 23:06:19 +1000297 if [[ -n "${PROGRAM_CL}" ]]; then
298 cd "${PROGDIR}"
299 amend "${PROG_CQD}"
300 if ! repo upload -y "--ht=${BRANCH}" --cbr . > "${TEMPDIR}/upload.amend.output" 2>&1 ;then
301 cat "${TEMPDIR}/upload.amend.output"
302 abort "repo upload failed"
303 fi
304 fi
Andrew McRae0809eb52020-06-18 00:13:36 +1000305fi
306#
307# All the boxster configs have been uploaded.
308# Now run the update script and update the firmware manifest.
309#
310# Build base coreboot files
311# TODO: Should be selective here.
312#
313echo "Running emerge for coreboot. This may take a while..."
Andrew McRae7c9655c2020-06-22 15:09:54 +1000314if ! ("emerge-${FLAGS_board}" --quiet-build chromeos-ec coreboot depthcharge vboot_reference \
Andrew McRae0809eb52020-06-18 00:13:36 +1000315 libpayload chromeos-bootimage coreboot-private-files \
Andrew McRae7c9655c2020-06-22 15:09:54 +1000316 "coreboot-private-files-${FLAGS_board}"); then
Andrew McRae0809eb52020-06-18 00:13:36 +1000317 abort "emerge for coreboot failed!"
318fi
319echo "emerge of coreboot successful"
Andrew McRae7c9655c2020-06-22 15:09:54 +1000320EB9999="chromeos-firmware-${FLAGS_board}-9999.ebuild"
Andrew McRae0809eb52020-06-18 00:13:36 +1000321#
322# Remove any previous attempts to build the firmware.
323#
Andrew McRae7c9655c2020-06-22 15:09:54 +1000324"cros_workon-${FLAGS_board}" stop "chromeos-base/chromeos-firmware-${FLAGS_board}"
325"cros_workon-${FLAGS_board}" stop "chromeos-base/chromeos-config-bsp-${FLAGS_board}-private"
Andrew McRaef96cd602020-06-23 23:06:19 +1000326cd "${OVERLAY}"
Andrew McRae0809eb52020-06-18 00:13:36 +1000327branch
Andrew McRaef96cd602020-06-23 23:06:19 +1000328cd "${DEVCONTRIB}"
Andrew McRae7c9655c2020-06-22 15:09:54 +1000329if ! (./cros_update_firmware -q "--board=${FLAGS_board}"); then
330 abort "cros_update_firmware failed for ${FLAGS_board}"
Andrew McRae0809eb52020-06-18 00:13:36 +1000331fi
Andrew McRaef96cd602020-06-23 23:06:19 +1000332cd "${OVERLAY}"
Andrew McRae0809eb52020-06-18 00:13:36 +1000333#
334# If files have been updated, then create a CL for the changes.
335#
336OVERLAY_CL=""
337if changed; then
338 #
339 # Bump the version in the ebuild file. Relies on the format
340 # of the version so that the last number is at the end of the line.
341 #
342 CURVERS=$(grep "VERSION=REVBUMP" "${EB9999}" | grep -o "[0-9][0-9]*$")
343 NEXTVERS=$((CURVERS + 1))
Andrew McRaef96cd602020-06-23 23:06:19 +1000344 sed -i "/VERSION=REVBUMP/s/${CURVERS}$/${NEXTVERS}/" "${EB9999}"
Andrew McRae0809eb52020-06-18 00:13:36 +1000345 git add .
Andrew McRaef96cd602020-06-23 23:06:19 +1000346 git commit -q -F - <<EOF
Andrew McRae7c9655c2020-06-22 15:09:54 +1000347${FLAGS_board}: Update firmware to ${FLAGS_release}
Andrew McRae0809eb52020-06-18 00:13:36 +1000348
Andrew McRae3b94aaf2020-06-25 15:28:18 +1000349Autogenerated by: ${COMMAND}
350
351BUG=${FLAGS_bug}
Andrew McRae7c9655c2020-06-22 15:09:54 +1000352TEST=FAFT tests on ${FLAGS_board}
Andrew McRae0809eb52020-06-18 00:13:36 +1000353
Andrew McRaef96cd602020-06-23 23:06:19 +1000354${PROG_CQD}
Andrew McRae0809eb52020-06-18 00:13:36 +1000355EOF
356 #
357 # Upload with no-verify since the file lines are too long.
358 #
Andrew McRaef96cd602020-06-23 23:06:19 +1000359 if ! repo upload "--ht=${BRANCH}" -y --no-verify --cbr . > "${TEMPDIR}/overlay.output" 2>&1 ;then
360 cat "${TEMPDIR}/overlay.output"
361 abort "repo upload failed"
362 fi
Andrew McRae7c9655c2020-06-22 15:09:54 +1000363 OVERLAY_CL=$(getcl "overlays/overlay-${FLAGS_board}-private" "${TEMPDIR}/overlay.output")
Andrew McRae0809eb52020-06-18 00:13:36 +1000364 #
365 # Go back and amend all the project commit messages with a Cq-Depend on
366 # the program and overlay CLs.
367 #
368 CQD="Cq-Depend: chrome-internal:${OVERLAY_CL}"
369 if [[ -n "${PROGRAM_CL}" ]]; then
370 CQD="${CQD}, chrome-internal:${PROGRAM_CL}"
371 fi
372 for DIR in "${PROJ_DIRS[@]}"; do
Andrew McRaef96cd602020-06-23 23:06:19 +1000373 cd "${DIR}"
Andrew McRae0809eb52020-06-18 00:13:36 +1000374 amend "${CQD}"
Andrew McRaef96cd602020-06-23 23:06:19 +1000375 if ! repo upload -y --cbr . > "${TEMPDIR}/cqd.output" 2>&1 ;then
376 cat "${TEMPDIR}/cqd.output"
377 abort "repo upload failed"
378 fi
Andrew McRae0809eb52020-06-18 00:13:36 +1000379 done
380fi
381#
382# Send all of the CLs to the CQ for a dry run.
383#
384ALL_CLS=$(gerrit -i --raw search "owner:me status:open hashtag:${BRANCH}")
385if [[ -z "${ALL_CLS}" ]]; then
Andrew McRae7c9655c2020-06-22 15:09:54 +1000386 echo "No changes required for program ${FLAGS_board}"
Andrew McRae0809eb52020-06-18 00:13:36 +1000387 repo abandon "${BRANCH}"
388 exit 0
389fi
390for cl in ${ALL_CLS}; do
391 gerrit -i label-cq "${cl}" 1
392 gerrit -i label-v "${cl}" 1
393 gerrit -i label-as "${cl}" 1
394done
395#
396# If reviewer is set, then add them to the CLs
397#
Andrew McRae7c9655c2020-06-22 15:09:54 +1000398if [[ -n "${FLAGS_reviewer}" ]]; then
399 echo "Sending CLs ${ALL_CLS} to ${FLAGS_reviewer} for review"
Andrew McRae0809eb52020-06-18 00:13:36 +1000400 for cl in ${ALL_CLS}; do
Andrew McRae7c9655c2020-06-22 15:09:54 +1000401 gerrit -i reviewers "${cl}" "${FLAGS_reviewer}"
Andrew McRae0809eb52020-06-18 00:13:36 +1000402 done
403else
404 echo "Send CLs for review by running:"
405 echo " for cl in ${ALL_CLS}; do gerrit -i reviewers \$cl <reviewer>; done"
406fi
407#
408# Final instructions.
409#
410echo "Run:"
Andrew McRae7c9655c2020-06-22 15:09:54 +1000411echo " /build/${FLAGS_board}/usr/sbin/chromeos-firmwareupdate --manifest"
Andrew McRae0809eb52020-06-18 00:13:36 +1000412echo "to verify firmware update"
413echo "When submitted, cleanup by running:"
414echo "repo abandon ${BRANCH}"