11#!/usr/bin/env python3
22
3+ import sys
34import os
45import re
6+ import urllib .request
57import time
8+ import json
9+ from datetime import datetime , timezone
610
711ROOT = "."
812init_py_path = os .path .join (ROOT , "ddns" , "__init__.py" )
@@ -153,32 +157,83 @@ def remove_python2_compatibility(pyfile):
153157 print (f"Removed python2 compatibility from { pyfile } " )
154158
155159
156- def extract_version_from_env ():
157- """
158- 从环境变量中提取版本号
159- """
160- ref = os .environ .get ("GITHUB_REF_NAME" )
161- if not ref :
162- return time .strftime ("0.0.%m%d.%H%M" ) # 默认版本号
163- if ref and ref .startswith ("v" ):
164- return ref [1 :] # 去掉前缀 'v'
165- return ref # 返回原始版本号
160+ def get_latest_tag ():
161+ url = "https://api.github.com/repos/NewFuture/DDNS/tags?per_page=1"
162+ try :
163+ with urllib .request .urlopen (url ) as response :
164+ data = json .load (response )
165+ if data and isinstance (data , list ):
166+ return data [0 ]['name' ] # 获取第一个 tag 的 name
167+ except Exception as e :
168+ print ("Error fetching tag:" , e )
169+ return None
170+
171+
172+ def normalize_tag (tag : str ) -> str :
173+ v = tag .lower ().lstrip ("v" )
174+ v = re .sub (r"-beta(\d*)" , r"b\1" , v )
175+ v = re .sub (r"-alpha(\d*)" , r"a\1" , v )
176+ v = re .sub (r"-rc(\d*)" , r"rc\1" , v )
177+ return v
178+
179+
180+ def ten_minute_bucket_id ():
181+ epoch_minutes = int (time .time () // 60 ) # 当前时间(分钟级)
182+ bucket = epoch_minutes // 10 # 每10分钟为一个 bucket
183+ return bucket % 65536 # 限制在 0~65535 (2**16)
184+
185+
186+ def generate_version ():
187+ ref = os .environ .get ('GITHUB_REF_NAME' , '' )
188+ if re .match (r"^v\d+\.\d+" , ref ):
189+ return normalize_tag (ref )
190+
191+ base = "4.0.0"
192+ suffix = ten_minute_bucket_id ()
193+ if ref == "master" or ref == "main" :
194+ tag = get_latest_tag ()
195+ if tag :
196+ base = normalize_tag (tag )
197+
198+ return f"{ base } .dev{ suffix } "
199+
200+
201+ def replace_version_and_date (pyfile : str , version : str , date_str : str ):
202+ with open (pyfile , 'r' , encoding = "utf-8" ) as f :
203+ text = f .read ()
204+ text = text .replace ("${BUILD_VERSION}" , version )
205+ text = text .replace ("${BUILD_DATE}" , date_str )
206+ if text is not None :
207+ with open (pyfile , 'w' , encoding = "utf-8" ) as f :
208+ f .write (text )
209+ print (f"Updated { pyfile } : version={ version } , date={ date_str } " )
210+ else :
211+ exit (1 )
166212
167213
168214def main ():
169215 """
170216 遍历所有py文件并替换兼容导入,同时更新nuitka版本号
171217 """
218+ if len (sys .argv ) > 1 and sys .argv [1 ].lower () != 'version' :
219+ print (f'unknown arguments: { sys .argv } ' )
220+ exit (1 )
221+ version = generate_version ()
222+ date_str = datetime .now (timezone .utc ).replace (microsecond = 0 ).isoformat ().replace ("+00:00" , "Z" )
223+ print (f"Version: { version } " )
224+ print (f"Date: { date_str } " )
225+
226+ # 修改__init__.py 中的 __version__
227+ replace_version_and_date (init_py_path , version , date_str )
228+ if len (sys .argv ) > 1 and sys .argv [1 ].lower () == 'version' :
229+ # python version only
230+ exit (0 )
231+
172232 run_py_path = os .path .join (ROOT , "run.py" )
173- version = extract_version_from_env ()
174233 update_nuitka_version (run_py_path , version )
175234 add_nuitka_file_description (run_py_path )
176235 add_nuitka_include_modules (run_py_path )
177236
178- # 修改__init__.py 中的 __version__
179-
180- replace_version_in_init (version , init_py_path )
181-
182237 changed_files = 0
183238 for dirpath , _ , filenames in os .walk (ROOT ):
184239 for fname in filenames :
@@ -190,21 +245,5 @@ def main():
190245 print (f"Total processed files: { changed_files } " )
191246
192247
193- def replace_version_in_init (version , init_py_path ):
194- """
195- 替换 ddns/__init__.py 中的 __version__ 变量
196- """
197- version_str = f'v{ version } @{ time .strftime ("%Y-%m-%dT%H:%M:%S" )} '
198- with open (init_py_path , "r" , encoding = "utf-8" ) as f :
199- content = f .read ()
200- new_content = re .sub (
201- r'__version__\s*=\s*[\'"]([^\'"]+)[\'"]' , f'__version__ = "{ version_str } "' , content
202- )
203- if new_content != content :
204- with open (init_py_path , "w" , encoding = "utf-8" ) as f :
205- f .write (new_content )
206- print (f"Updated __version__ in { init_py_path } to { version_str } " )
207-
208-
209248if __name__ == "__main__" :
210249 main ()
0 commit comments