Skip to content

Commit d9e2031

Browse files
Use standardizedVersioning from vscode-engineering for pre-release version numbers (#1441)
## Summary This PR stops `update_ext_version.py` from overriding the pre-release version number and instead lets the `vscode-engineering` shared pipeline template handle it via the `standardizedVersioning` flag (which was already enabled but being overriden). ## Why change the versioning? ### Problem 1: Poor readability The old pre-release version format was `1.27.10931010`, computed as `1` + Julian day (`093`) + hour (`10`) + minute (`10`). Looking at `1.27.10931010`, there's no easy way to tell *when* it was built. You'd have to reverse-engineer the Julian day and time to figure out it means "April 3, 10:10 AM UTC". ### Problem 2: Different platforms got different version numbers The pre-release pipeline builds 10 platform-specific packages (win32-x64, darwin-arm64, linux-x64, etc.) in parallel. Each platform ran `update_ext_version.py` independently, and because the script uses the current time (down to the minute), each platform ended up with a slightly different version: ``` 1.27.10931008 ← linux-x64 finished at 10:08 1.27.10931009 ← darwin-arm64 finished at 10:09 1.27.10931010 ← win32-x64 finished at 10:10 ``` In VS Code, users only see their own platform's version, so this wasn't visually obvious — but the Marketplace version history showed multiple entries per day, which was confusing. For example, marketplace shows <img width="858" height="582" alt="image" src="https://github.com/user-attachments/assets/d7790618-0ce7-4ee9-b885-e63ca47264ce" /> while vscode shows <img width="625" height="144" alt="image" src="https://github.com/user-attachments/assets/2c9450cd-92b2-4c75-a882-2f777a32291d" /> ## What does `standardizedVersioning` do? The flag is already set in our pre-release pipeline (`azure-pipeline.pre-release.yml` line 32): ```yaml standardizedVersioning: true ``` When this flag is `true` and it's a pre-release build, the `vscode-engineering` template runs a step called `modify-extension-version.yml` **before** our `buildSteps`. See https://github.com/microsoft/vscode-engineering/blob/main/azure-pipelines/extension/templates/steps/modify-extension-version.yml for what it does. This runs **once per platform job**, but `$(Build.BuildNumber)` is the **same for all jobs** in a pipeline run, so every platform gets the identical version. ### Example versions under the new scheme | Scenario | Version | |---|---| | First build on April 6, 2026 | `1.27.2026040601` | | Second build same day (manual re-trigger) | `1.27.2026040602` | | Build on April 7 | `1.27.2026040701` | ### Why this is better - **Readable** — `1.27.2026040601` clearly means "April 6, 2026, build 1" - **Consistent** — all 10 platforms share the exact same version - **Same-day safe** — the `.Rev` suffix from Azure DevOps handles re-triggers - **Always increasing** — `2026040601` > `13652359` (old max), so new versions always sort ahead of old ones on the Marketplace - **Within Marketplace limits** — max possible value ~`2099123199` ≈ 2.1 billion, well under the uint32 max of ~4.3 billion ## What changed in the code? ### `build/update_ext_version.py` - Added an **early return** for the pre-release case (no `--release`, no `--build-id`). The script now validates the even/odd minor version rule and strips any `-dev`/`-rc` suffix if `--for-publishing`, but **does not overwrite the version** set by the template. - Removed the `else` branch that called `micro_build_number()` — this was the code that was clobbering the template's version. - The `--release` and `--build-id` code paths are **completely unchanged**. ### `build/azure-pipeline.pre-release.yml` - Renamed the step display name from "Update build number" to "Validate version number" to reflect what it actually does now. ### `build/test_update_ext_version.py` - Updated test expectations: the no-args and `--for-publishing` (without `--release` or `--build-id`) cases now expect the original micro version to be preserved instead of being replaced with a computed timestamp. - Removed the unused `EXPECTED_BUILD_ID` constant. ## Stable releases are not affected The stable pipeline (`azure-pipeline.stable.yml`) does not use `standardizedVersioning` and continues to call `update_ext_version.py --release --for-publishing`, which is unchanged.
1 parent 76c2430 commit d9e2031

3 files changed

Lines changed: 16 additions & 11 deletions

File tree

build/azure-pipeline.pre-release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ extends:
8383
displayName: Update telemetry in package.json
8484

8585
- script: python ./build/update_ext_version.py --for-publishing
86-
displayName: Update build number
86+
displayName: Validate version number
8787

8888
- bash: |
8989
mkdir -p $(Build.SourcesDirectory)/python-env-tools/bin

build/test_update_ext_version.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,6 @@
99

1010
TEST_DATETIME = "2022-03-14 01:23:45"
1111

12-
# The build ID is calculated via:
13-
# "1" + datetime.datetime.strptime(TEST_DATETIME,"%Y-%m-%d %H:%M:%S").strftime('%j%H%M')
14-
EXPECTED_BUILD_ID = "10730123"
15-
1612

1713
def create_package_json(directory, version):
1814
"""Create `package.json` in `directory` with a specified version of `version`."""
@@ -71,7 +67,7 @@ def test_invalid_args(tmp_path, version, args):
7167
["--build-id", "999999999999"],
7268
("1", "1", "999999999999", "rc"),
7369
),
74-
("1.1.0-rc", [], ("1", "1", EXPECTED_BUILD_ID, "rc")),
70+
("1.1.0-rc", [], ("1", "1", "0", "rc")),
7571
(
7672
"1.0.0-rc",
7773
["--release"],
@@ -80,7 +76,7 @@ def test_invalid_args(tmp_path, version, args):
8076
(
8177
"1.1.0-rc",
8278
["--for-publishing"],
83-
("1", "1", EXPECTED_BUILD_ID, ""),
79+
("1", "1", "0", ""),
8480
),
8581
(
8682
"1.0.0-rc",
@@ -95,7 +91,7 @@ def test_invalid_args(tmp_path, version, args):
9591
(
9692
"1.1.0-rc",
9793
[],
98-
("1", "1", EXPECTED_BUILD_ID, "rc"),
94+
("1", "1", "0", "rc"),
9995
),
10096
],
10197
)

build/update_ext_version.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,18 @@ def main(package_json: pathlib.Path, argv: Sequence[str]) -> None:
7979
)
8080

8181
print(f"Updating build FROM: {package['version']}")
82+
83+
# Pre-release without --build-id: version is managed by the CI template
84+
# (standardizedVersioning). Just strip suffix if publishing.
85+
if not args.release and not args.build_id:
86+
if args.for_publishing and len(suffix):
87+
package["version"] = ".".join((major, minor, micro))
88+
print(f"Updating build TO: {package['version']}")
89+
package_json.write_text(
90+
json.dumps(package, indent=4, ensure_ascii=False) + "\n", encoding="utf-8"
91+
)
92+
return
93+
8294
if args.build_id:
8395
# If build id is provided it should fall within the 0-INT32 max range
8496
# that the max allowed value for publishing to the Marketplace.
@@ -88,9 +100,6 @@ def main(package_json: pathlib.Path, argv: Sequence[str]) -> None:
88100
package["version"] = ".".join((major, minor, str(args.build_id)))
89101
elif args.release:
90102
package["version"] = ".".join((major, minor, micro))
91-
else:
92-
# micro version only updated for pre-release.
93-
package["version"] = ".".join((major, minor, micro_build_number()))
94103

95104
if not args.for_publishing and not args.release and len(suffix):
96105
package["version"] += "-" + suffix

0 commit comments

Comments
 (0)