Skip to content

Commit 5c613bf

Browse files
committed
ci: gate and verify testing image release
1 parent a7ee0a9 commit 5c613bf

6 files changed

Lines changed: 473 additions & 40 deletions

File tree

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/usr/bin/env python3
2+
# SPDX-FileCopyrightText: 2025-present Amazon.com, Inc. or its affiliates.
3+
#
4+
# SPDX-License-Identifier: Apache-2.0
5+
from __future__ import annotations
6+
7+
import argparse
8+
9+
from packaging.version import InvalidVersion, Version
10+
11+
12+
def is_newest(candidate: str, existing_tags: list[str]) -> bool:
13+
"""True if candidate is >= every v<semver> tag in existing_tags.
14+
15+
Non-version tags (latest, malformed) are ignored. With no existing
16+
version tags the candidate is newest by default.
17+
"""
18+
candidate_version = Version(candidate)
19+
highest = candidate_version
20+
for tag in existing_tags:
21+
if not tag.startswith("v"):
22+
continue
23+
try:
24+
version = Version(tag[1:])
25+
except InvalidVersion:
26+
continue
27+
if version > highest:
28+
highest = version
29+
return candidate_version >= highest
30+
31+
32+
def main(argv: list[str] | None = None) -> int:
33+
parser = argparse.ArgumentParser(
34+
description="Decide whether a release version is the newest published."
35+
)
36+
parser.add_argument("--candidate", required=True)
37+
parser.add_argument(
38+
"tags", nargs="*", help="Existing image tags, e.g. v1.2.1 v2.0.0 latest"
39+
)
40+
args = parser.parse_args(argv)
41+
42+
print("true" if is_newest(args.candidate, args.tags) else "false")
43+
return 0
44+
45+
46+
if __name__ == "__main__":
47+
raise SystemExit(main())
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/usr/bin/env python3
2+
# SPDX-FileCopyrightText: 2025-present Amazon.com, Inc. or its affiliates.
3+
#
4+
# SPDX-License-Identifier: Apache-2.0
5+
from __future__ import annotations
6+
7+
import os
8+
import re
9+
10+
# A release-tag component naming the testing package: testing-v<x.y.z> with an
11+
# optional pre-release suffix. Anchored and matched against a single comma-split
12+
# component so prefixes like "mytesting-v1.2.1" are rejected.
13+
_COMPONENT = re.compile(r"testing-v([0-9]+\.[0-9]+\.[0-9]+[0-9A-Za-z.-]*)\Z")
14+
15+
16+
def parse_testing_version(release_tag: str) -> str:
17+
"""Return the testing version named by the release tag, or empty if none."""
18+
for part in release_tag.split(","):
19+
match = _COMPONENT.fullmatch(part.strip())
20+
if match:
21+
return match.group(1)
22+
return ""
23+
24+
25+
def main():
26+
release_tag = os.environ.get("RELEASE_TAG", "")
27+
tag_version = parse_testing_version(release_tag)
28+
29+
github_output = os.environ.get("GITHUB_OUTPUT")
30+
if github_output:
31+
with open(github_output, "a", encoding="utf-8") as f:
32+
f.write(f"tag_version={tag_version}\n")
33+
34+
print(tag_version)
35+
36+
37+
if __name__ == "__main__":
38+
main()
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#!/usr/bin/env python3
2+
# SPDX-FileCopyrightText: 2025-present Amazon.com, Inc. or its affiliates.
3+
#
4+
# SPDX-License-Identifier: Apache-2.0
5+
import os
6+
import sys
7+
8+
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
9+
10+
from is_newest_testing_version import is_newest
11+
12+
13+
def test_is_newest():
14+
test_cases = [
15+
# Newest so far
16+
("2.0.0", ["v1.2.1", "v1.1.3", "latest"], True),
17+
# First ever release
18+
("1.0.0", [], True),
19+
("1.0.0", ["latest"], True),
20+
# Equal to the highest counts as newest (idempotent re-publish)
21+
("2.0.0", ["v2.0.0", "latest"], True),
22+
# Backport below the highest is NOT newest
23+
("1.1.3", ["v1.2.1", "v2.0.0", "latest"], False),
24+
("1.9.9", ["v2.0.0"], False),
25+
# Malformed and non-version tags are ignored
26+
("2.0.1", ["v2.0.0", "notaversion", "latest", "v"], True),
27+
# Pre-release ordering
28+
("2.0.0", ["v2.0.0rc1"], True),
29+
("2.0.0rc1", ["v2.0.0"], False),
30+
]
31+
32+
for candidate, tags, expected in test_cases:
33+
result = is_newest(candidate, tags)
34+
# Assert is expected in test functions
35+
assert result == expected, ( # noqa: S101
36+
f"Expected {expected} but got {result} for {candidate} against {tags}"
37+
)
38+
39+
40+
if __name__ == "__main__":
41+
test_is_newest()
42+
sys.exit(0)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/usr/bin/env python3
2+
3+
import os
4+
import sys
5+
6+
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
7+
8+
from parse_testing_version import parse_testing_version
9+
10+
11+
def test_parse_testing_version():
12+
test_cases = [
13+
# Testing-only tag enables the job
14+
("testing-v2.0.0", "2.0.0"),
15+
("testing-v1.2.1", "1.2.1"),
16+
# Combined comma-separated tags resolve to the testing version
17+
("sdk-v2.0.0,testing-v2.0.0", "2.0.0"),
18+
("testing-v2.0.0,sdk-v2.1.0", "2.0.0"),
19+
("otel-v1.0.0,testing-v1.2.1,sdk-v2.0.0", "1.2.1"),
20+
# SDK-only or OTel-only tags do not enable the job
21+
("sdk-v2.1.0", ""),
22+
("otel-v1.0.0", ""),
23+
("sdk-v2.0.0,otel-v1.0.0", ""),
24+
# Malformed or unrelated prefixes must not match
25+
("not-testing-v1.2.1", ""),
26+
("sdk-v2.0.0,mytesting-v1.2.1", ""),
27+
("testing-v1.2", ""),
28+
("testing-version-1.2.1", ""),
29+
# No release tag
30+
("", ""),
31+
("v2.0.0", ""),
32+
("random-text", ""),
33+
# Pre-release suffix is kept
34+
("testing-v2.0.0rc1", "2.0.0rc1"),
35+
("testing-v2.0.0-beta,sdk-v1.0.0", "2.0.0-beta"),
36+
]
37+
38+
for input_text, expected in test_cases:
39+
result = parse_testing_version(input_text)
40+
# Assert is expected in test functions
41+
assert result == expected, ( # noqa: S101
42+
f"Expected '{expected}' but got '{result}' for input: {input_text}"
43+
)
44+
45+
46+
if __name__ == "__main__":
47+
test_parse_testing_version()
48+
sys.exit(0)

0 commit comments

Comments
 (0)