@@ -120,14 +120,42 @@ echo
120120#
121121# Provenance is recorded where it is knowable rather than guessed here: each
122122# binary is stamped into MANIFEST by the build that produced it, on the host
123- # that could actually run `--version `. Scraping version strings out of a
123+ # that could actually run `--info `. Scraping version strings out of a
124124# cross-platform image was tried and is not reliable - the engine does not
125125# store its version as a standalone string on every target, so good binaries
126126# were reported as stale.
127127MANIFEST=" $VSCODE_BIN /BUILD-MANIFEST"
128128
129+ # The binary name is the last field, so a line whose second field is that name
130+ # is one written before the manifest carried a commit at all.
131+ manifest_line () {
132+ [ -f " $MANIFEST " ] || return 0
133+ awk -v b=" $1 " ' $NF == b { print; exit }' " $MANIFEST "
134+ }
135+
136+ manifest_version () {
137+ local line ver
138+ line=" $( manifest_line " $1 " ) "
139+ if [ -n " $line " ]; then
140+ read -r ver _ <<< " $line"
141+ printf ' %s\n' " $ver "
142+ fi
143+ }
144+
145+ manifest_commit () {
146+ local line ver commit
147+ line=" $( manifest_line " $1 " ) "
148+ if [ -n " $line " ]; then
149+ read -r ver commit _ <<< " $line"
150+ if [ " $commit " != " $1 " ]; then
151+ printf ' %s\n' " $commit "
152+ fi
153+ fi
154+ }
155+
129156missing=0
130157stale=0
158+ COMMITS=()
131159for bin in " ${BINARIES[@]} " " $WINDOWS_SIDECAR " ; do
132160 if [ ! -f " $VSCODE_BIN /$bin " ]; then
133161 printf ' ✗ %-36s MISSING\n' " $bin "
@@ -143,12 +171,19 @@ for bin in "${BINARIES[@]}" "$WINDOWS_SIDECAR"; do
143171 continue
144172 fi
145173
146- if [ -f " $MANIFEST " ] && grep -qxF " $VERSION $bin " " $MANIFEST " ; then
147- printf ' ✓ %-36s %s (%s)\n' " $bin " " $size " " $VERSION "
148- else
149- recorded=" $( grep -F " $bin " " $MANIFEST " 2> /dev/null | awk ' {print $1}' | tr ' \n' ' ' || true) "
150- printf ' ✗ %-36s %s NOT STAMPED %s\n' " $bin " " $size " " ${recorded: +(manifest says: $recorded )} "
174+ recorded_version=" $( manifest_version " $bin " ) "
175+ recorded_commit=" $( manifest_commit " $bin " ) "
176+
177+ if [ " $recorded_version " != " $VERSION " ]; then
178+ printf ' ✗ %-36s %s NOT STAMPED %s\n' \
179+ " $bin " " $size " " ${recorded_version: +(manifest says: $recorded_version )} "
151180 stale=1
181+ elif [ -z " $recorded_commit " ]; then
182+ printf ' ✗ %-36s %s NO COMMIT RECORDED\n' " $bin " " $size "
183+ stale=1
184+ else
185+ printf ' ✓ %-36s %s (%s @ %s)\n' " $bin " " $size " " $VERSION " " $recorded_commit "
186+ COMMITS+=(" $recorded_commit " )
152187 fi
153188done
154189
168203if [ " $stale " -ne 0 ]; then
169204 cat >&2 << EOF
170205
171- ERROR: at least one binary is not stamped as $VERSION in
206+ ERROR: at least one binary is not stamped as $VERSION with a source commit in
172207$VSCODE_BIN /BUILD-MANIFEST.
173208
174209vscode/bin/ is not cleaned between releases, so an unstamped binary is assumed
175210to be left over from an earlier one. Rebuild it and record it with:
176211
177- ./scripts/stamp-binary.sh <name> <version>
212+ ./scripts/stamp-binary.sh <name> <version> [commit]
213+
214+ A binary stamped with no commit was recorded before the manifest carried one;
215+ re-stamp it, from the host that can run it or with the commit stated, so the
216+ set can be checked for agreement.
178217
179218Publishing an unverified binary would produce a release whose checksums are
180219perfectly valid for the wrong build - the hardest kind of mistake to notice.
181220EOF
182221 exit 1
183222fi
184223
224+ # ------------------------------------------------------ one commit, all assets
225+ # A shared version number is not a shared source. Each platform is built on its
226+ # own host, so five binaries can all be stamped $VERSION and still come from
227+ # five different trees - and then a bug reported against $VERSION on Linux and
228+ # one reported against $VERSION on macOS describe different software under the
229+ # same name. Compared by prefix: each host's git abbreviates commits to its own
230+ # length, so the same commit legitimately appears as 7 and 12 hex digits.
231+ ref_commit=" "
232+ for c in " ${COMMITS[@]} " ; do
233+ if [ -z " $ref_commit " ] || [ " ${# c} " -lt " ${# ref_commit} " ]; then
234+ ref_commit=" $c "
235+ fi
236+ done
237+
238+ commit_mismatch=0
239+ for c in " ${COMMITS[@]} " ; do
240+ case " $c " in " $ref_commit " * ) ;; * ) commit_mismatch=1 ;; esac
241+ done
242+
243+ if [ " $commit_mismatch " -ne 0 ]; then
244+ {
245+ echo
246+ echo " ERROR: the staged binaries were not all built from the same commit."
247+ echo
248+ for bin in " ${BINARIES[@]} " ; do
249+ printf ' %-36s %s\n' " $bin " " $( manifest_commit " $bin " ) "
250+ done
251+ cat << EOF
252+
253+ Everything in one release has to come from one tree, or the tag names a build
254+ that never existed as a whole. Rebuild the assets that disagree from the commit
255+ being released - see cross-platform-builds.md for the per-platform hosts - and
256+ re-stamp them with ./scripts/stamp-binary.sh.
257+ EOF
258+ } >&2
259+ exit 1
260+ fi
261+
262+ echo
263+ printf ' all %d engine binaries built from %s\n' " ${# COMMITS[@]} " " $ref_commit "
264+
185265# ---------------------------------------------------------------- checksums
186266# An engine binary runs on the user's machine with their permissions, so the
187267# client verifies what it downloaded. TLS alone does not cover a mirror, a
0 commit comments