Skip to content

Commit 5b3ab06

Browse files
authored
Merge branch 'main' into vijay/session-process-case-sensitivity-fix
2 parents f49bbba + 822df77 commit 5b3ab06

36 files changed

Lines changed: 1275 additions & 484 deletions

eng/automation/generate.py

Lines changed: 71 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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

293344
def 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:

eng/automation/generate_utils.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,6 @@ def generate_typespec_project(
532532
remove_before_regen: bool = False,
533533
group_id: str = None,
534534
api_version: str = None,
535-
generate_beta_sdk: bool = True,
536535
version: str = None, # SDK version
537536
disable_customization: bool = False,
538537
**kwargs,
@@ -610,10 +609,6 @@ def generate_typespec_project(
610609

611610
if remove_before_regen and group_id:
612611
remove_generated_source_code(os.path.join(sdk_root, sdk_folder), f"{group_id}.{service}")
613-
_, current_version = set_or_increase_version(
614-
sdk_root, group_id, module, version=version, preview=generate_beta_sdk
615-
)
616-
emitter_options.append(f"package-version={current_version}")
617612
if api_version:
618613
emitter_options.append(f"api-version={api_version}")
619614

eng/automation/test_generate.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import os
2+
import tempfile
3+
import unittest
4+
5+
from generate import update_revapi_skip
6+
7+
POM_WITH_REVAPI_TRUE = """\
8+
<project>
9+
<properties>
10+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
11+
<jacoco.min.linecoverage>0</jacoco.min.linecoverage>
12+
<revapi.skip>true</revapi.skip>
13+
</properties>
14+
</project>
15+
"""
16+
17+
POM_WITH_REVAPI_FALSE = """\
18+
<project>
19+
<properties>
20+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
21+
<jacoco.min.linecoverage>0</jacoco.min.linecoverage>
22+
<revapi.skip>false</revapi.skip>
23+
</properties>
24+
</project>
25+
"""
26+
27+
POM_WITHOUT_REVAPI = """\
28+
<project>
29+
<properties>
30+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
31+
<jacoco.min.linecoverage>0</jacoco.min.linecoverage>
32+
</properties>
33+
</project>
34+
"""
35+
36+
37+
class TestUpdateRevapiSkip(unittest.TestCase):
38+
39+
def _write_and_update(self, content: str, beta: bool) -> str:
40+
fd, path = tempfile.mkstemp(suffix=".xml")
41+
try:
42+
with os.fdopen(fd, "w") as f:
43+
f.write(content)
44+
update_revapi_skip(path, beta)
45+
with open(path, "r") as f:
46+
return f.read()
47+
finally:
48+
os.unlink(path)
49+
50+
# --- beta=True cases ---
51+
52+
def test_beta_already_true_no_change(self):
53+
result = self._write_and_update(POM_WITH_REVAPI_TRUE, beta=True)
54+
self.assertEqual(result, POM_WITH_REVAPI_TRUE)
55+
56+
def test_beta_false_flipped_to_true(self):
57+
result = self._write_and_update(POM_WITH_REVAPI_FALSE, beta=True)
58+
self.assertIn("<revapi.skip>true</revapi.skip>", result)
59+
self.assertNotIn("<revapi.skip>false</revapi.skip>", result)
60+
61+
def test_beta_missing_added_true(self):
62+
result = self._write_and_update(POM_WITHOUT_REVAPI, beta=True)
63+
self.assertIn("<revapi.skip>true</revapi.skip>", result)
64+
self.assertIn("</properties>", result)
65+
66+
# --- beta=False (stable) cases ---
67+
68+
def test_stable_true_flipped_to_false(self):
69+
result = self._write_and_update(POM_WITH_REVAPI_TRUE, beta=False)
70+
self.assertIn("<revapi.skip>false</revapi.skip>", result)
71+
self.assertNotIn("<revapi.skip>true</revapi.skip>", result)
72+
73+
def test_stable_already_false_no_change(self):
74+
result = self._write_and_update(POM_WITH_REVAPI_FALSE, beta=False)
75+
self.assertEqual(result, POM_WITH_REVAPI_FALSE)
76+
77+
def test_stable_missing_not_added(self):
78+
result = self._write_and_update(POM_WITHOUT_REVAPI, beta=False)
79+
self.assertNotIn("revapi.skip", result)
80+
self.assertEqual(result, POM_WITHOUT_REVAPI)
81+
82+
83+
if __name__ == "__main__":
84+
unittest.main()

0 commit comments

Comments
 (0)