v0.13.9-rework_ha_addon

This commit is contained in:
Mateusz Gruszczyński
2026-09-10 08:24:53 +02:00
parent b905a6fcc4
commit 34e62da372
45 changed files with 405 additions and 1597 deletions
+112 -53
View File
@@ -3,87 +3,146 @@ set -Eeuo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
ENV_FILE="${HA_ADDON_ENV_FILE:-$SCRIPT_DIR/.env}"
if [[ -f "$SCRIPT_DIR/.env" ]]; then
set -a
# shellcheck disable=SC1091
source "$SCRIPT_DIR/.env"
set +a
fi
[[ -f "$ENV_FILE" ]] || {
echo "Missing $ENV_FILE. Copy $SCRIPT_DIR/.env.example to $SCRIPT_DIR/.env and edit it." >&2
exit 1
}
REGISTRY="${REGISTRY:-zot.linuxiarz.pl}"
IMAGE_NAME="${IMAGE_NAME:-gree-controller}"
DISTRO="${DISTRO:-trixie}"
BUILDER="${BUILDER:-gree-controller-multiarch}"
BUILDER_CONFIG="${BUILDER_CONFIG:-}"
ACTION="${1:-push}"
set -a
# shellcheck disable=SC1090
source "$ENV_FILE"
set +a
VERSION="$(awk -F '"' '/^version = "/ {print $2; exit}' "$PROJECT_ROOT/Cargo.toml")"
[[ -n "$VERSION" ]] || { echo "Cannot determine version from Cargo.toml" >&2; exit 1; }
required=(REGISTRY IMAGE_NAME DISTRO RUST_VERSION BUILD_PLATFORMS BUILDER HA_REPO_URL ADDON_DIR INTEGRATION_DOMAIN)
for name in "${required[@]}"; do
[[ -n "${!name:-}" ]] || { echo "Missing $name in $ENV_FILE" >&2; exit 1; }
done
case "$DISTRO" in
trixie|alpine) ;;
*) echo "DISTRO must be one of: trixie, alpine" >&2; exit 2 ;;
esac
ACTION="${1:-push}"
VERSION="$(awk -F '"' '/^version = "/ {print $2; exit}' "$PROJECT_ROOT/Cargo.toml")"
[[ -n "$VERSION" ]] || { echo "Cannot determine version from Cargo.toml" >&2; exit 1; }
IMAGE_REPO="${REGISTRY%/}/${IMAGE_NAME#/}"
IMAGE_TAG="${IMAGE_REPO}:${VERSION}"
CONFIG="$SCRIPT_DIR/repository/$ADDON_DIR/config.yaml"
LOCKFILE="$PROJECT_ROOT/Cargo.lock"
INTEGRATION_MANIFEST="$SCRIPT_DIR/home-assistant/custom_components/$INTEGRATION_DOMAIN/manifest.json"
REPOSITORY_CONFIG="$SCRIPT_DIR/repository/repository.yaml"
"$SCRIPT_DIR/render-repository.sh"
[[ -f "$CONFIG" ]] || { echo "Missing add-on config: $CONFIG" >&2; exit 1; }
[[ -f "$INTEGRATION_MANIFEST" ]] || { echo "Missing integration manifest: $INTEGRATION_MANIFEST" >&2; exit 1; }
[[ -f "$REPOSITORY_CONFIG" ]] || { echo "Missing repository config: $REPOSITORY_CONFIG" >&2; exit 1; }
if [[ "$ACTION" == "render" ]]; then
exit 0
fi
render_metadata() {
command -v python3 >/dev/null 2>&1 || { echo "python3 is required" >&2; exit 1; }
python3 - "$CONFIG" "$LOCKFILE" "$INTEGRATION_MANIFEST" "$REPOSITORY_CONFIG" "$VERSION" "$IMAGE_REPO" "$HA_REPO_URL" <<'PY'
from pathlib import Path
import re
import sys
command -v docker >/dev/null 2>&1 || { echo "docker is required" >&2; exit 1; }
docker buildx version >/dev/null 2>&1 || { echo "docker buildx is required" >&2; exit 1; }
config = Path(sys.argv[1])
lockfile = Path(sys.argv[2])
manifest = Path(sys.argv[3])
repository = Path(sys.argv[4])
version = sys.argv[5]
image = sys.argv[6]
repo_url = sys.argv[7]
lines = config.read_text(encoding="utf-8").splitlines()
out = []
for line in lines:
if line.startswith("version:"):
out.append(f'version: "{version}"')
elif line.startswith("image:"):
out.append(f'image: "{image}"')
elif line.startswith("url:"):
out.append(f'url: "{repo_url}"')
else:
out.append(line)
config.write_text("\n".join(out) + "\n", encoding="utf-8")
lock = lockfile.read_text(encoding="utf-8")
pattern = r'(\[\[package\]\]\nname = "gree-controller"\nversion = ")[^"]+("\n)'
updated, count = re.subn(pattern, rf'\g<1>{version}\g<2>', lock, count=1)
if count != 1:
raise SystemExit("Could not find gree-controller package version in Cargo.lock")
lockfile.write_text(updated, encoding="utf-8")
import json
data = json.loads(manifest.read_text(encoding="utf-8"))
data["version"] = version
manifest.write_text(json.dumps(data, indent=2) + "\n", encoding="utf-8")
repo_lines = repository.read_text(encoding="utf-8").splitlines()
repo_out = [f"url: {repo_url}" if line.startswith("url:") else line for line in repo_lines]
repository.write_text("\n".join(repo_out) + "\n", encoding="utf-8")
PY
printf 'Synced version %s; image %s\n' "$VERSION" "$IMAGE_REPO"
}
ensure_builder() {
command -v docker >/dev/null 2>&1 || { echo "docker is required" >&2; exit 1; }
docker buildx version >/dev/null 2>&1 || { echo "docker buildx is required" >&2; exit 1; }
if docker buildx inspect "$BUILDER" >/dev/null 2>&1; then
docker buildx use "$BUILDER"
else
args=(create --name "$BUILDER" --driver docker-container --use)
if [[ -n "$BUILDER_CONFIG" ]]; then
args+=(--config "$BUILDER_CONFIG")
fi
[[ -z "${BUILDER_CONFIG:-}" ]] || args+=(--config "$BUILDER_CONFIG")
docker buildx "${args[@]}" >/dev/null
fi
docker buildx inspect --bootstrap >/dev/null
}
ensure_builder
build_push() {
ensure_builder
docker buildx build \
--platform "$BUILD_PLATFORMS" \
-f "$SCRIPT_DIR/Dockerfile" \
--target "runtime-${DISTRO}" \
--build-arg "BUILD_VERSION=$VERSION" \
--build-arg "RUST_VERSION=$RUST_VERSION" \
-t "$IMAGE_TAG" \
--push \
"$PROJECT_ROOT"
printf 'Published %s (%s, %s)\n' "$IMAGE_TAG" "$BUILD_PLATFORMS" "$DISTRO"
}
build_load() {
local arch="${2:-amd64}" platform
case "$arch" in
amd64) platform="linux/amd64" ;;
aarch64|arm64) platform="linux/arm64" ;;
*) echo "Usage: $0 load [amd64|aarch64]" >&2; exit 2 ;;
esac
ensure_builder
docker buildx build \
--platform "$platform" \
-f "$SCRIPT_DIR/Dockerfile" \
--target "runtime-${DISTRO}" \
--build-arg "BUILD_VERSION=$VERSION" \
--build-arg "RUST_VERSION=$RUST_VERSION" \
-t "${IMAGE_REPO}:local" \
--load \
"$PROJECT_ROOT"
printf 'Loaded %s:local for %s (%s)\n' "$IMAGE_REPO" "$arch" "$DISTRO"
}
render_metadata
case "$ACTION" in
push)
docker buildx build \
--platform linux/amd64,linux/arm64 \
-f "$SCRIPT_DIR/Dockerfile" \
--target "runtime-${DISTRO}" \
--build-arg "BUILD_VERSION=$VERSION" \
-t "$IMAGE_TAG" \
--push \
"$PROJECT_ROOT"
printf 'Published %s using %s (amd64 + aarch64)\n' "$IMAGE_TAG" "$DISTRO"
;;
load)
arch="${2:-amd64}"
case "$arch" in
amd64) platform="linux/amd64" ;;
aarch64|arm64) platform="linux/arm64" ;;
*) echo "Usage: $0 load [amd64|aarch64]" >&2; exit 2 ;;
esac
docker buildx build \
--platform "$platform" \
-f "$SCRIPT_DIR/Dockerfile" \
--target "runtime-${DISTRO}" \
--build-arg "BUILD_VERSION=$VERSION" \
-t "${IMAGE_REPO}:local" \
--load \
"$PROJECT_ROOT"
printf 'Loaded %s:local for %s using %s\n' "$IMAGE_REPO" "$arch" "$DISTRO"
;;
render) ;;
push) build_push ;;
load) build_load "${2:-amd64}" ;;
*)
echo "Usage: $0 [push|load [amd64|aarch64]|render]" >&2
echo "Usage: $0 [render|push|load [amd64|aarch64]]" >&2
exit 2
;;
esac