| 1 | #!/usr/bin/env bash |
| 2 | set -euo pipefail |
| 3 | |
| 4 | channel="${1:-}" |
| 5 | version="${2:-}" |
| 6 | asset_base="${3:-}" |
| 7 | manifest="${4:-}" |
| 8 | notes_version="${5:-$version}" |
| 9 | |
| 10 | stable_version_pattern='^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$' |
| 11 | preview_version_pattern='^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)-preview\.(0|[1-9][0-9]*)$' |
| 12 | release_version_pattern='^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-([0-9A-Za-z-]+)(\.[0-9A-Za-z-]+)*)?)?$' |
| 13 | |
| 14 | case "$channel" in |
| 15 | stable) |
| 16 | version_pattern="$stable_version_pattern" |
| 17 | legacy=false |
| 18 | ;; |
| 19 | preview) |
| 20 | version_pattern="$preview_version_pattern" |
| 21 | legacy=false |
| 22 | ;; |
| 23 | any) |
| 24 | version_pattern="$release_version_pattern" |
| 25 | legacy=false |
| 26 | ;; |
| 27 | legacy-stable) |
| 28 | version_pattern="$stable_version_pattern" |
| 29 | legacy=true |
| 30 | ;; |
| 31 | legacy-preview) |
| 32 | version_pattern="$preview_version_pattern" |
| 33 | legacy=true |
| 34 | ;; |
| 35 | legacy-any) |
| 36 | version_pattern="$release_version_pattern" |
| 37 | legacy=true |
| 38 | ;; |
| 39 | *) |
| 40 | echo "Desktop manifest channel must be stable, preview, any, legacy-stable, legacy-preview, or legacy-any: $channel" >&2 |
| 41 | exit 2 |
| 42 | ;; |
| 43 | esac |
| 44 | |
| 45 | if [[ ! "$version" =~ $version_pattern ]]; then |
| 46 | echo "invalid $channel Desktop manifest version: $version" >&2 |
| 47 | exit 1 |
| 48 | fi |
| 49 | if [[ ! "$notes_version" =~ $release_version_pattern ]]; then |
| 50 | echo "invalid Desktop release-notes version: $notes_version" >&2 |
| 51 | exit 1 |
| 52 | fi |
| 53 | |
| 54 | expected_tag="desktop-${version}" |
| 55 | github_base="https://github.com/esengine/DeepSeek-Reasonix/releases/download/${expected_tag}/" |
| 56 | r2_base="https://dl.reasonix.io/${expected_tag}/" |
| 57 | legacy_preview_base="https://dl.reasonix.io/desktop-preview/" |
| 58 | if [ "$channel" = "legacy-preview" ] && [ "$asset_base" = "$legacy_preview_base" ]; then |
| 59 | : |
| 60 | elif [ "$asset_base" != "$github_base" ] && [ "$asset_base" != "$r2_base" ]; then |
| 61 | echo "invalid official Desktop asset base: $asset_base" >&2 |
| 62 | exit 1 |
| 63 | fi |
| 64 | if [ ! -f "$manifest" ]; then |
| 65 | echo "Desktop release manifest does not exist: $manifest" >&2 |
| 66 | exit 1 |
| 67 | fi |
| 68 | |
| 69 | jq -e \ |
| 70 | --arg version "$version" \ |
| 71 | --arg notes_version "$notes_version" \ |
| 72 | --arg base "$asset_base" \ |
| 73 | --argjson legacy "$legacy" ' |
| 74 | def exact_keys($expected): |
| 75 | (type == "object") and ((keys | sort) == ($expected | sort)); |
| 76 | def valid_asset($name): |
| 77 | (type == "object") and |
| 78 | (.url == ($base + $name)) and |
| 79 | (.sig == ($base + $name + ".minisig")) and |
| 80 | (.size | type == "number" and . > 0 and . <= 1073741824 and floor == .) and |
| 81 | (.sha256 | type == "string" and test("^[0-9a-f]{64}$")); |
| 82 | |
| 83 | (type == "object") and |
| 84 | (.version == $version) and |
| 85 | (.download_page == "https://reasonix.io/?download=desktop#start") and |
| 86 | (if $legacy |
| 87 | then (.release_notes_url == null or .release_notes_url == ("https://reasonix.io/changelog/" + $notes_version + "/")) |
| 88 | else (.release_notes_url == ("https://reasonix.io/changelog/" + $notes_version + "/")) |
| 89 | end) and |
| 90 | (.platforms | exact_keys([ |
| 91 | "darwin-arm64", |
| 92 | "darwin-amd64", |
| 93 | "windows-amd64", |
| 94 | "windows-arm64", |
| 95 | "linux-amd64" |
| 96 | ])) and |
| 97 | (.platforms["darwin-arm64"] | valid_asset("Reasonix-darwin-arm64.zip")) and |
| 98 | (.platforms["darwin-amd64"] | valid_asset("Reasonix-darwin-amd64.zip")) and |
| 99 | (.platforms["windows-amd64"] | valid_asset("Reasonix-windows-amd64-installer.exe")) and |
| 100 | (.platforms["windows-arm64"] | valid_asset("Reasonix-windows-arm64-installer.exe")) and |
| 101 | (.platforms["linux-amd64"] | valid_asset("Reasonix-linux-amd64.tar.gz")) and |
| 102 | (.native_packages | exact_keys(["linux-amd64"])) and |
| 103 | (.native_packages["linux-amd64"] | valid_asset("Reasonix-linux-amd64.deb")) and |
| 104 | (if $legacy and (.downloads == null) |
| 105 | then true |
| 106 | else |
| 107 | (.downloads | exact_keys([ |
| 108 | "Reasonix-darwin-universal.dmg", |
| 109 | "Reasonix-windows-amd64.zip" |
| 110 | ])) and |
| 111 | (.downloads["Reasonix-darwin-universal.dmg"] | valid_asset("Reasonix-darwin-universal.dmg")) and |
| 112 | (.downloads["Reasonix-windows-amd64.zip"] | valid_asset("Reasonix-windows-amd64.zip")) |
| 113 | end) |
| 114 | ' "$manifest" >/dev/null |
| 115 |