Merge pull request #34641 from ClickHouse/version-and-release

refactor version_helper, create release script
This commit is contained in:
Mikhail f. Shiryaev 2022-02-16 14:00:55 +01:00 committed by GitHub
commit 4f84406136
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 839 additions and 178 deletions

View File

@ -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};

View File

@ -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

View File

@ -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,

112
tests/ci/git_helper.py Normal file
View File

@ -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

View File

@ -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)

View File

@ -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,

328
tests/ci/release.py Executable file
View File

@ -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()

368
tests/ci/version_helper.py Normal file → Executable file
View File

@ -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()