diff --git a/src/Storages/System/StorageSystemContributors.generated.cpp b/src/Storages/System/StorageSystemContributors.generated.cpp index 87bd266af96..85cb51862e8 100644 --- a/src/Storages/System/StorageSystemContributors.generated.cpp +++ b/src/Storages/System/StorageSystemContributors.generated.cpp @@ -1,12 +1,16 @@ -// autogenerated by ./StorageSystemContributors.sh +// autogenerated by tests/ci/version_helper.py const char * auto_contributors[] { "0xflotus", + "13DaGGeR", "20018712", "243f6a88 85a308d3", "243f6a8885a308d313198a2e037", "3ldar-nasyrov", + "7", "821008736@qq.com", "ANDREI STAROVEROV", + "Aaron Katz", + "Adri Fernandez", "Ahmed Dardery", "Aimiyoo", "Akazz", @@ -19,15 +23,15 @@ const char * auto_contributors[] { "Aleksandrov Vladimir", "Aleksei Levushkin", "Aleksei Semiglazov", - "Aleksey Akulovich", "Aleksey", + "Aleksey Akulovich", + "Alex", "Alex Bocharov", "Alex Cao", "Alex Karo", "Alex Krash", "Alex Ryndin", "Alex Zatelepin", - "Alex", "Alexander Avdonkin", "Alexander Bezpiatov", "Alexander Burmak", @@ -55,20 +59,21 @@ const char * auto_contributors[] { "Alexandr Kondratev", "Alexandr Krasheninnikov", "Alexandr Orlov", - "Alexandra Latysheva", "Alexandra", + "Alexandra Latysheva", "Alexandre Snarskii", "Alexei Averchenko", + "Alexey", "Alexey Arno", "Alexey Boykov", "Alexey Dushechkin", "Alexey Elymanov", + "Alexey Gusev", "Alexey Ilyukhov", "Alexey Milovidov", "Alexey Tronov", "Alexey Vasiliev", "Alexey Zatelepin", - "Alexey", "Alexsey Shestakov", "Ali Demirci", "Aliaksandr Pliutau", @@ -84,14 +89,17 @@ const char * auto_contributors[] { "Anastasiya Tsarkova", "Anatoly Pugachev", "Andr0901", + "Andre Marianiello", "Andreas Hunkeler", "AndreevDm", "Andrei Bodrov", "Andrei Ch", "Andrei Chulkov", "Andrei Nekrashevich", + "Andrew", "Andrew Grigorev", "Andrew Onyshchuk", + "Andrey", "Andrey Chulkov", "Andrey Dudin", "Andrey Kadochnikov", @@ -103,12 +111,13 @@ const char * auto_contributors[] { "Andrey Torsunov", "Andrey Urusov", "Andrey Z", - "Andrey", + "Andrii Buriachevskyi", "Andy Liang", "Andy Yang", "Anmol Arora", - "Anna Shakhova", "Anna", + "Anna Shakhova", + "Anselmo D. Adams", "Anthony N. Simon", "Anton Ivashkin", "Anton Kobzev", @@ -121,6 +130,7 @@ const char * auto_contributors[] { "Anton Tikhonov", "Anton Yuzhaninov", "Anton Zhabolenko", + "Antonio Andelic", "Ariel Robaldo", "Arsen Hakobyan", "Arslan G", @@ -136,9 +146,9 @@ const char * auto_contributors[] { "Arthur Petukhovsky", "Arthur Tokarchuk", "Arthur Wong", + "Artur", "Artur Beglaryan", "Artur Filatenkov", - "Artur", "AsiaKorushkina", "Atri Sharma", "Avogar", @@ -149,6 +159,7 @@ const char * auto_contributors[] { "BanyRule", "Baudouin Giard", "BayoNet", + "Ben", "Benjamin Naecker", "Bertrand Junqua", "Bharat Nallan", @@ -156,12 +167,13 @@ const char * auto_contributors[] { "Bill", "BiteTheDDDDt", "BlahGeek", - "Bogdan Voronin", "Bogdan", + "Bogdan Voronin", "BohuTANG", "Bolinov", "BoloniniD", "Boris Granveaud", + "Boris Kuschel", "Bowen Masco", "Braulio Valdivielso", "Brett Hoerner", @@ -173,6 +185,8 @@ const char * auto_contributors[] { "Chen Yufei", "Chienlung Cheung", "Christian", + "Christoph Wurm", + "Chun-Sheng, Li", "Ciprian Hacman", "Clement Rodriguez", "ClickHouse Admin", @@ -181,12 +195,15 @@ const char * auto_contributors[] { "Colum", "Constantin S. Pan", "Constantine Peresypkin", + "CoolT2", "CurtizJ", + "DF5HSE", "DIAOZHAFENG", "Daniel Bershatsky", "Daniel Dao", "Daniel Qin", "Danila Kutenin", + "Dao", "Dao Minh Thuc", "Daria Mozhaeva", "Dario", @@ -198,13 +215,16 @@ const char * auto_contributors[] { "Denis Zhuravlev", "Denny Crane", "Derek Perkins", + "DimaAmega", "Ding Xiang Fei", "Dmitriev Mikhail", "Dmitrii Kovalkov", + "Dmitrii Mokhnatkin", "Dmitrii Raev", + "Dmitriy", "Dmitriy Dorofeev", "Dmitriy Lushnikov", - "Dmitriy", + "Dmitry", "Dmitry Belyavtsev", "Dmitry Bilunov", "Dmitry Galuza", @@ -217,7 +237,6 @@ const char * auto_contributors[] { "Dmitry Rubashkin", "Dmitry S..ky / skype: dvska-at-skype", "Dmitry Ukolov", - "Dmitry", "Doge", "Dongdong Yang", "DoomzD", @@ -232,8 +251,8 @@ const char * auto_contributors[] { "Elizaveta Mironyuk", "Elykov Alexandr", "Emmanuel Donin de Rosière", - "Eric Daniel", "Eric", + "Eric Daniel", "Erixonich", "Ernest Poletaev", "Eugene Klimov", @@ -243,9 +262,9 @@ const char * auto_contributors[] { "Evgeniia Sudarikova", "Evgeniy Gatov", "Evgeniy Udodov", + "Evgeny", "Evgeny Konkov", "Evgeny Markov", - "Evgeny", "Ewout", "FArthur-cmd", "Fabian Stäber", @@ -254,10 +273,12 @@ const char * auto_contributors[] { "Fan()", "FawnD2", "Federico Ceratto", + "Federico Rodriguez", "FeehanG", "FgoDt", "Filatenkov Artur", "Filipe Caixeta", + "Filippov Denis", "Flowyi", "Francisco Barón", "Frank Chen", @@ -269,8 +290,10 @@ const char * auto_contributors[] { "Gagan Arneja", "Gao Qiang", "Gary Dotzler", - "George G", + "Gaurav Kumar", + "Geoff Genz", "George", + "George G", "George3d6", "Georgy Ginzburg", "Gervasio Varela", @@ -278,28 +301,35 @@ const char * auto_contributors[] { "Gleb Novikov", "Gleb-Tretyakov", "Gregory", + "Grigory", "Grigory Buteyko", "Grigory Pervakov", - "Grigory", "Guillaume Tassery", "Guo Wei (William)", "Haavard Kvaalen", "Habibullah Oladepo", "Hamoon", + "Harry-Lee", + "HarryLeeIBM", "Hasitha Kanchana", "Hasnat", + "Heena Bansal", + "HeenaBansal2009", "Hiroaki Nakamura", "HuFuwang", "Hui Wang", + "ILya Limarenko", + "Igor", "Igor Hatarist", "Igor Mineev", + "Igor Nikonov", "Igor Strykhar", - "Igor", - "Igr Mineev", "Igr", + "Igr Mineev", "Ikko Ashimine", "Ildar Musin", "Ildus Kurbangaliev", + "Ilya", "Ilya Breev", "Ilya Golshtein", "Ilya Khomutov", @@ -310,10 +340,11 @@ const char * auto_contributors[] { "Ilya Shipitsin", "Ilya Skrypitsa", "Ilya Yatsishin", - "Ilya", + "IlyaTsoi", "ImgBotApp", - "Islam Israfilov (Islam93)", "Islam Israfilov", + "Islam Israfilov (Islam93)", + "Ivan", "Ivan A. Torgashov", "Ivan Babrou", "Ivan Blinkov", @@ -325,27 +356,29 @@ const char * auto_contributors[] { "Ivan Remen", "Ivan Starkov", "Ivan Zhukov", - "Ivan", "Jack Song", "JackyWoo", "Jacob Hayes", + "Jake Liu", "Jakub Kuklis", "JaosnHsieh", - "Jason Keirstead", "Jason", + "Jason Keirstead", "Javi Santana", "Javi santana bot", + "JaySon-Huang", "Jean Baptiste Favre", "Jeffrey Dang", "Jiading Guo", "Jiang Tao", "Jochen Schalanda", + "John", "John Hummel", "John Skopis", - "John", "Jonatas Freitas", "João Figueiredo", "Julian Zhou", + "Justin Hilliard", "Kang Liu", "Karl Pietrzak", "Keiji Yoshida", @@ -375,7 +408,9 @@ const char * auto_contributors[] { "Ky Li", "LB", "Latysheva Alexandra", + "Lemore", "Leonardo Cecchi", + "Leonid Krylov", "Leopold Schabel", "Lev Borodin", "Lewinma", @@ -391,9 +426,9 @@ const char * auto_contributors[] { "M0r64n", "MagiaGroz", "Maks Skorokhod", + "Maksim", "Maksim Fedotov", "Maksim Kita", - "Maksim", "Malte", "Marat IDRISOV", "Marek Vavrusa", @@ -412,10 +447,11 @@ const char * auto_contributors[] { "Masha", "Matthew Peveler", "Matwey V. Kornilov", + "Max", "Max Akhmedov", "Max Bruce", "Max Vetrov", - "Max", + "MaxTheHuman", "MaxWk", "Maxim Akhmedov", "Maxim Babenko", @@ -430,6 +466,7 @@ const char * auto_contributors[] { "Maxim Ulanovskiy", "MaximAL", "Mc.Spring", + "Meena-Renganathan", "MeiK", "Memo", "Metehan Çetinkaya", @@ -439,18 +476,21 @@ const char * auto_contributors[] { "Michael Monashev", "Michael Razuvaev", "Michael Smitasin", + "Michail Safronov", "Michal Lisowski", "MicrochipQ", "Miguel Fernández", "Mihail Fandyushin", "Mikahil Nacharov", + "Mike", "Mike F", "Mike Kot", - "Mike", + "Mikhail", "Mikhail Andreev", "Mikhail Cheshkov", "Mikhail Fandyushin", "Mikhail Filimonov", + "Mikhail Fursov", "Mikhail Gaidamaka", "Mikhail Korotov", "Mikhail Malafeev", @@ -458,18 +498,19 @@ const char * auto_contributors[] { "Mikhail Salosin", "Mikhail Surin", "Mikhail f. Shiryaev", - "Mikhail", "MikuSugar", "Milad Arabi", "Misko Lee", "Mohamad Fadhil", "Mohammad Hossein Sekhavat", + "Mojtaba Yaghoobzadeh", "Mostafa Dahab", "MovElb", "Mr.General", "Murat Kabilov", "MyroTk", "Mátyás Jani", + "N. Kolotov", "NIKITA MIKHAILOV", "Narek Galstyan", "Natasha Murashkina", @@ -477,15 +518,17 @@ const char * auto_contributors[] { "Neeke Gao", "Neng Liu", "NengLiu", - "Nickita Taranov", "Nickita", + "Nickita Taranov", "Nickolay Yastrebov", "Nico Mandery", "Nico Piderman", "Nicolae Vartolomei", + "Niek", "Nik", "Nikhil Nadig", "Nikhil Raman", + "Nikita", "Nikita Lapkov", "Nikita Mikhailov", "Nikita Mikhalev", @@ -495,13 +538,13 @@ const char * auto_contributors[] { "Nikita Vasilev", "Nikolai Kochetov", "Nikolai Sorokin", + "Nikolay", "Nikolay Degterinsky", "Nikolay Kirsh", "Nikolay Semyachkin", "Nikolay Shcheglov", "Nikolay Vasiliev", "Nikolay Volosatov", - "Nikolay", "Niu Zhaojie", "Odin Hultgren Van Der Horst", "Okada Haruki", @@ -517,11 +560,13 @@ const char * auto_contributors[] { "OnePiece", "Onehr7", "Orivej Desh", + "Orkhan Zeynalli", "Oskar Wojciski", "OuO", "PHO", "Paramtamtam", "Patrick Zippenfenig", + "Pavel", "Pavel Cheremushkin", "Pavel Kartaviy", "Pavel Kartavyy", @@ -531,7 +576,6 @@ const char * auto_contributors[] { "Pavel Medvedev", "Pavel Patrin", "Pavel Yakunin", - "Pavel", "Pavlo Bashynskiy", "Pawel Rog", "Peignon Melvyn", @@ -545,6 +589,7 @@ const char * auto_contributors[] { "Pysaoke", "Quid37", "Rafael David Tinoco", + "Rajkumar", "Ramazan Polat", "Ravengg", "Raúl Marín", @@ -556,8 +601,10 @@ const char * auto_contributors[] { "Ri", "Rich Raposa", "Robert Hodges", + "RogerYK", "Rohit Agarwal", "Romain Neutron", + "Roman", "Roman Bug", "Roman Chyrva", "Roman Lipovsky", @@ -566,13 +613,15 @@ const char * auto_contributors[] { "Roman Peshkurov", "Roman Tsisyk", "Roman Zhukov", - "Roman", - "Ruslan Savchenko", "Ruslan", + "Ruslan Savchenko", "Russ Frank", "Ruzal Ibragimov", + "Ryad ZENINE", "S.M.A. Djawadi", + "Saad Ur Rahman", "Sabyanin Maxim", + "Safronov Michail", "SaltTan", "Sami Kerola", "Samuel Chou", @@ -583,6 +632,7 @@ const char * auto_contributors[] { "Sergei Bocharov", "Sergei Semin", "Sergei Shtykov", + "Sergei Trifonov", "Sergei Tsetlin (rekub)", "Sergey Demurin", "Sergey Elantsev", @@ -614,26 +664,28 @@ const char * auto_contributors[] { "Stas Kelvich", "Stas Pavlovichev", "Stefan Thies", - "Stepan Herold", "Stepan", + "Stepan Herold", "Steve-金勇", "Stig Bakken", "Storozhuk Kostiantyn", "Stupnikov Andrey", "SuperBot", "SuperDJY", - "Sébastien Launay", + "Suzy Wang", "Sébastien", + "Sébastien Launay", + "TABLUM.IO", "TAC", "TCeason", "Tagir Kuskarov", "Tai White", "Taleh Zaliyev", "Tangaev", - "Tatiana Kirillova", "Tatiana", - "Teja Srivastasa", + "Tatiana Kirillova", "Teja", + "Teja Srivastasa", "Tema Novikov", "Tentoshka", "The-Alchemist", @@ -655,10 +707,10 @@ const char * auto_contributors[] { "UnamedRus", "V", "VDimir", + "Vadim", "Vadim Plakhtinskiy", "Vadim Skipin", "Vadim Volodin", - "Vadim", "VadimPE", "Val", "Valera Ryaboshapko", @@ -672,8 +724,8 @@ const char * auto_contributors[] { "Veniamin Gvozdikov", "Veselkov Konstantin", "Viachaslau Boben", - "Victor Tarnavsky", "Victor", + "Victor Tarnavsky", "Viktor Taranenko", "Vitalii S", "Vitaliy Fedorchenko", @@ -681,13 +733,15 @@ const char * auto_contributors[] { "Vitaliy Kozlovskiy", "Vitaliy Lyudvichenko", "Vitaliy Zakaznikov", + "Vitaly", + "Vitaly Artemyev", "Vitaly Baranov", "Vitaly Orlov", "Vitaly Samigullin", "Vitaly Stoyan", - "Vitaly", "Vivien Maisonneuve", "Vlad Arkhipov", + "Vladimir", "Vladimir Bunchuk", "Vladimir C", "Vladimir Ch", @@ -699,7 +753,6 @@ const char * auto_contributors[] { "Vladimir Kopysov", "Vladimir Kozbin", "Vladimir Smirnov", - "Vladimir", "Vladislav Rassokhin", "Vladislav Smirnov", "Vojtech Splichal", @@ -707,6 +760,7 @@ const char * auto_contributors[] { "Vsevolod Orlov", "Vxider", "Vyacheslav Alipov", + "W", "Wang Fenjin", "WangZengrui", "Weiqing Xu", @@ -714,8 +768,10 @@ const char * auto_contributors[] { "Winter Zhang", "Xianda Ke", "Xiang Zhou", + "Xin Wang", "Y Lu", "Yangkuan Liu", + "Yatian Xu", "Yatsishin Ilya", "Yağızcan Değirmenci", "Yegor Andreenko", @@ -724,13 +780,14 @@ const char * auto_contributors[] { "Yingfan Chen", "Yiğit Konur", "Yohann Jardin", + "Youenn Lebras", "Yuntao Wu", "Yuri Dyachenko", "Yurii Vlasenko", + "Yuriy", "Yuriy Baranov", "Yuriy Chernyshov", "Yuriy Korzhenevskiy", - "Yuriy", "Yury Karpovich", "Yury Stankevich", "ZhiYong Wang", @@ -756,6 +813,7 @@ const char * auto_contributors[] { "alex.lvxin", "alexander kozhikhov", "alexey-milovidov", + "alexeypavlenko", "alfredlu", "amesaru", "amoschen", @@ -810,10 +868,12 @@ const char * auto_contributors[] { "cms", "cmsxbc", "cn-ds", + "cnmade", "comunodi", "congbaoyangrou", "coraxster", "d.v.semenov", + "dalei2019", "damozhaeva", "dankondr", "daoready", @@ -849,6 +909,7 @@ const char * auto_contributors[] { "ezhaka", "f1yegor", "fancno", + "fanzhou", "fastio", "favstovol", "feihengye", @@ -863,8 +924,8 @@ const char * auto_contributors[] { "flow", "flynn", "foxxmary", - "frank chen", "frank", + "frank chen", "franklee", "fredchenbj", "freedomDR", @@ -877,8 +938,11 @@ const char * auto_contributors[] { "giordyb", "glockbender", "glushkovds", + "grantovsky", + "gulige", "guoleiyi", "gyuton", + "hanqf-git", "hao.he", "hchen9", "hcz", @@ -890,6 +954,7 @@ const char * auto_contributors[] { "huangzhaowei", "hustnn", "huzhichengdd", + "ianton-ru", "ice1x", "idfer", "igomac", @@ -907,8 +972,8 @@ const char * auto_contributors[] { "jasine", "jasperzhu", "javartisan", - "javi santana", "javi", + "javi santana", "jennyma", "jetgm", "jianmei zhang", @@ -937,6 +1002,8 @@ const char * auto_contributors[] { "levie", "levushkin aleksej", "levysh", + "lgbo", + "lgbo-ustc", "lhuang0928", "lhuang09287750", "liang.huang", @@ -947,6 +1014,7 @@ const char * auto_contributors[] { "listar", "litao91", "liu-bov", + "liuneng1994", "liuyangkuan", "liuyimin", "liyang", @@ -983,11 +1051,15 @@ const char * auto_contributors[] { "mikael", "mikepop7", "millb", + "minhthucdao", + "mlkui", "mnkonkova", "mo-avatar", "morty", "moscas", + "mreddy017", "msaf1980", + "msirm", "muzzlerator", "mwish", "myrrc", @@ -1007,6 +1079,7 @@ const char * auto_contributors[] { "ocadaruma", "ogorbacheva", "olegkv", + "olevino", "olgarev", "orantius", "p0ny", @@ -1014,6 +1087,7 @@ const char * auto_contributors[] { "pawelsz-rb", "pdv-ru", "peshkurov", + "peter279k", "philip.han", "pingyu", "potya", @@ -1040,8 +1114,10 @@ const char * auto_contributors[] { "roverxu", "ruct", "ryzuo", + "s-kat", "santaux", "satanson", + "save-my-heart", "sdk2", "serebrserg", "sev7e0", @@ -1068,8 +1144,10 @@ const char * auto_contributors[] { "taiyang-li", "tao jiang", "tavplubix", + "tekeri", "templarzq", "terrylin", + "tesw yew isal", "tianzhou", "tiger.yan", "tison", @@ -1080,6 +1158,8 @@ const char * auto_contributors[] { "unegare", "unknown", "urgordeadbeef", + "usurai", + "vahid-sohrabloo", "vdimir", "velom", "vesslanjin", @@ -1121,8 +1201,11 @@ const char * auto_contributors[] { "zhangxiao018", "zhangxiao871", "zhen ni", + "zhifeng", "zhongyuankai", + "zhoubintao", "zhukai", + "zkun", "zlx19950903", "zvonand", "zvrr", @@ -1150,6 +1233,7 @@ const char * auto_contributors[] { "曲正鹏", "木木夕120", "未来星___费", + "李扬", "极客青年", "枢木", "董海镔", @@ -1159,5 +1243,6 @@ const char * auto_contributors[] { "靳阳", "黄朝晖", "黄璞", + "박동철", "박현우", nullptr}; diff --git a/src/Storages/System/StorageSystemContributors.sh b/src/Storages/System/StorageSystemContributors.sh index 9b714a94207..a724fdc9d39 100755 --- a/src/Storages/System/StorageSystemContributors.sh +++ b/src/Storages/System/StorageSystemContributors.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash +echo "THIS IS HEAVILY DEPRECATED, USE tests/ci/version_helper.py:update_contributors()" set -x # doesn't actually cd to directory, but return absolute path diff --git a/tests/ci/build_check.py b/tests/ci/build_check.py index e21e7d0138d..4ea97d68ded 100644 --- a/tests/ci/build_check.py +++ b/tests/ci/build_check.py @@ -175,7 +175,7 @@ def get_release_or_pr( # for pushes to master - major version, but not for performance builds # they havily relies on a fixed path for build package and nobody going # to deploy them somewhere, so it's ok. - return ".".join(version.as_tuple()[:2]) + return f"{version.major}.{version.minor}" # PR number for anything else return str(pr_info.number) @@ -218,7 +218,7 @@ def main(): s3_helper = S3Helper("https://s3.amazonaws.com") - version = get_version_from_repo(REPO_COPY) + version = get_version_from_repo() release_or_pr = get_release_or_pr(pr_info, build_config, version) s3_path_prefix = "/".join((release_or_pr, pr_info.sha, build_name)) @@ -255,13 +255,13 @@ def main(): docker_image = get_image_with_version(IMAGES_PATH, image_name) image_version = docker_image.version - logging.info("Got version from repo %s", version.get_version_string()) + logging.info("Got version from repo %s", version.string) version_type = "testing" if "release" in pr_info.labels or "release-lts" in pr_info.labels: version_type = "stable" - update_version_local(REPO_COPY, pr_info.sha, version, version_type) + update_version_local(REPO_COPY, version, version_type) logging.info("Updated local files with version") @@ -290,7 +290,7 @@ def main(): build_config, os.path.join(REPO_COPY, "docker/packager"), build_output_path, - version.get_version_string(), + version.string, image_version, ccache_path, pr_info, diff --git a/tests/ci/git_helper.py b/tests/ci/git_helper.py new file mode 100644 index 00000000000..aebbf96abe2 --- /dev/null +++ b/tests/ci/git_helper.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +import argparse +import os.path as p +import re +import subprocess +from typing import Optional + +TAG_REGEXP = r"^v\d{2}[.][1-9]\d*[.][1-9]\d*[.][1-9]\d*-(testing|prestable|stable|lts)$" +SHA_REGEXP = r"^([0-9]|[a-f]){40}$" + + +# Py 3.8 removeprefix and removesuffix +def removeprefix(string: str, prefix: str): + if string.startswith(prefix): + return string[len(prefix) :] # noqa: ignore E203, false positive + return string + + +def removesuffix(string: str, suffix: str): + if string.endswith(suffix): + return string[: -len(suffix)] + return string + + +def commit(name: str): + r = re.compile(SHA_REGEXP) + if not r.match(name): + raise argparse.ArgumentTypeError( + "commit hash should contain exactly 40 hex characters" + ) + return name + + +class Runner: + """lightweight check_output wrapper with stripping last NEW_LINE""" + + def __init__(self, cwd: str = p.dirname(p.realpath(__file__))): + self.cwd = cwd + + def run(self, cmd: str, cwd: Optional[str] = None) -> str: + if cwd is None: + cwd = self.cwd + return subprocess.check_output( + cmd, shell=True, cwd=cwd, encoding="utf-8" + ).strip() + + +class Git: + """A small wrapper around subprocess to invoke git commands""" + + def __init__(self): + runner = Runner() + rel_root = runner.run("git rev-parse --show-cdup") + self.root = p.realpath(p.join(runner.cwd, rel_root)) + self._tag_pattern = re.compile(TAG_REGEXP) + runner.cwd = self.root + self.run = runner.run + self.new_branch = "" + self.branch = "" + self.sha = "" + self.sha_short = "" + self.description = "" + self.commits_since_tag = 0 + self.update() + + def update(self): + """Is used to refresh all attributes after updates, e.g. checkout or commit""" + self.branch = self.run("git branch --show-current") + self.sha = self.run("git rev-parse HEAD") + self.sha_short = self.sha[:11] + # The following command shows the most recent tag in a graph + # Format should match TAG_REGEXP + self.latest_tag = self.run("git describe --tags --abbrev=0") + # Format should be: {latest_tag}-{commits_since_tag}-g{sha_short} + self.description = self.run("git describe --tags --long") + self.commits_since_tag = int( + self.run(f"git rev-list {self.latest_tag}..HEAD --count") + ) + + def _check_tag(self, value: str): + if value == "": + return + if not self._tag_pattern.match(value): + raise Exception(f"last tag {value} doesn't match the pattern") + + @property + def latest_tag(self) -> str: + return self._latest_tag + + @latest_tag.setter + def latest_tag(self, value: str): + self._check_tag(value) + self._latest_tag = value + + @property + def new_tag(self) -> str: + return self._new_tag + + @new_tag.setter + def new_tag(self, value: str): + self._check_tag(value) + self._new_tag = value + + @property + def tweak(self) -> int: + if not self.latest_tag.endswith("-testing"): + # When we are on the tag, we still need to have tweak=1 to not + # break cmake with versions like 12.13.14.0 + return self.commits_since_tag or 1 + + version = self.latest_tag.split("-", maxsplit=1)[0] + return int(version.split(".")[-1]) + self.commits_since_tag diff --git a/tests/ci/keeper_jepsen_check.py b/tests/ci/keeper_jepsen_check.py index b7acc92b0f3..70d1ced6fe8 100644 --- a/tests/ci/keeper_jepsen_check.py +++ b/tests/ci/keeper_jepsen_check.py @@ -149,8 +149,8 @@ if __name__ == "__main__": build_name = get_build_name_for_check(CHECK_NAME) if pr_info.number == 0: - version = get_version_from_repo(REPO_COPY) - release_or_pr = ".".join(version.as_tuple()[:2]) + version = get_version_from_repo() + release_or_pr = f"{version.major}.{version.minor}" else: # PR number for anything else release_or_pr = str(pr_info.number) diff --git a/tests/ci/push_to_artifactory.py b/tests/ci/push_to_artifactory.py index d2241d10b6c..7747525df02 100755 --- a/tests/ci/push_to_artifactory.py +++ b/tests/ci/push_to_artifactory.py @@ -8,19 +8,7 @@ from typing import Tuple from artifactory import ArtifactorySaaSPath # type: ignore from build_download_helper import dowload_build_with_progress - - -# Py 3.8 removeprefix and removesuffix -def removeprefix(string: str, prefix: str): - if string.startswith(prefix): - return string[len(prefix) :] # noqa: ignore E203, false positive - return string - - -def removesuffix(string: str, suffix: str): - if string.endswith(suffix): - return string[: -len(suffix)] - return string +from git_helper import TAG_REGEXP, commit, removeprefix, removesuffix # Necessary ENV variables @@ -124,7 +112,7 @@ class S3: class Release: def __init__(self, name: str): - r = re.compile(r"^v\d{2}[.]\d+[.]\d+[.]\d+-(testing|prestable|stable|lts)$") + r = re.compile(TAG_REGEXP) # Automatically remove refs/tags/ if full refname passed here name = removeprefix(name, "refs/tags/") if not r.match(name): @@ -212,15 +200,6 @@ class Artifactory: return self.__path_helper("_tgz", package_file) -def commit(name: str): - r = re.compile(r"^([0-9]|[a-f]){40}$") - if not r.match(name): - raise argparse.ArgumentTypeError( - "commit hash should contain exactly 40 hex characters" - ) - return name - - def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter, diff --git a/tests/ci/release.py b/tests/ci/release.py new file mode 100755 index 00000000000..f1ed27f3d8c --- /dev/null +++ b/tests/ci/release.py @@ -0,0 +1,328 @@ +#!/usr/bin/env python + + +from contextlib import contextmanager +from typing import Optional +import argparse +import logging + +from git_helper import commit +from version_helper import ( + FILE_WITH_VERSION_PATH, + ClickHouseVersion, + VersionType, + git, + get_abs_path, + get_version_from_repo, + update_cmake_version, +) + + +class Release: + BIG = ("major", "minor") + SMALL = ("patch",) + + def __init__(self, version: ClickHouseVersion): + self._version = version + self._git = version._git + self._release_commit = "" + + def run(self, cmd: str, cwd: Optional[str] = None) -> str: + logging.info("Running in directory %s, command:\n %s", cwd or "$CWD", cmd) + return self._git.run(cmd, cwd) + + @property + def version(self) -> ClickHouseVersion: + return self._version + + @version.setter + def version(self, version: ClickHouseVersion): + if not isinstance(version, ClickHouseVersion): + raise ValueError(f"version must be ClickHouseVersion, not {type(version)}") + self._version = version + + @property + def release_commit(self) -> str: + return self._release_commit + + @release_commit.setter + def release_commit(self, release_commit: str): + self._release_commit = commit(release_commit) + + def check_no_tags_after(self): + tags_after_commit = self.run(f"git tag --contains={self.release_commit}") + if tags_after_commit: + raise Exception( + f"Commit {self.release_commit} belongs to following tags:\n" + f"{tags_after_commit}\nChoose another commit" + ) + + def check_branch(self, release_type: str): + if release_type in self.BIG: + # Commit to spin up the release must belong to a main branch + output = self.run(f"git branch --contains={self.release_commit} master") + if "master" not in output: + raise Exception( + f"commit {self.release_commit} must belong to 'master' for " + f"{release_type} release" + ) + if release_type in self.SMALL: + branch = f"{self.version.major}.{self.version.minor}" + if self._git.branch != branch: + raise Exception(f"branch must be '{branch}' for {release_type} release") + + def update(self): + self._git.update() + self.version = get_version_from_repo() + + @contextmanager + def _new_branch(self, name: str, start_point: str = ""): + self.run(f"git branch {name} {start_point}") + try: + yield + except BaseException: + logging.warning("Rolling back created branch %s", name) + self.run(f"git branch -D {name}") + raise + + @contextmanager + def _checkout(self, ref: str, with_rollback: bool = False): + orig_ref = self._git.branch or self._git.sha + need_rollback = False + if ref not in (self._git.branch, self._git.sha): + need_rollback = True + self.run(f"git checkout {ref}") + try: + yield + except BaseException: + logging.warning("Rolling back checked out %s for %s", ref, orig_ref) + self.run(f"git reset --hard; git checkout {orig_ref}") + raise + else: + if with_rollback and need_rollback: + self.run(f"git checkout {orig_ref}") + + @contextmanager + def prestable(self, args: argparse.Namespace): + self.check_no_tags_after() + # Create release branch + # TODO: this place is wrong. If we are in stale branch, it will produce + # a wrong version + self.update() + release_branch = f"{self.version.major}.{self.version.minor}" + with self._new_branch(release_branch, self.release_commit): + with self._checkout(release_branch, True): + self.update() + self.version.with_description(VersionType.PRESTABLE) + with self._create_gh_release(args): + with self._bump_prestable_version(release_branch, args): + # At this point everything will rollback automatically + yield + + @contextmanager + def testing(self, args: argparse.Namespace): + # Create branch for a version bump + self.update() + # TODO: this place is wrong. If we are in stale branch, it will produce + # a wrong version + self.version = self.version.update(args.release_type) + helper_branch = f"{self.version.major}.{self.version.minor}-prepare" + with self._new_branch(helper_branch, self.release_commit): + with self._checkout(helper_branch, True): + self.update() + self.version = self.version.update(args.release_type) + with self._bump_testing_version(helper_branch, args): + yield + + @contextmanager + def _bump_testing_version(self, helper_branch: str, args: argparse.Namespace): + update_cmake_version(self.version) + cmake_path = get_abs_path(FILE_WITH_VERSION_PATH) + self.run( + f"git commit -m 'Update version to {self.version.string}' '{cmake_path}'" + ) + with self._push(helper_branch, args): + body_file = get_abs_path(".github/PULL_REQUEST_TEMPLATE.md") + self.run( + f"gh pr create --repo {args.repo} --title 'Update version after " + f"release' --head {helper_branch} --body-file '{body_file}'" + ) + # Here the prestable part is done + yield + + @contextmanager + def _bump_prestable_version(self, release_branch: str, args: argparse.Namespace): + new_version = self.version.patch_update() + update_cmake_version(new_version) + cmake_path = get_abs_path(FILE_WITH_VERSION_PATH) + self.run( + f"git commit -m 'Update version to {new_version.string}' '{cmake_path}'" + ) + with self._push(release_branch, args): + self.run( + f"gh pr create --repo {args.repo} --title 'Release pull request for " + f"branch {release_branch}' --head {release_branch} --body 'This " + "PullRequest is a part of ClickHouse release cycle. It is used by CI " + "system only. Do not perform any changes with it.' --label release" + ) + # Here the prestable part is done + yield + + @contextmanager + def _create_gh_release(self, args: argparse.Namespace): + with self._create_tag(args): + # Preserve tag if version is changed + tag = self.version.describe + self.run( + f"gh release create --prerelease --draft --repo {args.repo} '{tag}'" + ) + try: + yield + except BaseException: + logging.warning("Rolling back release publishing") + self.run(f"gh release delete --yes --repo {args.repo} '{tag}'") + raise + + @contextmanager + def _create_tag(self, args: argparse.Namespace): + tag = self.version.describe + self.run(f"git tag -a -m 'Release {tag}' '{tag}'") + try: + with self._push(f"'{tag}'", args): + yield + except BaseException: + logging.warning("Rolling back tag %s", tag) + self.run(f"git tag -d '{tag}'") + raise + + @contextmanager + def _push(self, ref: str, args: argparse.Namespace): + self.run(f"git push git@github.com:{args.repo}.git {ref}") + try: + yield + except BaseException: + logging.warning("Rolling back pushed ref %s", ref) + self.run(f"git push -d git@github.com:{args.repo}.git {ref}") + raise + + def do(self, args: argparse.Namespace): + self.release_commit = args.commit + + if not args.no_check_dirty: + logging.info("Checking if repo is clean") + self.run("git diff HEAD --exit-code") + + if not args.no_check_branch: + self.check_branch(args.release_type) + + if args.release_type in self.BIG: + if args.no_prestable: + logging.info("Skipping prestable stage") + else: + with self.prestable(args): + logging.info("Prestable part of the releasing is done") + + with self.testing(args): + logging.info("Testing part of the releasing is done") + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser( + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + description="Script to release a new ClickHouse version, requires `git` and " + "`gh` (github-cli) commands", + ) + + parser.add_argument( + "--repo", + default="ClickHouse/ClickHouse", + help="repository to create the release", + ) + parser.add_argument( + "--type", + default="minor", + # choices=Release.BIG+Release.SMALL, # add support later + choices=Release.BIG + Release.SMALL, + dest="release_type", + help="a release type, new branch is created only for 'major' and 'minor'", + ) + parser.add_argument( + "--no-prestable", + action="store_true", + help=f"for release types in {Release.BIG} skip creating prestable release and " + "release branch", + ) + parser.add_argument( + "--commit", + default=git.sha, + type=commit, + help="commit create a release, default to HEAD", + ) + parser.add_argument( + "--no-check-dirty", + action="store_true", + help="skip check repository for uncommited changes", + ) + parser.add_argument( + "--no-check-branch", + action="store_true", + help="by default, 'major' and 'minor' types work only for master, and 'patch' " + "works only for a release branches, that name should be the same as " + "'$MAJOR.$MINOR' version, e.g. 22.2", + ) + parser.add_argument( + "--no-publish-release", + action="store_true", + help="by default, 'major' and 'minor' types work only for master, and 'patch' ", + ) + + return parser.parse_args() + + +def prestable(): + pass + + +def main(): + logging.basicConfig(level=logging.INFO) + args = parse_args() + release = Release(get_version_from_repo()) + + release.do(args) + + # if not args.no_publish_release: + # # Publish release on github for the current HEAD (master, if checked) + # git.run(f"gh release create --draft {git.new_tag} --target {git.sha}") + + ## Commit updated versions to HEAD and push to remote + # write_versions(versions_file, new_versions) + # git.run(f"git checkout -b {git.new_branch}-helper") + # git.run( + # f"git commit -m 'Auto version update to [{new_versions['VERSION_STRING']}] " + # f"[{new_versions['VERSION_REVISION']}]' {versions_file}" + # ) + # git.run(f"git push -u origin {git.new_branch}-helper") + # git.run( + # f"gh pr create --title 'Update version after release {git.new_branch}' " + # f"--body-file '{git.root}/.github/PULL_REQUEST_TEMPLATE.md'" + # ) + + ## Create a new branch from the previous commit and push there with creating + ## a PR + # git.run(f"git checkout -b {git.new_branch} HEAD~") + # write_versions(versions_file, versions) + # git.run( + # f"git commit -m 'Auto version update to [{versions['VERSION_STRING']}] " + # f"[{versions['VERSION_REVISION']}]' {versions_file}" + # ) + # git.run(f"git push -u origin {git.new_branch}") + # git.run( + # "gh pr create --title 'Release pull request for branch " + # f"{versions['VERSION_MAJOR']}.{versions['VERSION_MINOR']}' --body " + # "'This PullRequest is part of ClickHouse release cycle. It is used by CI " + # "system only. Do not perform any changes with it.' --label release" + # ) + + +if __name__ == "__main__": + main() diff --git a/tests/ci/version_helper.py b/tests/ci/version_helper.py old mode 100644 new mode 100755 index e207dac4671..02e22ee0c4d --- a/tests/ci/version_helper.py +++ b/tests/ci/version_helper.py @@ -1,128 +1,191 @@ #!/usr/bin/env python3 -import os -import subprocess import datetime +import logging +import os.path as p +import subprocess +from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter +from typing import Dict, Tuple, Union + +from git_helper import Git, removeprefix FILE_WITH_VERSION_PATH = "cmake/autogenerated_versions.txt" CHANGELOG_IN_PATH = "debian/changelog.in" CHANGELOG_PATH = "debian/changelog" -CONTRIBUTORS_SCRIPT_DIR = "src/Storages/System/" +GENERATED_CONTRIBUTORS = "src/Storages/System/StorageSystemContributors.generated.cpp" + +# It has {{ for plain "{" +CONTRIBUTORS_TEMPLATE = """// autogenerated by {executer} +const char * auto_contributors[] {{ +{contributors} + nullptr}}; +""" + +VERSIONS = Dict[str, Union[int, str]] + +VERSIONS_TEMPLATE = """# This variables autochanged by release_lib.sh: + +# NOTE: has nothing common with DBMS_TCP_PROTOCOL_VERSION, +# only DBMS_TCP_PROTOCOL_VERSION should be incremented on protocol changes. +SET(VERSION_REVISION {revision}) +SET(VERSION_MAJOR {major}) +SET(VERSION_MINOR {minor}) +SET(VERSION_PATCH {patch}) +SET(VERSION_GITHASH {githash}) +SET(VERSION_DESCRIBE {describe}) +SET(VERSION_STRING {string}) +# end of autochange +""" + +git = Git() -class ClickHouseVersion(): - def __init__(self, major, minor, patch, tweak, revision): - self.major = major - self.minor = minor - self.patch = patch - self.tweak = tweak - self.revision = revision +class ClickHouseVersion: + """Immutable version class. On update returns a new instance""" - def minor_update(self): + def __init__( + self, + major: Union[int, str], + minor: Union[int, str], + patch: Union[int, str], + revision: Union[int, str], + git: Git, + ): + self._major = int(major) + self._minor = int(minor) + self._patch = int(patch) + self._revision = int(revision) + self._git = git + self._describe = "" + + def update(self, part: str) -> "ClickHouseVersion": + """If part is valid, returns a new version""" + method = getattr(self, f"{part}_update") + return method() + + def major_update(self) -> "ClickHouseVersion": + return ClickHouseVersion(self.major + 1, 1, 1, self.revision + 1, self._git) + + def minor_update(self) -> "ClickHouseVersion": return ClickHouseVersion( - self.major, - self.minor + 1, - 1, - 1, - self.revision + 1) + self.major, self.minor + 1, 1, self.revision + 1, self._git + ) - def patch_update(self): + def patch_update(self) -> "ClickHouseVersion": return ClickHouseVersion( - self.major, - self.minor, - self.patch + 1, - 1, - self.revision) + self.major, self.minor, self.patch + 1, self.revision, self._git + ) - def tweak_update(self): - return ClickHouseVersion( - self.major, - self.minor, - self.patch, - self.tweak + 1, - self.revision) + @property + def major(self) -> int: + return self._major - def get_version_string(self): - return '.'.join([ - str(self.major), - str(self.minor), - str(self.patch), - str(self.tweak) - ]) + @property + def minor(self) -> int: + return self._minor - def as_tuple(self): + @property + def patch(self) -> int: + return self._patch + + @property + def tweak(self) -> int: + return self._git.tweak + + @property + def revision(self) -> int: + return self._revision + + @property + def githash(self) -> str: + return self._git.sha + + @property + def describe(self): + return self._describe + + @property + def string(self): + return ".".join( + (str(self.major), str(self.minor), str(self.patch), str(self.tweak)) + ) + + def as_dict(self) -> VERSIONS: + return { + "revision": self.revision, + "major": self.major, + "minor": self.minor, + "patch": self.patch, + "tweak": self.tweak, + "githash": self.githash, + "describe": self.describe, + "string": self.string, + } + + def as_tuple(self) -> Tuple[int, int, int, int]: return (self.major, self.minor, self.patch, self.tweak) + def with_description(self, version_type): + if version_type not in VersionType.VALID: + raise ValueError(f"version type {version_type} not in {VersionType.VALID}") + self._describe = f"v{self.string}-{version_type}" -class VersionType(): + +class VersionType: + LTS = "lts" + PRESTABLE = "prestable" STABLE = "stable" TESTING = "testing" + VALID = (TESTING, PRESTABLE, STABLE, LTS) -def build_version_description(version, version_type): - return "v" + version.get_version_string() + "-" + version_type +def get_abs_path(path: str) -> str: + return p.abspath(p.join(git.root, path)) -def _get_version_from_line(line): - _, ver_with_bracket = line.strip().split(' ') - return ver_with_bracket[:-1] +def read_versions(versions_path: str = FILE_WITH_VERSION_PATH) -> VERSIONS: + versions = {} + path_to_file = get_abs_path(versions_path) + with open(path_to_file, "r", encoding="utf-8") as f: + for line in f: + line = line.strip() + if not line.startswith("SET("): + continue -def get_tweak_from_git_describe(repo_path): - # something like v21.12.1.8816-testing-358-g81942b8128 - # or v21.11.4.14-stable-31-gd6aab025e0 - output = subprocess.check_output(f"cd {repo_path} && git describe --long", shell=True).decode('utf-8') - commits_number = int(output.split('-')[-2]) - # for testing releases we have to also add fourth number of - # the previous tag - if 'testing' in output: - previous_version = output.split('-')[0] - previous_version_commits = int(previous_version.split('.')[3]) - commits_number += previous_version_commits + value = 0 # type: Union[int, str] + name, value = line[4:-1].split(maxsplit=1) + name = removeprefix(name, "VERSION_").lower() + try: + value = int(value) + except ValueError: + pass + versions[name] = value - return commits_number + return versions -def get_version_from_repo(repo_path): - path_to_file = os.path.join(repo_path, FILE_WITH_VERSION_PATH) - major = 0 - minor = 0 - patch = 0 - tweak = get_tweak_from_git_describe(repo_path) - version_revision = 0 - with open(path_to_file, 'r') as ver_file: - for line in ver_file: - if "VERSION_MAJOR" in line and "math" not in line and "SET" in line: - major = _get_version_from_line(line) - elif "VERSION_MINOR" in line and "math" not in line and "SET" in line: - minor = _get_version_from_line(line) - elif "VERSION_PATCH" in line and "math" not in line and "SET" in line: - patch = _get_version_from_line(line) - elif "VERSION_REVISION" in line and "math" not in line: - version_revision = _get_version_from_line(line) - return ClickHouseVersion(major, minor, patch, tweak, version_revision) - - -def _update_cmake_version(repo_path, version, sha, version_type): - cmd = """sed -i --follow-symlinks -e "s/SET(VERSION_REVISION [^) ]*/SET(VERSION_REVISION {revision}/g;" \ - -e "s/SET(VERSION_DESCRIBE [^) ]*/SET(VERSION_DESCRIBE {version_desc}/g;" \ - -e "s/SET(VERSION_GITHASH [^) ]*/SET(VERSION_GITHASH {sha}/g;" \ - -e "s/SET(VERSION_MAJOR [^) ]*/SET(VERSION_MAJOR {major}/g;" \ - -e "s/SET(VERSION_MINOR [^) ]*/SET(VERSION_MINOR {minor}/g;" \ - -e "s/SET(VERSION_PATCH [^) ]*/SET(VERSION_PATCH {patch}/g;" \ - -e "s/SET(VERSION_STRING [^) ]*/SET(VERSION_STRING {version_string}/g;" \ - {path}""".format( - revision=version.revision, - version_desc=build_version_description(version, version_type), - sha=sha, - major=version.major, - minor=version.minor, - patch=version.patch, - version_string=version.get_version_string(), - path=os.path.join(repo_path, FILE_WITH_VERSION_PATH), +def get_version_from_repo( + versions_path: str = FILE_WITH_VERSION_PATH, +) -> ClickHouseVersion: + versions = read_versions(versions_path) + return ClickHouseVersion( + versions["major"], + versions["minor"], + versions["patch"], + versions["revision"], + git, ) - subprocess.check_call(cmd, shell=True) -def _update_changelog(repo_path, version): +def update_cmake_version( + version: ClickHouseVersion, + versions_path: str = FILE_WITH_VERSION_PATH, +): + path_to_file = get_abs_path(versions_path) + with open(path_to_file, "w", encoding="utf-8") as f: + f.write(VERSIONS_TEMPLATE.format_map(version.as_dict())) + + +def _update_changelog(repo_path: str, version: ClickHouseVersion): cmd = """sed \ -e "s/[@]VERSION_STRING[@]/{version_str}/g" \ -e "s/[@]DATE[@]/{date}/g" \ @@ -130,24 +193,117 @@ def _update_changelog(repo_path, version): -e "s/[@]EMAIL[@]/clickhouse-release@yandex-team.ru/g" \ < {in_path} > {changelog_path} """.format( - version_str=version.get_version_string(), + version_str=version.string, date=datetime.datetime.now().strftime("%a, %d %b %Y %H:%M:%S") + " +0300", - in_path=os.path.join(repo_path, CHANGELOG_IN_PATH), - changelog_path=os.path.join(repo_path, CHANGELOG_PATH) + in_path=p.join(repo_path, CHANGELOG_IN_PATH), + changelog_path=p.join(repo_path, CHANGELOG_PATH), ) subprocess.check_call(cmd, shell=True) -def _update_contributors(repo_path): - cmd = "cd {} && ./StorageSystemContributors.sh".format(os.path.join(repo_path, CONTRIBUTORS_SCRIPT_DIR)) + +def update_contributors( + relative_contributors_path: str = GENERATED_CONTRIBUTORS, force: bool = False +): + # Check if we have shallow checkout by comparing number of lines + # '--is-shallow-repository' is in git since 2.15, 2017-10-30 + if git.run("git rev-parse --is-shallow-repository") == "true" and not force: + logging.warning("The repository is shallow, refusing to update contributors") + return + + contributors = git.run("git shortlog HEAD --summary") + contributors = sorted( + [c.split(maxsplit=1)[-1].replace('"', r"\"") for c in contributors.split("\n")], + ) + contributors = [f' "{c}",' for c in contributors] + + executer = p.relpath(p.realpath(__file__), git.root) + content = CONTRIBUTORS_TEMPLATE.format( + executer=executer, contributors="\n".join(contributors) + ) + contributors_path = get_abs_path(relative_contributors_path) + with open(contributors_path, "w", encoding="utf-8") as cfd: + cfd.write(content) + + +def _update_dockerfile(repo_path: str, version: ClickHouseVersion): + version_str_for_docker = ".".join( + [str(version.major), str(version.minor), str(version.patch), "*"] + ) + cmd = "ls -1 {path}/docker/*/Dockerfile | xargs sed -i -r -e 's/ARG version=.+$/ARG version='{ver}'/'".format( + path=repo_path, ver=version_str_for_docker + ) subprocess.check_call(cmd, shell=True) -def _update_dockerfile(repo_path, version): - version_str_for_docker = '.'.join([str(version.major), str(version.minor), str(version.patch), '*']) - cmd = "ls -1 {path}/docker/*/Dockerfile | xargs sed -i -r -e 's/ARG version=.+$/ARG version='{ver}'/'".format(path=repo_path, ver=version_str_for_docker) - subprocess.check_call(cmd, shell=True) -def update_version_local(repo_path, sha, version, version_type="testing"): - _update_contributors(repo_path) - _update_cmake_version(repo_path, version, sha, version_type) +def update_version_local(repo_path, version, version_type="testing"): + update_contributors() + version.with_description(version_type) + update_cmake_version(version, version_type) _update_changelog(repo_path, version) _update_dockerfile(repo_path, version) + + +def main(): + """The simplest thing it does - reads versions from cmake and produce the + environment variables that may be sourced in bash scripts""" + parser = ArgumentParser( + formatter_class=ArgumentDefaultsHelpFormatter, + description="The script reads versions from cmake and produce ENV variables", + ) + parser.add_argument( + "--version-path", + "-p", + default=FILE_WITH_VERSION_PATH, + help="relative path to the cmake file with versions", + ) + parser.add_argument( + "--version-type", + "-t", + choices=VersionType.VALID, + help="optional parameter to generate DESCRIBE", + ) + parser.add_argument( + "--export", + "-e", + action="store_true", + help="if the ENV variables should be exported", + ) + parser.add_argument( + "--update", + "-u", + choices=("major", "minor", "patch"), + help="the version part to update, tweak is always calculated from commits", + ) + parser.add_argument( + "--update-contributors", + "-c", + action="store_true", + help=f"update {GENERATED_CONTRIBUTORS} file and exit, " + "doesn't work on shallow repo", + ) + args = parser.parse_args() + + if args.update_contributors: + update_contributors() + return + + version = get_version_from_repo(args.version_path) + + if args.update: + version = version.update(args.update) + + if args.version_type: + version.with_description(args.version_type) + + if args.update: + update_cmake_version(version) + + for k, v in version.as_dict().items(): + name = f"CLICKHOUSE_VERSION_{k.upper()}" + print(f"{name}='{v}'") + if args.export: + print(f"export {name}") + + +if __name__ == "__main__": + main()