publish-update-manifest.sh 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #!/usr/bin/env bash
  2. set -euo pipefail
  3. channel="${1:-}"
  4. version="${2:-}"
  5. if [[ "$channel" != "official" && "$channel" != "beta" ]]; then
  6. echo "Unsupported update channel: $channel" >&2
  7. exit 1
  8. fi
  9. if [[ -z "$version" ]]; then
  10. echo "Release version is required" >&2
  11. exit 1
  12. fi
  13. : "${GITHUB_REPOSITORY:?GITHUB_REPOSITORY is required}"
  14. : "${RUNNER_TEMP:?RUNNER_TEMP is required}"
  15. manifest_branch="update-manifests"
  16. manifest_dir="$RUNNER_TEMP/$manifest_branch"
  17. release_tmp="$manifest_dir/release.tmp"
  18. release_list_tmp="$manifest_dir/releases.tmp"
  19. write_manifest() {
  20. local source_file="$1"
  21. local target_channel="$2"
  22. local expected_version="$3"
  23. local target_file="$manifest_dir/$target_channel.json"
  24. local target_tmp="$target_file.tmp"
  25. local expected_prerelease="false"
  26. if [[ "$target_channel" == "beta" ]]; then
  27. expected_prerelease="true"
  28. fi
  29. jq -e \
  30. --arg version "$expected_version" \
  31. --argjson prerelease "$expected_prerelease" \
  32. 'if .tag_name == $version and .prerelease == $prerelease and (.assets | type == "array") then
  33. {
  34. tag_name,
  35. name,
  36. body: (.body // ""),
  37. prerelease,
  38. created_at,
  39. assets: [.assets[] | {
  40. browser_download_url,
  41. content_type,
  42. created_at,
  43. download_count: 0,
  44. id,
  45. name,
  46. state,
  47. url
  48. }]
  49. }
  50. else
  51. error("Release response does not match the requested channel and version")
  52. end' \
  53. "$source_file" > "$target_tmp"
  54. mv "$target_tmp" "$target_file"
  55. }
  56. rm -rf "$manifest_dir"
  57. if git fetch --no-tags origin "$manifest_branch"; then
  58. git worktree add --detach "$manifest_dir" FETCH_HEAD
  59. else
  60. git worktree add --detach "$manifest_dir" HEAD
  61. git -C "$manifest_dir" checkout --orphan "$manifest_branch"
  62. git -C "$manifest_dir" rm -q -rf --ignore-unmatch .
  63. fi
  64. trap 'git worktree remove --force "$manifest_dir" >/dev/null 2>&1 || true' EXIT
  65. gh api \
  66. -H "Accept: application/vnd.github+json" \
  67. -H "X-GitHub-Api-Version: 2026-03-10" \
  68. "repos/$GITHUB_REPOSITORY/releases/tags/$version" > "$release_tmp"
  69. write_manifest "$release_tmp" "$channel" "$version"
  70. other_channel="official"
  71. if [[ "$channel" == "official" ]]; then
  72. other_channel="beta"
  73. fi
  74. if [[ ! -f "$manifest_dir/$other_channel.json" ]]; then
  75. if [[ "$other_channel" == "official" ]]; then
  76. gh api \
  77. -H "Accept: application/vnd.github+json" \
  78. -H "X-GitHub-Api-Version: 2026-03-10" \
  79. "repos/$GITHUB_REPOSITORY/releases/latest" > "$release_tmp"
  80. other_version="$(jq -r '.tag_name' "$release_tmp")"
  81. write_manifest "$release_tmp" "$other_channel" "$other_version"
  82. else
  83. gh api \
  84. -H "Accept: application/vnd.github+json" \
  85. -H "X-GitHub-Api-Version: 2026-03-10" \
  86. "repos/$GITHUB_REPOSITORY/releases?per_page=100" > "$release_list_tmp"
  87. if jq -e \
  88. '[.[] | select(.draft == false and .prerelease == true)] | max_by(.created_at) | select(. != null)' \
  89. "$release_list_tmp" > "$release_tmp"; then
  90. other_version="$(jq -r '.tag_name' "$release_tmp")"
  91. write_manifest "$release_tmp" "$other_channel" "$other_version"
  92. fi
  93. fi
  94. fi
  95. rm -f "$release_tmp" "$release_list_tmp"
  96. git -C "$manifest_dir" config user.name "github-actions[bot]"
  97. git -C "$manifest_dir" config user.email "41898282+github-actions[bot]@users.noreply.github.com"
  98. git -C "$manifest_dir" add --all
  99. if git -C "$manifest_dir" diff --cached --quiet; then
  100. echo "$channel update manifest is already current"
  101. exit 0
  102. fi
  103. git -C "$manifest_dir" commit -m "Update release manifests for $version"
  104. git -C "$manifest_dir" push origin "HEAD:refs/heads/$manifest_branch"