Skip to content

Commit 70e002a

Browse files
Dev container images info issue fix regarding history documentation and cgmanifest updates (#1891)
* Dev container images info issue fix regarding history documentation and cgmanifest * Updating review comment. * Updating manifest versions * Implementing review comment. * Correct indentation. --------- Co-authored-by: Abdurrahmaan Iqbal <[email protected]>
1 parent 4f60ce0 commit 70e002a

7 files changed

Lines changed: 53 additions & 17 deletions

File tree

‎build/config.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@
183183
"downloadUrl": "https://github.com/cli/cli"
184184
},
185185
"yarn": {
186-
"versionCommand": "yarn --version",
186+
"versionCommand": "yarn --version 2>/dev/null | grep -oE '[0-9]+\\.[0-9]+\\.[0-9]+'",
187187
"downloadUrl": "https://yarnpkg.com/"
188188
},
189189
"Maven": {

‎build/src/utils/config.js‎

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ function getTagsForVersion(definitionId, version, registry, registryPath, varian
214214
}
215215
}
216216

217+
const seen = new Set();
217218
return tags.reduce((list, tag) => {
218219
// One of the tags that needs to be supported is one where there is no version, but there
219220
// are other attributes. For example, python:3 in addition to python:0.35.0-3. So, a version
@@ -224,7 +225,11 @@ function getTagsForVersion(definitionId, version, registry, registryPath, varian
224225
.replace(/\$\{?VARIANT\}?/, variant || 'NOVARIANT')
225226
.replace('-NOVARIANT', '');
226227
if (baseTag.charAt(baseTag.length - 1) !== ':') {
227-
list.push(`${registry}/${registryPath}/${baseTag}`);
228+
const fullTag = `${registry}/${registryPath}/${baseTag}`;
229+
if (!seen.has(fullTag)) {
230+
seen.add(fullTag);
231+
list.push(fullTag);
232+
}
228233
}
229234
return list;
230235
}, []);
@@ -305,13 +310,23 @@ function getTagList(definitionId, release, versionPartHandling, registry, regist
305310
// If this variant should also be used for the the latest tag, add it. The "latest" value could be
306311
// true, false, or a specific variant. "true" assumes the first variant is the latest.
307312
const definitionLatestProperty = config.definitionBuildSettings[definitionId].latest;
308-
return tagList.concat((updateLatest
313+
const allTags = tagList.concat((updateLatest
309314
&& definitionLatestProperty
310315
&& (!allVariants
311-
|| variant === definitionLatestProperty
316+
|| variant === definitionLatestProperty
312317
|| (definitionLatestProperty === true && variant === firstVariant)))
313318
? getLatestTag(definitionId, registry, registryPath)
314319
: []);
320+
321+
// Deduplicate tags while preserving order
322+
const seen = new Set();
323+
return allTags.filter((tag) => {
324+
if (seen.has(tag)) {
325+
return false;
326+
}
327+
seen.add(tag);
328+
return true;
329+
});
315330
}
316331

317332
const getDefinitionObject = (id, variant) => {

‎build/src/utils/image-content-extractor.js‎

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -271,12 +271,34 @@ async function getPipPackageInfo(imageTagOrContainerName, packageList, usePipx,
271271
console.log('(*) Gathering information about pip packages...');
272272
const versionLookup = usePipx ? await getPipxVersionLookup(imageTagOrContainerName) : await getPipVersionLookup(imageTagOrContainerName, imageId);
273273

274-
return packageList.map((package) => {
275-
return {
276-
name: package,
277-
version: versionLookup[package]
278-
};
279-
});
274+
// Build a fallback lookup keyed by PEP 503 normalized names so packages that
275+
// differ only by casing/normalization (e.g. "pyOpenssl" vs "pyOpenSSL") still resolve.
276+
const normalizedVersionLookup = Object.keys(versionLookup).reduce((prev, name) => {
277+
prev[normalizePipPackageName(name)] = versionLookup[name];
278+
return prev;
279+
}, {});
280+
281+
return packageList.reduce((list, package) => {
282+
const version = versionLookup[package] || normalizedVersionLookup[normalizePipPackageName(package)];
283+
// Skip packages that aren't actually installed in the inspected environment.
284+
// Emitting an entry without a version produces blank markdown rows and
285+
// conflicting/duplicate cgmanifest.json (SBOM) registrations.
286+
if (version) {
287+
list.push({
288+
name: package,
289+
version: version
290+
});
291+
} else {
292+
console.log(`(!) Warning: Could not determine version for pip package "${package}" - skipping.`);
293+
}
294+
return list;
295+
}, []);
296+
}
297+
298+
// Normalize a Python package name per PEP 503 (lowercase, runs of "-_." collapsed to "-")
299+
// so lookups are tolerant of casing/separator differences between manifests and pip output.
300+
function normalizePipPackageName(name) {
301+
return name.replace(/[-_.]+/g, '-').toLowerCase();
280302
}
281303

282304
function getUserName(imageId) {

‎src/dotnet/manifest.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080
"languages": {
8181
".NET": {
8282
"cgIgnore": true,
83-
"versionCommand": "dotnet --version | grep -oE '[0-9]+\\.[0-9]+\\.[0-9]+' | tr -d '\\n' && echo \\\" (\\$(dotnet --info | grep -ozP 'Host.*:\\s*Version:\\s*\\K[0-9]\\.[0-9]\\.[0-9]' | tr '\\0' '\\n'))\\\"",
83+
"versionCommand": "dotnet --version | grep -oE '[0-9]+\\.[0-9]+\\.[0-9]+' | tr -d '\\n' && echo \\\" (\\$(dotnet --info | grep -ozP 'Host.*:\\s*Version:\\s*\\K[0-9]+\\.[0-9]+\\.[0-9]+' | tr '\\0' '\\n'))\\\"",
8484
"path": "/usr",
8585
"downloadUrl": "https://dotnet.microsoft.com/"
8686
}

‎src/java-8/README.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ Refer to [this guide](https://containers.dev/guide/dockerfile) for more details.
3030
You can decide how often you want updates by referencing a [semantic version](https://semver.org/) of each image. For example:
3131

3232
- `mcr.microsoft.com/devcontainers/java:3-8` (or `3-8-trixie`, `3-8-bookworm` to pin to an OS version)
33-
- `mcr.microsoft.com/devcontainers/java:3.0-8` (or `3.0-8-trixie`, `3.0-8-bookworm` to pin to an OS version)
34-
- `mcr.microsoft.com/devcontainers/java:3.0.12-8` (or `3.0.12-8-trixie`, `3.0.12-8-bookworm` to pin to an OS version)
33+
- `mcr.microsoft.com/devcontainers/java:3.1-8` (or `3.1-8-trixie`, `3.1-8-bookworm` to pin to an OS version)
34+
- `mcr.microsoft.com/devcontainers/java:3.1.0-8` (or `3.1.0-8-trixie`, `3.1.0-8-bookworm` to pin to an OS version)
3535

3636
However, we only do security patching on the latest [non-breaking, in support](https://github.com/devcontainers/images/issues/90) versions of images (e.g. `3-8`). You may want to run `apt-get update && apt-get upgrade` in your Dockerfile if you lock to a more specific version to at least pick up OS security updates.
3737

‎src/java-8/manifest.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "3.0.12",
2+
"version": "3.1.0",
33
"variants": [
44
"trixie",
55
"bookworm"
@@ -56,7 +56,7 @@
5656
"languages": {
5757
"Java": {
5858
"cgIgnore": true,
59-
"versionCommand": "/usr/local/sdkman/candidates/java/current/bin/java -version 2>&1 | grep -ozP '^openjdk\\sversion\\s\\\"\\K[^\\\"]+' | tr '\\0' '\\n' && /usr/local/openjdk-*/bin/java --version | grep -ozP 'openjdk\\s+\\K[0-9]+\\.[0-9]+\\.[0-9]+' | tr '\\0' '\\n'",
59+
"versionCommand": "/usr/local/sdkman/candidates/java/current/bin/java -version 2>&1 | grep -ozP '^openjdk\\sversion\\s\\\"\\K[^\\\"]+' | tr '\\0' '\\n'",
6060
"path": "/usr/local/sdkman/candidates/java/current<br />/usr/local"
6161
}
6262
}

‎src/universal/manifest.json‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,7 @@
118118
"plotly",
119119
"jupyterlab_git",
120120
"certifi",
121-
"setuptools",
122-
"wheel"
121+
"setuptools"
123122
],
124123
"other": {
125124
"git": {},

0 commit comments

Comments
 (0)