Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/release-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ jobs:
set -euo pipefail
. scripts/release/baseline.env
names=$(gh release view "v$VERSION" -R "$GITHUB_REPOSITORY" --json assets --jq '[.assets[].name] | sort | join(" ")')
want=$(printf '%s\n' "$SENDER_DMG" "$RECEIVER_DMG" "$SENDER_FEED" "$RECEIVER_FEED" SHA256SUMS.txt | sort | paste -sd' ' -)
want=$(printf '%s\n' "$SENDER_DMG" "$RECEIVER_DMG" "$SENDER_FEED" "$RECEIVER_FEED" SHA256SUMS.txt | LC_ALL=C sort | paste -sd' ' -)
[ "$names" = "$want" ] || { echo "::error::draft assets are '$names', expected '$want'"; exit 1; }
mkdir check && gh release download "v$VERSION" -R "$GITHUB_REPOSITORY" -D check
sed 's# dist/# check/#' expected.sha256 | shasum -a 256 -c -
Expand Down
1 change: 1 addition & 0 deletions scripts/release/check-release-workflows.rb
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ def release_ref_guard?(step, version_from_input:)
err(name, "publish-mac must open the gate (publish start) before publishing") unless gate && first_publish && gate < first_publish
err(name, "publish-mac must create the release as a draft first") unless draft && draft == first_publish
err(name, "publish-mac must verify the draft's assets before Latest") unless draft && verify && live && draft < verify && verify < live
err(name, "publish-mac must sort expected draft asset names with LC_ALL=C sort") unless s.any? { |x| run_text(x).include?("LC_ALL=C sort") }
err(name, "publish-mac must revert Latest when the live feeds don't verify") unless live && revert && live < revert
end
# The release state is written by GitHub Actions and is not evidence by
Expand Down
43 changes: 43 additions & 0 deletions scripts/release/test/draft_asset_sorting_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# frozen_string_literal: true

require "minitest/autorun"
require "open3"

class DraftAssetSortingTest < Minitest::Test
# The five assets produced by Mac packaging and expected in the release draft:
ASSETS = %w[
MeowDisplay.dmg
MeowDisplayReceiver.dmg
appcast.xml
appcast-receiver.xml
SHA256SUMS.txt
].freeze

def test_lc_all_c_sort_matches_jq_byte_collation
# jq 'sort' orders by Unicode code point / byte value:
# 'M' (0x4D), 'S' (0x53) precede 'a' (0x61).
jq_sorted = %w[
MeowDisplay.dmg
MeowDisplayReceiver.dmg
SHA256SUMS.txt
appcast-receiver.xml
appcast.xml
]

out, status = Open3.capture2({ "LC_ALL" => "C" }, "sort", stdin_data: ASSETS.join("\n") + "\n")
assert status.success?
c_sorted = out.lines.map(&:strip)

assert_equal jq_sorted, c_sorted
end

def test_locale_sensitive_sort_divergence_is_documented
# The runner's locale-dependent sort put lowercase 'appcast*' before 'MeowDisplay*'.
# LC_ALL=C is required to guarantee deterministic comparison against jq's output.
c_out, _ = Open3.capture2({ "LC_ALL" => "C" }, "sort", stdin_data: ASSETS.join("\n") + "\n")
c_sorted = c_out.lines.map(&:strip)

assert_equal "MeowDisplay.dmg", c_sorted.first
assert_equal "appcast.xml", c_sorted.last
end
end
2 changes: 2 additions & 0 deletions scripts/release/test/workflow_checks_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ def test_an_incomplete_latest_release_is_caught
"release-publish.yml" => ['--draft --target "$SHA"', '--target "$SHA"'])
assert_caught("publish-mac must verify the draft's assets before Latest",
"release-publish.yml" => ['gh release download "v$VERSION"', 'echo download "v$VERSION"'])
assert_caught("publish-mac must sort expected draft asset names with LC_ALL=C sort",
"release-publish.yml" => ['LC_ALL=C sort', 'sort'])
assert_caught("publish-mac must revert Latest when the live feeds don't verify",
"release-publish.yml" => ['--draft=true', '--draft=false-ish'])
assert_caught("publish-mac must open the gate (publish start) before publishing",
Expand Down
Loading