Remove Probe build jobs and release paths. Transfer Gitea publishing credentials to both Agent architecture jobs, publish each platform archive once, and run slow tests after development images are published.
160 lines
7.8 KiB
Bash
160 lines
7.8 KiB
Bash
#!/usr/bin/env bash
|
|
# Create/update the Gitea Release after all platform package workflows succeed.
|
|
set -euo pipefail
|
|
|
|
tag="${CI_COMMIT_TAG:-}"
|
|
[[ "$tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]] || {
|
|
echo "release must run from a vMAJOR.MINOR.PATCH tag" >&2
|
|
exit 2
|
|
}
|
|
[[ -n "${GITEA_TOKEN:-}" ]] || { echo "GITEA_TOKEN is required" >&2; exit 2; }
|
|
|
|
version="${tag#v}"
|
|
gitea_base="${GITEA_BASE:-http://192.168.2.162:3100}"
|
|
gitea_base="${gitea_base%/}"
|
|
gitea_host="${gitea_base#https://}"
|
|
gitea_host="${gitea_host#http://}"
|
|
gitea_host="${gitea_host%%/*}"
|
|
gitea_host="${gitea_host%%:*}"
|
|
api="$gitea_base/api/v1/repos/justme/MoShiro"
|
|
tmp="$(mktemp -d)"
|
|
netrc="$tmp/netrc"
|
|
release_json="$tmp/release.json"
|
|
assets_json="$tmp/assets.json"
|
|
chmod 700 "$tmp"
|
|
printf 'machine %s login justme password %s\n' "$gitea_host" "$GITEA_TOKEN" > "$netrc"
|
|
chmod 600 "$netrc"
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
|
|
root_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
install_sh="$(sha256sum "$root_dir/packaging/install/install.sh" | cut -d" " -f1)"
|
|
install_ps1="$(sha256sum "$root_dir/packaging/install/install.ps1" | cut -d" " -f1)"
|
|
release_body="Install script SHA-256 (compare with the panel before you run an install command): install.sh $install_sh, install.ps1 $install_ps1. Agent builds: Linux glibc and musl (x64, arm64), macOS (x64, arm64), and Windows (x64, arm64). Linux musl Agent OCI image: registry.oeo.one/moshiro/moshiro-agent:$version (linux/amd64 and linux/arm64). Backend OCI image: registry.oeo.one/moshiro/moshiro-backend:$version (linux/amd64 and linux/arm64). Compose files for Agent and Backend: moshiro-compose-<role>.yaml (images use :latest, or pin MOSHIRO_VERSION in .env). macOS binaries are not Developer ID signed or notarized."
|
|
payload="$(printf '{"tag_name":"%s","target_commitish":"%s","name":"MoShiro %s","body":"%s","draft":false,"prerelease":false}' \
|
|
"$tag" "${CI_COMMIT_SHA:-}" "$tag" "$release_body")"
|
|
release_status="$(curl --silent --show-error --retry 3 --netrc-file "$netrc" \
|
|
--output "$release_json" --write-out '%{http_code}' "$api/releases/tags/$tag")"
|
|
release_created=false
|
|
if [[ "$release_status" == 404 ]]; then
|
|
release_status="$(curl --silent --show-error --retry 3 --netrc-file "$netrc" \
|
|
--header 'Content-Type: application/json' --data "$payload" \
|
|
--output "$release_json" --write-out '%{http_code}' "$api/releases")"
|
|
release_created=true
|
|
fi
|
|
[[ "$release_status" =~ ^2 ]] || {
|
|
echo "Gitea Release lookup/create failed (HTTP $release_status)" >&2
|
|
cat "$release_json" >&2
|
|
exit 1
|
|
}
|
|
release_id="$(grep -o '"id":[[:space:]]*[0-9][0-9]*' "$release_json" | head -1 | tr -cd '0-9')"
|
|
[[ -n "$release_id" ]] || { echo "Could not read Gitea Release ID" >&2; exit 1; }
|
|
if [[ "$release_created" == false ]]; then
|
|
update_response="$tmp/release-update.json"
|
|
update_status="$(curl --silent --show-error --retry 3 --netrc-file "$netrc" \
|
|
--request PATCH --header 'Content-Type: application/json' --data "$payload" \
|
|
--output "$update_response" --write-out '%{http_code}' "$api/releases/$release_id")"
|
|
[[ "$update_status" =~ ^2 ]] || {
|
|
echo "Gitea Release update failed (HTTP $update_status)" >&2
|
|
cat "$update_response" >&2
|
|
exit 1
|
|
}
|
|
fi
|
|
curl --fail-with-body --silent --show-error --retry 3 --netrc-file "$netrc" \
|
|
"$api/releases/$release_id/assets" -o "$assets_json"
|
|
|
|
assets=(
|
|
"moshiro-agent-v$version-linux-amd64.tar.gz"
|
|
"moshiro-agent-v$version-linux-arm64.tar.gz"
|
|
"moshiro-agent-v$version-linux-musl-amd64.tar.gz"
|
|
"moshiro-agent-v$version-linux-musl-arm64.tar.gz"
|
|
"moshiro-agent-v$version-macos-x64.tar.gz"
|
|
"moshiro-agent-v$version-macos-arm64.tar.gz"
|
|
"moshiro-agent-v$version-windows-amd64.zip"
|
|
"moshiro-agent-v$version-windows-arm64.zip"
|
|
)
|
|
|
|
upload_release_asset() {
|
|
local name="$1" file="$tmp/$1" upload_response="$tmp/$1.upload.json" status
|
|
curl --fail-with-body --silent --show-error --retry 3 --netrc-file "$netrc" \
|
|
"$gitea_base/api/packages/justme/generic/moshiro-node/$version/$name" -o "$file"
|
|
status="$(curl --silent --show-error --retry 3 --netrc-file "$netrc" \
|
|
--request POST --header 'Content-Type: application/octet-stream' --data-binary "@$file" \
|
|
--output "$upload_response" --write-out '%{http_code}' \
|
|
"$api/releases/$release_id/assets?name=$name")"
|
|
case "$status" in
|
|
2*) echo "attached $name" ;;
|
|
*) echo "Gitea Release asset upload failed for $name (HTTP $status)" >&2; cat "$upload_response" >&2; return 1 ;;
|
|
esac
|
|
}
|
|
|
|
pids=()
|
|
for archive in "${assets[@]}"; do
|
|
for name in "$archive" "$archive.sha256"; do
|
|
if grep -Eq "\"name\"[[:space:]]*:[[:space:]]*\"$name\"" "$assets_json"; then
|
|
echo "release asset $name already exists; keeping the existing asset"
|
|
continue
|
|
fi
|
|
upload_release_asset "$name" &
|
|
pids+=("$!")
|
|
if ((${#pids[@]} >= 8)); then
|
|
wait "${pids[0]}"
|
|
pids=("${pids[@]:1}")
|
|
fi
|
|
done
|
|
done
|
|
for pid in "${pids[@]}"; do
|
|
wait "$pid"
|
|
done
|
|
|
|
# 所有压缩包的校验和汇成一份 SHA256SUMS,用发布私钥签名(base64 的 DER ECDSA,和签名的发布清单是同一把密钥、同一种格式):
|
|
# 不走容器的安装(直接下载压缩包)先验这份签名再核对压缩包的哈希,发布页被改也骗不到;没有配置签名密钥(例如 fork)就跳过。
|
|
upload_local_asset() {
|
|
local name="$1" file="$2" upload_response="$tmp/$1.upload.json" status
|
|
if grep -Eq "\"name\"[[:space:]]*:[[:space:]]*\"$name\"" "$assets_json"; then
|
|
echo "release asset $name already exists; keeping the existing asset"
|
|
return 0
|
|
fi
|
|
status="$(curl --silent --show-error --retry 3 --netrc-file "$netrc" \
|
|
--request POST --header 'Content-Type: application/octet-stream' --data-binary "@$file" \
|
|
--output "$upload_response" --write-out '%{http_code}' "$api/releases/$release_id/assets?name=$name")"
|
|
[[ "$status" == 2* ]] || { echo "Gitea Release asset upload failed for $name (HTTP $status)" >&2; cat "$upload_response" >&2; return 1; }
|
|
echo "attached $name"
|
|
}
|
|
|
|
# compose 文件(Agent、Backend 各一份)和节点的 Podman Quadlet 单元(Agent 各一份),都是静态的(镜像用 :latest):作为发布资产,
|
|
# 第一次部署 Backend 时还没有面板,就从这里下载;它们也记进 SHA256SUMS(有签名密钥时一起签名)。
|
|
for role in agent backend; do
|
|
cp "$root_dir/packaging/compose/$role/compose.yaml" "$tmp/moshiro-compose-$role.yaml"
|
|
upload_local_asset "moshiro-compose-$role.yaml" "$tmp/moshiro-compose-$role.yaml"
|
|
done
|
|
for role in agent; do
|
|
cp "$root_dir/packaging/quadlet/moshiro-$role.container" "$tmp/moshiro-quadlet-$role.container"
|
|
upload_local_asset "moshiro-quadlet-$role.container" "$tmp/moshiro-quadlet-$role.container"
|
|
done
|
|
|
|
if [[ -n "${RELEASE_SIGNING_KEY:-}" ]]; then
|
|
sums="$tmp/SHA256SUMS"
|
|
: > "$sums"
|
|
for archive in "${assets[@]}"; do
|
|
curl --fail --silent --show-error --retry 3 --netrc-file "$netrc" \
|
|
"$gitea_base/api/packages/justme/generic/moshiro-node/$version/$archive.sha256" -o "$tmp/$archive.sha256"
|
|
cat "$tmp/$archive.sha256" >> "$sums"
|
|
done
|
|
[[ "$(wc -l < "$sums")" -eq "${#assets[@]}" ]] || { echo "SHA256SUMS does not have one line per archive" >&2; exit 1; }
|
|
for file in moshiro-compose-agent.yaml moshiro-compose-backend.yaml moshiro-quadlet-agent.container; do
|
|
printf '%s %s\n' "$(sha256sum "$tmp/$file" | cut -d' ' -f1)" "$file" >> "$sums"
|
|
done
|
|
signing_key="$(mktemp)"
|
|
chmod 600 "$signing_key"
|
|
printf '%s\n' "$RELEASE_SIGNING_KEY" > "$signing_key"
|
|
openssl dgst -sha256 -sign "$signing_key" -out "$tmp/SHA256SUMS.sig.bin" "$sums"
|
|
rm -f "$signing_key"
|
|
base64 -w0 "$tmp/SHA256SUMS.sig.bin" > "$tmp/SHA256SUMS.sig" 2>/dev/null || base64 "$tmp/SHA256SUMS.sig.bin" | tr -d '\n' > "$tmp/SHA256SUMS.sig"
|
|
upload_local_asset SHA256SUMS "$sums"
|
|
upload_local_asset SHA256SUMS.sig "$tmp/SHA256SUMS.sig"
|
|
else
|
|
echo "release signing is not configured; SHA256SUMS is not signed"
|
|
fi
|
|
|
|
echo "published Gitea Release $tag: https://git.oeo.one/justme/MoShiro/releases/tag/$tag"
|