1#!/usr/bin/env python 2 3# Release lvgl, lv_examples, lv_drivers. docs, blog and prepare the development of the next major, minoror bugfix release 4# Usage: ./release,py bugfix | minor | major 5# The option means what type of versin to prepare for development after release 6# 7# STEPS: 8# - clone all 5 repos 9# - get the version numnber from lvgl.h 10# - set release branch (e.g. "release/v7") 11# - prepare lvgl 12# - run lv_conf_internal.py 13# - run code formatter 14# - clear LVGL_VERSION_INFO (set to "") 15# - run Doxygen 16# - update the version in lvgl's library.json, library.properties, lv_conf_template.h 17# - update CHANGELOG.md 18# - commit changes 19# - prepare lv_examples 20# - upadte the required LVGL version in lv_examples.h (LV_VERSION_CHECK) 21# - update the version in lv_ex_conf_template.h 22# - prepare lv_drivers 23# - update the version in library.json, lv_drv_conf_template.h 24# - prepare docs 25# - update API XML 26# - clear the versiopn info (should be plain vx.y.z) 27# - tag all repos with the new version 28# - merge to release branches 29# - blog: add release post 30# - push tags and commits 31# - docs: run ./updade.py release/vX 32# 33# If --patch 34# - merge master to dev branches 35# - increment patch version by 1 and append "-dev". E.g. "vX.Y.(Z+1)-dev" 36# - update version numbers in lvgl and docs 37# - commit and push 38# - docs: run ./updade.py latest dev 39# 40# Else (not --patch) 41# - merge master to dev 42# - merge the dev to master 43# - increment version number like "vX.(Y+1).0-dev" 44# - apply the new version in dev branches of lvgl, lv_examples, lv_drivers, docs 45# - commit and push to dev branches 46# - docs: run ./updade.py latest dev 47 48import re 49import os, fnmatch 50import os.path 51from os import path 52from datetime import date 53import sys 54 55upstream_org_url = "https://github.com/lvgl/" 56workdir = "./release_tmp" 57proj_list = [ "lv_sim_eclipse_sdl"] 58 59ver_major = -1 60ver_minor = -1 61ver_patch = -1 62 63dev_ver_major = -1 64dev_ver_minor = -1 65dev_ver_patch = -1 66 67ver_str = "" 68dev_ver_str = "" 69release_br = "" 70release_note = "" 71 72prepare_type = ['major', 'minor', 'bugfix'] 73 74dev_prepare = 'minor' 75 76def upstream(repo): 77 return upstream_org_url + repo + ".git" 78 79def cmd(c, exit_on_err = True): 80 print("\n" + c) 81 r = os.system(c) 82 if r: 83 print("### Error: " + str(r)) 84 if exit_on_err: exit(int(r)) 85 86def define_set(fn, name, value): 87 print("In " + fn + " set " + name + " to " + value) 88 89 new_content = "" 90 s = r'^ *# *define +' + str(name).rstrip() 91 92 f = open(fn, "r") 93 for i in f.read().splitlines(): 94 r = re.search(s, i) 95 if r: 96 d = i.split("define") 97 i = d[0] + "define " + name + " " + value 98 new_content += i + '\n' 99 100 f.close() 101 102 f = open(fn, "w") 103 f.write(new_content) 104 f.close() 105 106def clone_repos(): 107 cmd("rm -fr " + workdir) 108 cmd("mkdir " + workdir) 109 os.chdir(workdir) 110 111 #For debuging just copy the repos 112 #cmd("cp -a ../repos/. .") 113 #return 114 115 cmd("git clone " + upstream("lvgl") + "; cd lvgl; git checkout master; git remote update origin --prune; ") 116 cmd("git clone " + upstream("lv_examples") + "; cd lv_examples; git checkout master; git remote update origin --prune; ") 117 cmd("git clone " + upstream("lv_drivers") + "; cd lv_drivers; git checkout master; git remote update origin --prune; ") 118 cmd("git clone --recurse-submodules " + upstream("docs") + "; cd docs; git checkout master; git remote update origin --prune; ") 119 cmd("git clone " + upstream("blog") + "; cd blog; git checkout master; git remote update origin --prune; ") 120 121 for p in proj_list: 122 cmd("git clone " + upstream(p) + " --recurse-submodules ; cd " + p + "; git checkout master; git remote update origin --prune; ") 123 124 125def get_lvgl_version(br): 126 print("Get LVGL's version") 127 128 global ver_str, ver_major, ver_minor, ver_patch, release_br 129 130 os.chdir("./lvgl") 131 132 cmd("git checkout " + br) 133 134 f = open("./lvgl.h", "r") 135 136 lastNum = re.compile(r'(?:[^\d]*(\d+)[^\d]*)+') 137 for i in f.read().splitlines(): 138 r = re.search(r'^#define LVGL_VERSION_MAJOR ', i) 139 if r: 140 m = lastNum.search(i) 141 if m: ver_major = m.group(1) 142 143 r = re.search(r'^#define LVGL_VERSION_MINOR ', i) 144 if r: 145 m = lastNum.search(i) 146 if m: ver_minor = m.group(1) 147 148 r = re.search(r'^#define LVGL_VERSION_PATCH ', i) 149 if r: 150 m = lastNum.search(i) 151 if m: ver_patch = m.group(1) 152 153 f.close() 154 155 cmd("git checkout master") 156 157 ver_str = "v" + str(ver_major) + "." + str(ver_minor) + "." + str(ver_patch) 158 print("New version:" + ver_str) 159 160 release_br = "release/v" + ver_major 161 162 os.chdir("../") 163 164def update_version(): 165 templ = fnmatch.filter(os.listdir('.'), '*templ*') 166 167 if templ[0]: 168 print("Updating version in " + templ[0]) 169 cmd("sed -i -r 's/v[0-9]+\.[0-9]+\.[0-9]+/"+ ver_str +"/' " + templ[0]) 170 171 if os.path.exists("library.json"): 172 print("Updating version in library.json") 173 cmd("sed -i -r 's/[0-9]+\.[0-9]+\.[0-9]+/"+ ver_str[1:] +"/' library.json") 174 175 if path.exists("library.properties"): 176 print("Updating version in library.properties") 177 cmd("sed -i -r 's/version=[0-9]+\.[0-9]+\.[0-9]+/"+ "version=" + ver_str[1:] + "/' library.properties") 178 179def lvgl_prepare(): 180 print("Prepare lvgl") 181 182 global ver_str, ver_major, ver_minor, ver_patch 183 184 os.chdir("./lvgl") 185 define_set("./lvgl.h", "LVGL_VERSION_INFO", '\"\"') 186 187 # Run some scripts 188 os.chdir("./scripts") 189 cmd("./code-format.sh") 190 cmd("./lv_conf_checker.py") 191 cmd("doxygen") 192 os.chdir("../") 193 194 update_version() 195 196 #update CHANGLELOG 197 new_content = "" 198 f = open("./CHANGELOG.md", "r") 199 200 global release_note 201 release_note = "" 202 note_state = 0 203 for i in f.read().splitlines(): 204 if note_state == 0: 205 r = re.search(r'^## ' + ver_str, i) 206 if r: 207 i = i.replace("planned on ", "") 208 note_state+=1 209 210 elif note_state == 1: 211 r = re.search(r'^## ', i) 212 if r: 213 note_state+=1 214 else: 215 release_note += i + '\n' 216 217 new_content += i + '\n' 218 219 f.close() 220 221 f = open("./CHANGELOG.md", "w") 222 f.write(new_content) 223 f.close() 224 225 cmd('git commit -am "prepare to release ' + ver_str + '"') 226 227 os.chdir("../") 228 229 230def lv_examples_prepare(): 231 print("Prepare lv_examples") 232 global ver_str, ver_major, ver_minor, ver_patch 233 234 os.chdir("./lv_examples") 235 236 update_version() 237 238 cmd("sed -i -r 's/LV_VERSION_CHECK\([0-9]+, *[0-9]+, *[0-9]+\)/"+ "LV_VERSION_CHECK(" + ver_major + ", " + ver_minor + ", " + ver_patch + ")/' lv_examples.h") 239 240 cmd('git commit -am "prepare to release ' + ver_str + '"') 241 242 os.chdir("../") 243 244def lv_drivers_prepare(): 245 print("Prepare lv_drivers") 246 global ver_str, ver_major, ver_minor, ver_patch 247 248 os.chdir("./lv_drivers") 249 250 update_version() 251 252 cmd('git commit -am "prepare to release ' + ver_str + '"') 253 254 os.chdir("../") 255 256def docs_prepare(): 257 print("Prepare docs") 258 global ver_str, ver_major, ver_minor, ver_patch 259 260 os.chdir("./docs") 261 262 cmd("git co latest --") 263 cmd("rm -rf xml"); 264 cmd("cp -r ../lvgl/docs/api_doc/xml ."); 265 cmd("git add xml"); 266 267 cmd("sed -i -r \"s/'v[0-9]+\.[0-9]+\.[0-9]+.*'/\'" + ver_str + "'/\" conf.py") 268 269 cmd('git commit -am "prepare to release ' + ver_str + '"') 270 271 os.chdir("../") 272 273def blog_add_post(): 274 global ver_str, release_note 275 276 os.chdir("./blog/_posts") 277 278 post = "---\nlayout: post\ntitle: " + ver_str + " is released\nauthor: \"kisvegabor\"\ncover: /assets/release_cover.png\n---\n\n" 279 post += release_note 280 281 today = date.today() 282 d = today.strftime("%Y-%m-%d") 283 284 f = open(d + "-release_" + ver_str + ".md", "w") 285 f.write(post) 286 f.close() 287 288 cmd("git add .") 289 cmd("git commit -am 'Add " + ver_str + " release post'") 290 291 os.chdir("../../") 292 293def add_tags(): 294 global ver_str 295 tag_cmd = " git tag -a " + ver_str + " -m 'Release " + ver_str + "' " 296 cmd("cd lvgl; " + tag_cmd) 297 cmd("cd lv_examples; " + tag_cmd) 298 cmd("cd lv_drivers; " + tag_cmd) 299 cmd("cd docs; " + tag_cmd) 300 301def update_release_branches(): 302 global release_br 303 merge_cmd = " git checkout " + release_br + "; git pull origin " + release_br + "; git merge master -X ours; git push origin " + release_br + "; git checkout master" 304 cmd("cd lvgl; " + merge_cmd) 305 cmd("cd lv_examples; " + merge_cmd) 306 cmd("cd lv_drivers; " + merge_cmd) 307 308 merge_cmd = " git checkout " + release_br + "; git pull origin " + release_br + "; git merge latest -X ours; git push origin " + release_br + "; git checkout latest" 309 cmd("cd docs; " + merge_cmd) 310 311def publish_master(): 312 313 #Merge LVGL master to dev first to avoid "merge-to-dev.yml" running asynchronous 314 os.chdir("./lvgl") 315 cmd("git checkout dev") 316 cmd("git merge master -X ours") 317 cmd("git add .") 318 cmd("git commit -am 'Merge master'", False) 319 cmd("git push origin dev") 320 cmd("git checkout master") 321 os.chdir("../") 322 323 pub_cmd = "git push origin master; git push origin " + ver_str 324 cmd("cd lvgl; " + pub_cmd) 325 cmd("cd lv_examples; " + pub_cmd) 326 cmd("cd lv_drivers; " + pub_cmd) 327 328 pub_cmd = "git push origin master" 329 cmd("cd blog; " + pub_cmd) 330 331def merge_from_dev(): 332 merge_cmd = "git checkout master; git merge dev;" 333 cmd("cd lvgl; " + merge_cmd) 334 335 merge_cmd = "git checkout latest -- ; git merge dev -X theirs --no-edit;" 336 cmd("cd docs; " + merge_cmd) 337 338 339def lvgl_update_master_version(): 340 global ver_major, ver_minor, ver_patch, ver_str 341 342 os.chdir("./lvgl") 343 344 cmd("git checkout master") 345 define_set("./lvgl.h", "LVGL_VERSION_MAJOR", ver_major) 346 define_set("./lvgl.h", "LVGL_VERSION_MINOR", ver_minor) 347 define_set("./lvgl.h", "LVGL_VERSION_PATCH", ver_patch) 348 define_set("./lvgl.h", "LVGL_VERSION_INFO", "dev") 349 350 templ = fnmatch.filter(os.listdir('.'), '*templ*') 351 if templ[0]: 352 print("Updating version in " + templ[0]) 353 cmd("sed -i -r 's/v[0-9]+\.[0-9]+\.[0-9]+.*/"+ ver_str +"/' " + templ[0]) 354 355 356 cmd("git commit -am 'Update version'") 357 358 os.chdir("../") 359 360def docs_update_latest_version(): 361 global ver_str 362 363 os.chdir("./docs") 364 cmd("git checkout latest --") 365 cmd("sed -i -r \"s/'v[0-9]+\.[0-9]+\.[0-9]+.*'/\'" + ver_str + "'/\" conf.py") 366 cmd("git commit -am 'Update version'") 367 cmd("git checkout master --") 368 369 os.chdir("../") 370 371 372def lvgl_update_dev_version(): 373 global ver_major, ver_minor, ver_patch, dev_ver_str 374 375 os.chdir("./lvgl") 376 377 cmd("git checkout dev") 378 define_set("./lvgl.h", "LVGL_VERSION_MAJOR", str(ver_major)) 379 define_set("./lvgl.h", "LVGL_VERSION_MINOR", str(ver_minor)) 380 define_set("./lvgl.h", "LVGL_VERSION_PATCH", str(ver_patch)) 381 define_set("./lvgl.h", "LVGL_VERSION_INFO", "\"dev\"") 382 383 templ = fnmatch.filter(os.listdir('.'), '*templ*') 384 if templ[0]: 385 print("Updating version in " + templ[0]) 386 cmd("sed -i -r 's/v[0-9]+\.[0-9]+\.[0-9]+.*/"+ dev_ver_str +"/' " + templ[0]) 387 388 389 cmd("git commit -am 'Update dev version'") 390 cmd("git checkout master") 391 392 os.chdir("../") 393 394def docs_update_dev_version(): 395 global dev_ver_str 396 397 os.chdir("./docs") 398 cmd("git checkout dev --") 399 cmd("sed -i -r \"s/'v[0-9]+\.[0-9]+\.[0-9]+.*'/\'" + dev_ver_str + "'/\" conf.py") 400 cmd("git commit -am 'Update dev version'") 401 cmd("git checkout master --") 402 403 os.chdir("../") 404 405 406def publish_dev_and_master(): 407 pub_cmd = "git checkout dev; git push origin dev" 408 cmd("cd lvgl; " + pub_cmd) 409 pub_cmd = "git checkout master; git push origin master" 410 cmd("cd lvgl; " + pub_cmd) 411 412def projs_update(): 413 global proj_list, release_br, ver_str 414 for p in proj_list: 415 os.chdir("./" + p) 416 cmd('git checkout master') 417 print(p + ": upadte lvgl"); 418 cmd("cd lvgl; git co " + release_br + "; git pull origin " + release_br) 419 cmd("cp -f lvgl/lv_conf_template.h lv_conf.h") 420 cmd("sed -i -r 's/#if 0/#if 1/' lv_conf.h") # Enable lv_conf.h 421 d = {} 422 with open("confdef.txt") as f: 423 for line in f: 424 (key, val) = line.rstrip().split('\t') 425 d[key] = val 426 427 for k,v in d.items(): 428 define_set("lv_conf.h", str(k), str(v)) 429 430 if os.path.exists("lv_examples"): 431 print(p + ": upadte lv_examples"); 432 cmd("cd lv_examples; git co " + release_br + "; git pull origin " + release_br) 433 434 if os.path.exists("lv_drivers"): 435 print(p + ": upadte lv_drivers"); 436 cmd("cd lv_drivers " + release_br + "; git pull origin " + release_br) 437 438 msg = 'Update to ' + ver_str 439 cmd("git add .") 440 cmd('git commit -am "' + msg + '"') 441 cmd('git push origin master') 442 cmd("git tag -a " + ver_str + " -m '" + msg + "' " ) 443 cmd('git push origin ' + ver_str) 444 445 os.chdir("../") 446 447def docs_update_all(): 448 cmd("cd docs; git checkout master; python 2.7 ./update.py master dev " + release_br) 449 450def cleanup(): 451 os.chdir("../") 452 cmd("rm -fr " + workdir) 453 454if __name__ == '__main__': 455 dev_prepare = 'bugfix' 456 if(len(sys.argv) != 2): 457 print("Missing argument. Usage ./release.py bugfix | minor | major") 458 print("Use minor by deafult") 459 else: 460 dev_prepare = sys.argv[1] 461 462 if not (dev_prepare in prepare_type): 463 print("Invalid argument. Usage ./release.py bugfix | minor | major") 464 exit(1) 465 466 clone_repos() 467 get_lvgl_version("dev") 468 dev_ver_major = ver_major 469 dev_ver_minor = ver_minor 470 dev_ver_patch = ver_patch 471 dev_ver_str = ver_str 472 473 get_lvgl_version("master") 474 475 lvgl_prepare() 476 lv_examples_prepare() 477 lv_drivers_prepare() 478 docs_prepare() 479 blog_add_post() 480 add_tags() 481 update_release_branches() 482 publish_master() 483 484 projs_update() 485 486 if dev_prepare == 'bugfix': 487 ver_patch = str(int(ver_patch) + 1) 488 ver_str = "v" + ver_major + "." + ver_minor + "." + ver_patch + "-dev" 489 490 print("Prepare bugfix version " + ver_str) 491 492 lvgl_update_master_version() 493 docs_update_latest_version() 494 495 else: 496 #merge_from_dev() 497 498 get_lvgl_version("master") 499 500 if dev_prepare == 'minor': 501 ver_minor = str(int(ver_minor) + 1) 502 ver_patch = "0" 503 else: 504 ver_major = str(int(ver_major) + 1) 505 ver_minor = "0" 506 ver_patch = "0" 507 508 dev_ver_str = "v" + str(ver_major) + "." + str(ver_minor) + "." + str(ver_patch) + "-dev" 509 510 print("Prepare minor version " + dev_ver_str) 511 512 lvgl_update_dev_version() 513 docs_update_dev_version() 514 publish_dev_and_master() 515 516 docs_update_all(); 517 cleanup() 518 519