renderdiff: enable update goldens on commit merge (#8771)

This commit is contained in:
Powei Feng
2025-06-02 14:12:26 -07:00
committed by GitHub
parent 1e2311da3d
commit 3da7dabb2a
9 changed files with 237 additions and 52 deletions

View File

@@ -12,11 +12,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from utils import execute
import sys
import re
def get_last_commit():
res, o = execute('git log -1')
commit, author, date, _, title, *desc = o.split('\n')
from utils import execute, ArgParseImpl
RDIFF_UPDATE_GOLDEN_STR = 'RDIFF_BRANCH'
def _parse_commit(commit_str):
commit, author, date, _, title, *desc = commit_str.split('\n')
commit = commit.split(' ')[1]
title = title.strip()
@@ -30,28 +34,27 @@ def get_last_commit():
desc
)
def sanitized_split(line, split_atom='\n'):
return list(
filter(
lambda x: len(x) > 0,
map(
lambda x: x.strip(),
line.split(split_atom)
)
)
)
RDIFF_UPDATE_GOLDEN_STR = 'RDIFF_UPDATE_GOLDEN'
if __name__ == "__main__":
RE_STR = f'{RDIFF_UPDATE_GOLDEN_STR}(?:S)?=[\[]?([a-zA-Z0-9,\s]+)[\]]?'
RE_STR = rf"{RDIFF_UPDATE_GOLDEN_STR}(?:S)?=[\[]?([a-zA-Z0-9,\s\-\/]+)[\]]?"
parser = ArgParseImpl()
parser.add_argument('--file', help='A file containing the commit message')
args, _ = parser.parse_known_args(sys.argv[1:])
if not args.file:
msg = sys.stdin.read()
else:
with open(args.file, 'r') as f:
msg = f.read()
to_update = []
commit, title, description = get_last_commit()
commit, title, description = _parse_commit(msg)
for line in description:
m = re.match(RE_STR, line)
if not m:
continue
print(m.group(1))
exit(0)
to_update += sanitize_split(m.group(1).replace(',', ' '), ' ')
print(','.join(to_update))
# Always default to the main branch
print('main')

View File

@@ -65,7 +65,7 @@ class GoldenManager:
assets_dir = self._assets_dir()
if not os.path.exists(assets_dir):
execute(
f'git clone --depth=1 {self._get_repo_url()}',
f'git clone {self._get_repo_url()}',
cwd=self.working_dir_,
capture_output=False
)
@@ -83,13 +83,26 @@ class GoldenManager:
self._git_exec('rebase')
def _git_exec(self, cmd):
execute(f'git {cmd}', cwd=self._assets_dir(), capture_output=False)
return execute(f'git {cmd}', cwd=self._assets_dir(), capture_output=False)
def merge_to_main(self, branch, push_to_remote=False):
# tag represent a hash in the filament repo that this merge is associated with
def merge_to_main(self, branch, tag, push_to_remote=False):
self.update()
assets_dir = self._assets_dir()
# Update commit message
self._git_exec(f'checkout {branch}')
code, old_commit = execute(f'git log --format=%B -n 1', cwd=assets_dir)
if tag and len(tag) > 0:
old_commit += f'\nFILAMENT={tag}'
COMMIT_FILE = '/tmp/golden_commit.txt'
with open(COMMIT_FILE, 'w') as f:
f.write(old_commit)
self._git_exec(f'commit --amend -F {COMMIT_FILE}')
# Do the actual merge
self._git_exec(f'checkout main')
self._git_exec(f'merge --no-ff {branch}')
self._git_exec(f'merge --no-ff --no-edit {branch}')
if push_to_remote and \
(self.access_token_ or self.access_type_ == ACCESS_TYPE_SSH):
self._git_exec(f'push origin main')
@@ -109,7 +122,7 @@ class GoldenManager:
self._git_exec(f'add {GOLDENS_DIR}')
else:
for f in deletes:
self._git_exec(f'remove {os.path.join(GOLDENS_DIR, f)}')
self._git_exec(f'rm {os.path.join(GOLDENS_DIR, f)}')
for f in updates:
shutil.copy2(
os.path.join(src_dir, f),

View File

@@ -34,7 +34,7 @@ CONFIG_NEW_SRC_DIR = 'goldens_dir'
CONFIG_GOLDENS_BRANCH = 'goldens_branch'
CONFIG_GOLDENS_UPDATES = 'goldens_updates'
CONFIG_GOLDENS_DELETES = 'goldens_deletes'
CONFIG_AUTO_COMMIT = 'auto-commit'
CONFIG_PUSH_TO_REMOTE = 'push-to-remote'
CONFIG_COMMIT_MSG = 'commit_msg'
def _get_current_branch():
@@ -54,12 +54,12 @@ def _do_update(golden_manager, config):
branch = config[CONFIG_GOLDENS_BRANCH]
src_dir = config[CONFIG_NEW_SRC_DIR]
auto_commit = config[CONFIG_AUTO_COMMIT]
push_to_remote = config[CONFIG_PUSH_TO_REMOTE]
commit_msg = config[CONFIG_COMMIT_MSG]
golden_manager.source_from(src_dir, commit_msg, branch,
updates=updates,
deletes=deletes,
push_to_remote=auto_commit)
push_to_remote=push_to_remote)
def _get_deletes_updates(update_dir, golden_dir):
ret_delete = []
@@ -95,7 +95,8 @@ def _interactive_mode(base_golden_dir):
if code != 0:
print('Failed to generate new goldens')
exit(1)
config[CONFIG_NEW_SRC_DIR] = os.path.join(os.getcwd(), './out/renderdiff_tests/')
# Note that this matches RENDER_OUTPUT_DIR in preamble.sh
config[CONFIG_NEW_SRC_DIR] = os.path.join(os.getcwd(), './out/renderdiff/renders')
else:
def validator(src_dir):
if not os.path.exists(src_dir):
@@ -136,16 +137,23 @@ def _interactive_mode(base_golden_dir):
config[CONFIG_GOLDENS_DELETES] = []
config[CONFIG_GOLDENS_UPDATES] = []
config[CONFIG_AUTO_COMMIT] = \
config[CONFIG_PUSH_TO_REMOTE] = \
prompt_helper(f'Commit golden repo changes to remote?') == PROMPT_YES
return config
if __name__ == "__main__":
parser = ArgParseImpl()
parser.add_argument('--branch', help='Branch of the golden repo to write to')
parser.add_argument('--golden-repo-token', help='Access token for the golden repo')
parser.add_argument('--push-to-remote', action="store_true", help='Access token for the golden repo')
# write-to-branch mode
parser.add_argument('--source', help='Directory containing the new goldens')
parser.add_argument('--commit-msg', help='Message for the commit to the golden repo')
parser.add_argument('--golden-repo-token', help='Access token for the golden repo')
# merge-to-main mode (used in postsubmit)
parser.add_argument('--merge-to-main', action="store_true", help='Merge to main the given branch')
parser.add_argument('--filament-tag', help='Tag to append to the commit message on merge')
args, _ = parser.parse_known_args(sys.argv[1:])
config = {}
@@ -155,17 +163,24 @@ if __name__ == "__main__":
access_token=args.golden_repo_token
)
base_golden_dir = golden_manager.directory()
# This is the write-to-branch mode
if args.branch and args.source and args.commit_msg:
assert os.path.exists(args.source), f'{args.source} (--source) directory not found'
deletes, updates = _get_deletes_updates(args.source, base_golden_dir)
config = {
CONFIG_AUTO_COMMIT: True,
CONFIG_PUSH_TO_REMOTE: args.push_to_remote,
CONFIG_GOLDENS_BRANCH: args.branch,
CONFIG_NEW_SRC_DIR: args.source,
CONFIG_GOLDENS_UPDATES: updates,
CONFIG_GOLDENS_DELETES: deletes,
CONFIG_COMMIT_MSG: args.commit_msg,
}
_do_update(golden_manager, config)
# This is the merge-to-main mode
elif args.branch and args.merge_to_main and args.filament_tag:
golden_manager.merge_to_main(branch=args.branch, tag=args.filament_tag, push_to_remote=True)
# Else, we're in interactive mode of write-to-branch (for local execution).
else:
config = _interactive_mode(base_golden_dir)
_do_update(golden_manager, config)
_do_update(golden_manager, config)