Skip to content

Commit 8e6c7bc

Browse files
authored
Remove unreleased dependency tags when library is shipped (#45427)
Remove unreleased dependency tags when library is shipped
1 parent ca27a20 commit 8e6c7bc

File tree

6 files changed

+86
-52
lines changed

6 files changed

+86
-52
lines changed

eng/versioning/set_versions.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def set_dev_zero_version(build_type, build_qualifier):
9090
newlines.append(module.string_for_version_file())
9191
continue
9292

93-
if hasattr(module, 'current'):
93+
if module.current != None:
9494

9595
if 'alpha' in module.current:
9696
newlines.append(module.string_for_version_file())
@@ -143,7 +143,7 @@ def update_versions_file_for_nightly_devops(build_type, build_qualifier, artifac
143143
continue
144144
if library_to_update == module.name:
145145
artifact_found = True
146-
if hasattr(module, 'current'):
146+
if module.current != None:
147147
set_both = False
148148
# In the case where the current and dependency are both equal then both
149149
# need to be updated. In theory, this should only really happen when a
@@ -223,7 +223,7 @@ def prep_version_file_for_source_testing(build_type, project_list):
223223
newlines.append(raw_line)
224224
else:
225225
module = CodeModule(stripped_line)
226-
if hasattr(module, 'current') and not module.current == module.dependency:
226+
if module.current != None and not module.current == module.dependency:
227227
# If the project list is passed in, only prep the versions for from source
228228
# build for those modules. This is the case specifically for patch release.
229229
if project_list_identifiers is not None:
@@ -279,7 +279,7 @@ def increment_or_set_library_version(build_type, artifact_id, group_id, new_vers
279279
# to use based on what has been released to Maven central. If "beta.1"
280280
# exists in Maven central then use "beta.2" and so on.
281281
# https://github.com/Azure/azure-sdk/blob/main/docs/policies/releases.md#java
282-
if module.name == library_to_update and hasattr(module, 'current'):
282+
if module.name == library_to_update and module.current != None:
283283
artifact_found = True
284284
if new_version is None:
285285
vmatch = version_regex_named.match(module.current)
@@ -398,7 +398,7 @@ def verify_current_version_of_artifact(build_type, artifact_id, group_id):
398398
# of the following:
399399
# <major>.<minor>.<patch/hotfix>
400400
# <major>.<minor>.<patch/hotfix>-beta.<prerelease>
401-
if module.name == library_to_update and hasattr(module, 'current'):
401+
if module.name == library_to_update and module.current != None:
402402
artifact_found = True
403403
vmatch = version_regex_named.match(module.current)
404404
temp_ver = '{}.{}.{}'.format(vmatch.group('major'), vmatch.group('minor'), vmatch.group('patch'))

eng/versioning/update_versions.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
import re
3737
import sys
3838
import time
39-
import traceback
39+
from typing import Dict
4040
from utils import BuildType
4141
from utils import CodeModule
4242
from utils import load_version_map_from_file
@@ -53,11 +53,11 @@
5353

5454
exception_list = []
5555

56-
def update_versions(update_type, version_map, ext_dep_map, target_file, skip_readme, auto_version_increment, library_array):
56+
def update_versions(update_type, version_map: Dict[str, CodeModule], ext_dep_map, target_file, skip_readme, auto_version_increment, library_array):
5757

5858
newlines = []
5959
repl_open, repl_thisline, file_changed, is_include = False, False, False, False
60-
print('processing: ' + target_file)
60+
print('processing: ' + os.path.normpath(target_file))
6161
try:
6262
with open(target_file, encoding='utf-8') as f:
6363
for line in f:
@@ -105,8 +105,12 @@ def update_versions(update_type, version_map, ext_dep_map, target_file, skip_rea
105105
elif version_type == 'dependency':
106106
try:
107107
module = version_map[module_name]
108-
new_version = module.dependency
109-
newline = re.sub(version_regex_str_no_anchor, new_version, line)
108+
if module.is_unreleased and module.replace_unreleased_dependency:
109+
to_replace_module = version_map[module.name[len('unreleased_'):]]
110+
newline = re.sub(version_regex_str_no_anchor, to_replace_module.dependency, line)
111+
newline = newline.replace(module.name, to_replace_module.name)
112+
else:
113+
newline = re.sub(version_regex_str_no_anchor, module.dependency, line)
110114
except (KeyError, AttributeError):
111115
# This should never happen unless the version file is malformed
112116
raise ValueError('Module: {0} does not have a dependency version.\nFile={1}\nLine={2}'.format(module_name, target_file, line))
@@ -170,7 +174,7 @@ def update_changelog(pom_file, is_increment, library_array):
170174
xml_groupId = xml_root.find('{http://maven.apache.org/POM/4.0.0}groupId')
171175
library = xml_groupId.text + ":" + xml_artifactId.text
172176
if len(library_array) == 0 or library in library_array:
173-
script = os.path.join(".", "eng", "common", "scripts", "Update-ChangeLog.ps1")
177+
script = os.path.join(os.path.dirname(__file__), '..', "common", "scripts", "Update-ChangeLog.ps1")
174178
commands = [
175179
"pwsh",
176180
script,
@@ -207,23 +211,23 @@ def display_version_info(version_map):
207211
for value in version_map.values():
208212
print(value)
209213

210-
def update_versions_all(update_type, build_type, target_file, skip_readme, auto_version_increment, library_array, version_overrides, include_perf_tests):
211-
version_map = {}
212-
ext_dep_map = {}
214+
def update_versions_all(update_type, build_type, target_file, skip_readme, auto_version_increment: bool, library_array, version_overrides, include_perf_tests):
215+
version_map: Dict[str, CodeModule] = {}
216+
ext_dep_map: Dict[str, CodeModule] = {}
213217
# Load the version and/or external dependency file for the given UpdateType
214218
# into the verion_map. If UpdateType.all is selected then versions for both
215219
# the libraries and external dependencies are being updated.
216220
if update_type == UpdateType.library or update_type == UpdateType.all:
217-
version_file = os.path.normpath('eng/versioning/version_' + build_type.name + '.txt')
218-
load_version_map_from_file(version_file, version_map)
221+
version_file = os.path.join(os.path.dirname(__file__), 'version_' + build_type.name + '.txt')
222+
load_version_map_from_file(version_file, version_map, auto_version_increment)
219223

220224
if update_type == UpdateType.external_dependency or update_type == UpdateType.all:
221-
dependency_file = os.path.normpath('eng/versioning/external_dependencies.txt')
225+
dependency_file = os.path.join(os.path.dirname(__file__), 'external_dependencies.txt')
222226
load_version_map_from_file(dependency_file, ext_dep_map)
223227

224228
if version_overrides and not version_overrides.startswith('$'):
225229
# Azure DevOps passes '$(VersionOverrides)' when the variable value is not set
226-
load_version_overrides("eng/versioning/supported_external_dependency_versions.json", ext_dep_map, version_overrides)
230+
load_version_overrides(os.path.join(os.path.dirname(__file__), 'supported_external_dependency_versions.json'), ext_dep_map, version_overrides)
227231

228232
# The dependency files are always loaded but reporting their information is based on the update type.
229233
if update_type == UpdateType.library or update_type == UpdateType.all:
@@ -237,7 +241,7 @@ def update_versions_all(update_type, build_type, target_file, skip_readme, auto_
237241
if target_file:
238242
update_versions(update_type, version_map, ext_dep_map, target_file, skip_readme, auto_version_increment, library_array)
239243
else:
240-
for root, _, files in os.walk("."):
244+
for root, _, files in os.walk(os.path.join(os.path.dirname(__file__), '..', '..')):
241245
for file_name in files:
242246
file_path = root + os.sep + file_name
243247
if (file_name.endswith('.md') and not skip_readme) or (file_name.startswith('pom') and file_name.endswith('.xml')):
@@ -254,7 +258,7 @@ def update_versions_all(update_type, build_type, target_file, skip_readme, auto_
254258
if not target_file and BuildType.none != build_type:
255259
# the good thing here is that the java files only contain library versions, not
256260
# external versions
257-
version_java_file = os.path.normpath('eng/versioning/version_' + build_type.name + '_java_files.txt')
261+
version_java_file = os.path.join(os.path.dirname(__file__), 'version_' + build_type.name + '_java_files.txt')
258262

259263
if os.path.exists(version_java_file):
260264
with open(version_java_file) as f:

eng/versioning/utils.py

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from enum import Enum
88
import re
9+
from typing import Dict
910
from subprocess import check_call, CalledProcessError
1011

1112
include_update_marker = re.compile(r'\{x-include-update;([^;]+);([^}]+)\}')
@@ -65,6 +66,17 @@ def __str__(self):
6566
return self.value
6667

6768
class CodeModule:
69+
name: str
70+
group_id: str
71+
artifact_id: str
72+
dependency: str
73+
current: str = None # current version is optional, only for library versions
74+
external_dependency: str = None # external dependency version is optional, only for external dependencies
75+
update_type: UpdateType
76+
is_beta: bool = False # beta_ is a prefix for unreleased dependencies, may not exist
77+
is_unreleased: bool = False # unreleased_ is a prefix for unreleased dependencies, may not exist
78+
replace_unreleased_dependency: bool = False # used to indicate that the unreleased dependency should be replaced with the dependency version
79+
6880
def __init__(self, module_str):
6981
# For library versions there will be up to 3 items resulting from the split
7082
# which will be module name, dependency version and current version. For
@@ -77,7 +89,9 @@ def __init__(self, module_str):
7789
self.artifact_id = items[0].split(':')[1]
7890

7991
if len(items) == 2:
80-
if self.group_id.startswith('unreleased_') or self.group_id.startswith('beta_'):
92+
self.is_beta = self.group_id.startswith('beta_')
93+
self.is_unreleased = self.group_id.startswith('unreleased_')
94+
if self.is_beta or self.is_unreleased:
8195
self.dependency = items[1].strip()
8296
self.update_type = UpdateType.library
8397
else:
@@ -95,18 +109,18 @@ def __init__(self, module_str):
95109
# overridden string primarily used for error reporting
96110
def __str__(self):
97111
# current may or may not exist
98-
if hasattr(self, 'external_dependency'):
112+
if self.external_dependency != None:
99113
return self.name + ': External Dependency version=' + self.external_dependency
100-
try:
114+
if self.current != None:
101115
return self.name + ': Dependency version=' + self.dependency + ': Current version=' + self.current
102-
except AttributeError:
116+
else:
103117
return self.name + ': Dependency version=' + self.dependency
104118

105119
# return the CodeModule string formatted for a version file
106120
def string_for_version_file(self):
107-
try:
121+
if self.current != None:
108122
return self.name + ';' + self.dependency + ';' + self.current + '\n'
109-
except AttributeError:
123+
else:
110124
return self.name + ';' + self.dependency + '\n'
111125

112126
# return the CodeModule string formatted for a allowlist include entry
@@ -115,7 +129,7 @@ def string_for_version_file(self):
115129
# would be treated as that version and above. For example:
116130
# <groupId>:<artifactId>:1.2 would be treated as 1.2 and above or equivalent to [1.2,)
117131
def string_for_allowlist_include(self):
118-
if hasattr(self, 'external_dependency'):
132+
if self.external_dependency != None:
119133
temp = self.name
120134
# This is necessary to deal with the fact that external_dependencies can have
121135
# '_' in them if they're an external dependency exception. Since the allowlist
@@ -159,25 +173,53 @@ def run_check_call(
159173
return err
160174

161175

162-
def load_version_map_from_file(the_file, version_map):
176+
def load_version_map_from_file(the_file, version_map: Dict[str, CodeModule], auto_increment_version=False):
177+
newlines = []
178+
file_changed = False
163179
with open(the_file) as f:
164180
for raw_line in f:
165181
stripped_line = raw_line.strip()
166182
if not stripped_line or stripped_line.startswith('#'):
183+
newlines.append(raw_line)
167184
continue
168185
module = CodeModule(stripped_line)
169186
# verify no duplicate entries
170187
if (module.name in version_map):
171188
raise ValueError('Version file: {0} contains a duplicate entry: {1}'.format(the_file, module.name))
172189
# verify that if the module is beta_ or unreleased_ that there's a matching non-beta_ or non-unreleased_ entry
173-
if (module.name.startswith('beta_') or module.name.startswith('unreleased_')):
190+
is_beta = module.name.startswith('beta_')
191+
is_unreleased = module.name.startswith('unreleased_')
192+
if (is_beta or is_unreleased):
174193
tempName = module.name
175-
if tempName.startswith('beta_'):
194+
if is_beta:
176195
tempName = module.name[len('beta_'):]
177196
else:
178197
tempName = module.name[len('unreleased_'):]
179198
# if there isn't a non beta or unreleased entry then raise an issue
180199
if tempName not in version_map:
181200
raise ValueError('Version file: {0} does not contain a non-beta or non-unreleased entry for beta_/unreleased_ library: {1}'.format(the_file, module.name))
201+
202+
# Unreleased dependencies have a few additional checks.
203+
# 1. If 'auto_increment_version' is true, check if the version matches the dependency version of the library.
204+
# If the unreleased dependency version is the same as the dependency version, flag the unreleased dependency for replacement.
205+
# This flag will indicate to the update script that the 'unreleased_*' tag should be replaced with just '*', ex 'unreleased_core' -> 'core'.
206+
# 2. Check to see that the version matches the current version of the library.
207+
# If it isn't raise an error as unreleased dependencies should match the current version of the library.
208+
if is_unreleased:
209+
non_unreleased_module = version_map[tempName]
210+
if auto_increment_version and module.dependency == non_unreleased_module.dependency:
211+
module.replace_unreleased_dependency = True
212+
file_changed = True
213+
elif module.dependency != non_unreleased_module.current:
214+
raise ValueError('Version file: {0} contains an unreleased dependency: {1} with a dependency version of {2} which does not match the current version of the library it represents: {3}'.format(the_file, module.name, module.dependency, version_map[tempName].current))
215+
216+
if not module.replace_unreleased_dependency:
217+
newlines.append(raw_line)
218+
182219
version_map[module.name] = module
220+
221+
if file_changed:
222+
with open(the_file, 'w', encoding='utf-8') as f:
223+
for line in newlines:
224+
f.write(line)
183225

sdk/appconfiguration/azure-data-appconfiguration-v2/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,14 @@ Code generated by Microsoft (R) TypeSpec Code Generator.
5656
<dependency>
5757
<groupId>com.azure.v2</groupId>
5858
<artifactId>azure-core</artifactId>
59-
<version>2.0.0-beta.1</version> <!-- {x-version-update;com.azure.v2:azure-core;dependency} -->
59+
<version>2.0.0-beta.1</version> <!-- {x-version-update;unreleased_com.azure.v2:azure-core;dependency} -->
6060
</dependency>
6161

6262
<!-- Test scope -->
6363
<dependency>
6464
<groupId>com.azure.v2</groupId>
6565
<artifactId>azure-identity</artifactId>
66-
<version>2.0.0-beta.1</version> <!-- {x-version-update;com.azure.v2:azure-identity;dependency} -->
66+
<version>2.0.0-beta.1</version> <!-- {x-version-update;unreleased_com.azure.v2:azure-identity;dependency} -->
6767
<scope>test</scope>
6868
</dependency>
6969

sdk/identity-v2/pom.xml

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,15 @@
1-
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
21
<!-- Copyright (c) Microsoft Corporation. All rights reserved.
32
Licensed under the MIT License. -->
4-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5-
3+
<project xmlns="http://maven.apache.org/POM/4.0.0"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
66
<modelVersion>4.0.0</modelVersion>
7-
87
<groupId>com.azure.v2</groupId>
9-
108
<artifactId>azure-identity-v2-service</artifactId>
11-
129
<packaging>pom</packaging>
13-
14-
<version>1.0.0</version>
15-
<!-- Need not change for every release-->
10+
<version>1.0.0</version> <!-- Need not change for every release-->
1611

1712
<modules>
1813
<module>azure-identity</module>
1914
</modules>
20-
2115
</project>

sdk/identity/pom.xml

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
1-
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
21
<!-- Copyright (c) Microsoft Corporation. All rights reserved.
32
Licensed under the MIT License. -->
4-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5-
3+
<project xmlns="http://maven.apache.org/POM/4.0.0"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
66
<modelVersion>4.0.0</modelVersion>
7-
87
<groupId>com.azure</groupId>
9-
108
<artifactId>azure-identity-service</artifactId>
11-
129
<packaging>pom</packaging>
13-
14-
<version>1.0.0</version>
15-
<!-- Need not change for every release-->
10+
<version>1.0.0</version> <!-- Need not change for every release-->
1611

1712
<modules>
1813
<module>azure-identity</module>
@@ -21,5 +16,4 @@
2116
<module>azure-identity-broker</module>
2217
<module>azure-identity-broker-samples</module>
2318
</modules>
24-
2519
</project>

0 commit comments

Comments
 (0)