diff --git a/.github/workflows/mkosi.yml b/.github/workflows/mkosi.yml index d76a935a40..26d905fb3e 100644 --- a/.github/workflows/mkosi.yml +++ b/.github/workflows/mkosi.yml @@ -105,7 +105,7 @@ jobs: steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 - - uses: systemd/mkosi@31b4e756c1484c302435653da5d3b9bdfae38518 + - uses: systemd/mkosi@2c9954fa51a3a995bbdc02db6ef51f5bd27bc1ba # Freeing up disk space with rm -rf can take multiple minutes. Since we don't need the extra free space # immediately, we remove the files in the background. However, we first move them to a different location diff --git a/tools/fetch-mkosi.py b/tools/fetch-mkosi.py new file mode 100755 index 0000000000..97ce401e8b --- /dev/null +++ b/tools/fetch-mkosi.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: LGPL-2.1-or-later + +""" +Check out mkosi into specified location. +With -u, if changed, commit the latest hash. +""" + +import argparse +import shlex +import subprocess +import re +from pathlib import Path + +URL = 'https://github.com/systemd/mkosi' +BRANCH = 'main' # We only want to ever use commits on upstream 'main' branch +FILENAME = Path('.github/workflows/mkosi.yml') + +def parse_args(): + p = argparse.ArgumentParser( + description=__doc__, + ) + p.add_argument( + 'dir', + type=Path, + ) + p.add_argument( + '--update', '-u', + action='store_true', + default=False, + ) + return p.parse_args() + +def read_config(): + print(f'Reading {FILENAME}…') + matches = [m.group(1) + for line in open(FILENAME) + if (m := re.match('^- uses: systemd/mkosi@([a-z0-9]{40})$', + line.strip()))] + assert len(matches) == 1 + return matches[0] + +def commit_file(args, file: Path, commit: str, changes: str): + cmd = [ + 'git', '-C', args.dir.as_posix(), + 'describe', + '--always', + commit] + print(f"+ {shlex.join(cmd)}") + desc = subprocess.check_output(cmd, text=True).strip() + + message = '\n'.join(( + f'mkosi: update mkosi commit reference to {desc}', + '', + changes)) + + cmd = ['git', 'commit', '-m', message, file.as_posix()] + print(f"+ {shlex.join(cmd)}") + subprocess.check_call(cmd) + +def checkout_mkosi(args): + if args.dir.exists(): + print(f'{args.dir} already exists.') + return + + cmd = [ + 'git', 'clone', URL, + f'--branch={BRANCH}', + args.dir.as_posix(), + ] + print(f"+ {shlex.join(cmd)}") + subprocess.check_call(cmd) + +def update_mkosi(args): + old_commit = read_config() + + cmd = ['git', '-C', args.dir.as_posix(), 'rev-parse', f'refs/remotes/origin/{BRANCH}'] + print(f"+ {shlex.join(cmd)}") + new_commit = subprocess.check_output(cmd, text=True).strip() + + if old_commit == new_commit: + print(f'mkosi: commit {new_commit!s} is still fresh') + return + + cmd = ['git', '-C', args.dir.as_posix(), 'log', '--graph', + '--pretty=oneline', '--no-decorate', '--abbrev-commit', '--abbrev=10', + f'{old_commit}..{new_commit}'] + print(f"+ {shlex.join(cmd)}") + changes = subprocess.check_output(cmd, text=True).strip() + + s = FILENAME.read_text() + assert old_commit in s + print(f'mkosi: {FILENAME}: found old hash, updating…') + new = s.replace(old_commit, new_commit) + assert new != s + FILENAME.write_text(new) + commit_file(args, FILENAME, new_commit, changes) + +if __name__ == '__main__': + args = parse_args() + checkout_mkosi(args) + if args.update: + update_mkosi(args)