ソースを参照

Add new `naughty-sharedtags.sh` script to detect incorrect `SharedTags` combinations

Here's an illustration of the problem this catches (the first one we've had with just eyeballing these, so honestly kind of an impressive history):

```console
$ bashbrew list --arch-filter --uniq nats:latest
nats:2.10.8-scratch
nats:2.9.24-scratch
```

Example output:

```console
$ ./naughty-sharedtags.sh
 - nats:2, nats:latest: (duplicate architectures in SharedTags; nats:2.10.8-scratch, nats:2.10.8-nanoserver-1809, nats:2.9.24-scratch)
   - amd64
   - amd64
   - arm32v6
   - arm32v6
   - arm32v7
   - arm32v7
   - arm64v8
   - arm64v8
```
Tianon Gravi 1 年間 前
コミット
7bca8e6dfe
2 ファイル変更55 行追加0 行削除
  1. 12 0
      .github/workflows/naughty.sh
  2. 43 0
      naughty-sharedtags.sh

+ 12 - 0
.github/workflows/naughty.sh

@@ -29,6 +29,18 @@ if badTags="$(bashbrew list "$@" | grep -E ':.+latest.*|:.*latest.+')" && [ -n "
 	(( ++numNaughty ))
 fi
 
+naughtySharedTags="$(./naughty-sharedtags.sh "$@")"
+if [ -n "$naughtySharedTags" ]; then
+	echo >&2
+	echo >&2 "Invalid 'SharedTags' combinations detected:"
+	echo >&2
+	echo >&2 "$naughtySharedTags"
+	echo >&2
+	echo >&2 'Read https://github.com/docker-library/faq#whats-the-difference-between-shared-and-simple-tags for more details.'
+	echo >&2
+	(( ++numNaughty ))
+fi
+
 naughtyFrom="$(./naughty-from.sh "$@")"
 if [ -n "$naughtyFrom" ]; then
 	echo >&2

+ 43 - 0
naughty-sharedtags.sh

@@ -0,0 +1,43 @@
+#!/usr/bin/env bash
+set -Eeuo pipefail
+
+if [ "$#" -eq 0 ]; then
+	set -- '--all'
+fi
+
+bashbrew cat --format '
+	{{- range $e := .Entries -}}
+		{{- range $t := .SharedTags -}}
+			{{- "{" -}}
+				"sharedTag": {{ join ":" $.RepoName $t | json }},
+				"tag": {{ join ":" $.RepoName ($e.Tags | first) | json }},
+				"arches": {{ $e.Architectures | json }}
+			{{- "}\n" -}}
+		{{- end -}}
+	{{- end -}}
+' "$@" | jq -rn '
+	# collect map of "shared tag -> all architectures" (combining shared tags back together, respecting/keeping duplicates, since that is what this is testing for)
+	reduce inputs as $in ({}; .[$in.sharedTag] |= (. // {} | .arches += $in.arches | .tags += [$in.tag]))
+	# convert that into a map of "shared tags -> same architecture list" (just to shrink the problem set and make it easier to look at/think about)
+	| reduce to_entries[] as $in ([];
+		(path(first(.[] | select(.value.arches == $in.value.arches))) // [length]) as $i
+		| .[$i[0]] |= (
+			.key |= if . then "\(.), \($in.key)" else $in.key end
+			| .value //= $in.value
+		)
+	)
+	| map(
+		# filter down to just entries with duplicates (ignoring Windows duplicates, since duplicating them is the primary use case of SharedTags in the first place)
+		.value.arches |= (
+			# TODO we *should* try to further verify that there is only one copy of each underlying Windows version here (not 2x "ltsc2022" for example), but that is a much more difficult query to automate
+			. - ["windows-amd64"]
+			# trim the list down to just the duplicates (so the error is more obvious)
+			| group_by(.)
+			| map(select(length > 1))
+			| flatten
+		)
+		| select(.value.arches | length > 0)
+		| " - \(.key): (duplicate architectures in SharedTags; \(.value.tags | join(", ")))\([ "", .value.arches[] ] | join("\n   - "))"
+	)
+	| join("\n\n")
+'