@@ -277,17 +277,68 @@ def sdk_automation_typespec(config: dict) -> List[dict]:
277277 return packages
278278
279279
280- def verify_self_serve_parameters (api_version , sdk_release_type ):
281- if sdk_release_type and sdk_release_type not in ["stable" , "beta" ]:
282- raise ValueError (f"Invalid SDK release type [{ sdk_release_type } ], only support 'stable' or 'beta'." )
283- if api_version and sdk_release_type :
284- if api_version .endswith ("-preview" ) and sdk_release_type == "stable" :
285- raise ValueError (f"SDK release type is [stable], but API version [{ api_version } ] is preview." )
286- logging .info (f"[SelfServe] Generate with apiVersion: { api_version } and sdkReleaseType: { sdk_release_type } " )
287- elif api_version or sdk_release_type :
288- raise ValueError (
289- "Both [API version] and [SDK release type] parameters are required for self-serve SDK generation."
290- )
280+ def infer_sdk_release_type (sdk_root : str , sdk_folder : str , module : str ) -> str :
281+ """Infer SDK release type from the generated metadata JSON.
282+
283+ Reads {sdk_root}/{sdk_folder}/src/main/resources/META-INF/{module}_metadata.json
284+ and inspects the apiVersions values:
285+ - All GA (no 'preview' substring) -> 'stable'
286+ - Any preview or mixed -> 'beta'
287+ - Fallback on error -> 'beta' (safe default)
288+ """
289+ metadata_path = os .path .join (sdk_root , sdk_folder , "src" , "main" , "resources" , "META-INF" , f"{ module } _metadata.json" )
290+ try :
291+ with open (metadata_path , "r" ) as f :
292+ metadata = json .load (f )
293+ api_versions = metadata .get ("apiVersions" , {})
294+ if not api_versions :
295+ logging .warning (f"[SelfServe] No apiVersions found in { metadata_path } , defaulting to beta." )
296+ return "beta"
297+
298+ has_preview = any ("preview" in v .lower () for v in api_versions .values ())
299+ inferred = "beta" if has_preview else "stable"
300+ logging .info (f"[SelfServe] Inferred sdkReleaseType={ inferred } from apiVersions: { api_versions } " )
301+ return inferred
302+ except FileNotFoundError :
303+ logging .warning (f"[SelfServe] Metadata file not found: { metadata_path } , defaulting to beta." )
304+ return "beta"
305+ except Exception as e :
306+ logging .warning (f"[SelfServe] Failed to read metadata file { metadata_path } : { e } , defaulting to beta." )
307+ return "beta"
308+
309+
310+ def update_revapi_skip (pom_path : str , beta : bool ):
311+ """Update revapi.skip property in pom.xml based on release type.
312+
313+ beta=True: ensure <revapi.skip>true</revapi.skip> (add if missing, flip if false)
314+ beta=False: flip <revapi.skip>true</revapi.skip> to false if present (skip if absent, as false is default)
315+ """
316+ try :
317+ with open (pom_path , "r" ) as f :
318+ content = f .read ()
319+ if beta :
320+ if "<revapi.skip>true</revapi.skip>" in content :
321+ return
322+ if "<revapi.skip>false</revapi.skip>" in content :
323+ new_content = content .replace ("<revapi.skip>false</revapi.skip>" , "<revapi.skip>true</revapi.skip>" )
324+ logging .info (f"[SelfServe] Changed revapi.skip to true in { pom_path } " )
325+ else :
326+ new_content = re .sub (
327+ r'([ \t]*)</properties>' ,
328+ r'\1 <revapi.skip>true</revapi.skip>\n\1</properties>' ,
329+ content ,
330+ count = 1 ,
331+ )
332+ logging .info (f"[SelfServe] Added revapi.skip=true to { pom_path } " )
333+ else :
334+ if "<revapi.skip>true</revapi.skip>" not in content :
335+ return
336+ new_content = content .replace ("<revapi.skip>true</revapi.skip>" , "<revapi.skip>false</revapi.skip>" )
337+ logging .info (f"[SelfServe] Changed revapi.skip to false in { pom_path } " )
338+ with open (pom_path , "w" ) as f :
339+ f .write (new_content )
340+ except Exception as e :
341+ logging .warning (f"[SelfServe] Failed to update revapi.skip in { pom_path } : { e } " )
291342
292343
293344def sdk_automation_typespec_project (tsp_project : str , config : dict ) -> dict :
@@ -299,14 +350,11 @@ def sdk_automation_typespec_project(tsp_project: str, config: dict) -> dict:
299350 repo_url : str = config ["repoHttpsUrl" ]
300351 sdk_release_type : str = config ["sdkReleaseType" ] if "sdkReleaseType" in config else None
301352 api_version = config ["apiVersion" ] if "apiVersion" in config else None
353+ # Generate with beta by default; will be corrected after inference if needed
302354 release_beta_sdk : bool = not sdk_release_type or sdk_release_type == "beta"
303355 breaking : bool = False
304356 changelog = ""
305357 breaking_change_items = []
306- run_mode : str = config ["runMode" ] if "runMode" in config else None
307-
308- if run_mode == "release" or run_mode == "local" :
309- verify_self_serve_parameters (api_version , sdk_release_type )
310358
311359 succeeded , require_sdk_integration , sdk_folder , service , module = generate_typespec_project (
312360 tsp_project ,
@@ -317,10 +365,14 @@ def sdk_automation_typespec_project(tsp_project: str, config: dict) -> dict:
317365 remove_before_regen = True ,
318366 group_id = GROUP_ID ,
319367 api_version = api_version ,
320- generate_beta_sdk = release_beta_sdk ,
321368 )
322369
323370 if succeeded :
371+ # Infer sdk release type from generated metadata when not explicitly provided
372+ if not sdk_release_type and sdk_folder and module :
373+ inferred_type = infer_sdk_release_type (sdk_root , sdk_folder , module )
374+ release_beta_sdk = inferred_type == "beta"
375+
324376 # TODO (weidxu): move to typespec-java
325377 if require_sdk_integration :
326378 update_service_files_for_new_lib (sdk_root , service , GROUP_ID , module )
@@ -332,6 +384,9 @@ def sdk_automation_typespec_project(tsp_project: str, config: dict) -> dict:
332384 output_folder = sdk_folder
333385 update_version (sdk_root , output_folder )
334386
387+ # Update revapi.skip based on release type
388+ update_revapi_skip (os .path .join (sdk_root , output_folder , "pom.xml" ), beta = release_beta_sdk )
389+
335390 # compile
336391 succeeded = compile_arm_package (sdk_root , module )
337392 if succeeded :
0 commit comments