0399a6d384
Manifest was hashed from Windows working tree while Linux checkout uses git blobs; verify failed with sha256 mismatch. build-release-manifest.sh now hashes :index/HEAD; .gitattributes enforces LF for agent scripts.
105 lines
2.8 KiB
Bash
105 lines
2.8 KiB
Bash
#!/bin/bash
|
|
# Генерация release/manifest-VERSION.json (SHA256 файлов + git commit HEAD).
|
|
# Хеши считаются по содержимому git (HEAD), как после checkout на Linux-хосте.
|
|
# Запуск из корня репозитория: ./scripts/build-release-manifest.sh [VERSION]
|
|
set -euo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
cd "$ROOT"
|
|
|
|
version="${1:-}"
|
|
if [ -z "$version" ]; then
|
|
version="$(tr -d '\r\n' <version.txt 2>/dev/null || true)"
|
|
fi
|
|
if [ -z "$version" ]; then
|
|
version="$(grep -E '^[[:space:]]*SSH_MONITOR_VERSION=' ssh-monitor 2>/dev/null | head -1 | sed -E 's/^[^=]*=//; s/^["'\'']//; s/["'\'']$//; s/^[[:space:]]+//; s/[[:space:]]+$//')"
|
|
fi
|
|
[ -n "$version" ] || {
|
|
echo "ERROR: укажите VERSION или заполните version.txt" >&2
|
|
exit 1
|
|
}
|
|
|
|
FILES=(
|
|
ssh-monitor
|
|
sac-client.sh
|
|
update_ssh_monitor.sh
|
|
ssh-monitor-watchdog
|
|
ssh-monitor-perms.sh
|
|
)
|
|
|
|
for f in "${FILES[@]}"; do
|
|
git rev-parse "HEAD:$f" >/dev/null 2>&1 || [ -f "$f" ] || {
|
|
echo "ERROR: нет файла $f (ни в git HEAD, ни на диске)" >&2
|
|
exit 1
|
|
}
|
|
done
|
|
|
|
git_commit=""
|
|
if git rev-parse HEAD >/dev/null 2>&1; then
|
|
git_commit="$(git rev-parse HEAD)"
|
|
fi
|
|
|
|
out="release/manifest-${version}.json"
|
|
mkdir -p release
|
|
|
|
export MANIFEST_ROOT="$ROOT"
|
|
export MANIFEST_VERSION="$version"
|
|
export MANIFEST_GIT_COMMIT="$git_commit"
|
|
export MANIFEST_OUT="$out"
|
|
export MANIFEST_FILES="${FILES[*]}"
|
|
|
|
python3 <<'PY'
|
|
import hashlib
|
|
import json
|
|
import os
|
|
import subprocess
|
|
|
|
root = os.environ["MANIFEST_ROOT"]
|
|
version = os.environ["MANIFEST_VERSION"]
|
|
git_commit = os.environ.get("MANIFEST_GIT_COMMIT", "")
|
|
files = os.environ["MANIFEST_FILES"].split()
|
|
out = os.environ["MANIFEST_OUT"]
|
|
|
|
|
|
def sha256_bytes(data: bytes) -> str:
|
|
h = hashlib.sha256()
|
|
h.update(data)
|
|
return h.hexdigest()
|
|
|
|
|
|
def file_bytes_from_git(name: str) -> bytes | None:
|
|
for ref in (f":{name}", f"HEAD:{name}"):
|
|
try:
|
|
return subprocess.check_output(["git", "-C", root, "show", ref])
|
|
except subprocess.CalledProcessError:
|
|
continue
|
|
return None
|
|
|
|
|
|
def sha256_release_file(name: str) -> str:
|
|
blob = file_bytes_from_git(name)
|
|
if blob is not None:
|
|
return sha256_bytes(blob)
|
|
path = os.path.join(root, name)
|
|
h = hashlib.sha256()
|
|
with open(path, "rb") as f:
|
|
for chunk in iter(lambda: f.read(1024 * 1024), b""):
|
|
h.update(chunk)
|
|
return h.hexdigest()
|
|
|
|
|
|
manifest = {
|
|
"version": version,
|
|
"git_commit": git_commit,
|
|
"files": {},
|
|
}
|
|
for name in files:
|
|
manifest["files"][name] = f"sha256:{sha256_release_file(name)}"
|
|
|
|
with open(out, "w", encoding="utf-8") as f:
|
|
json.dump(manifest, f, indent=2, ensure_ascii=False)
|
|
f.write("\n")
|
|
|
|
print(f"Wrote {out} commit={git_commit[:12] if git_commit else '?'}")
|
|
PY
|