Updating changelog + build for 3.6.6

This commit is contained in:
Jack Kingsman
2026-03-31 22:52:14 -07:00
parent 96e108037c
commit 704a3d8a87
10 changed files with 544 additions and 158 deletions

View File

@@ -1,3 +1,7 @@
## [3.6.6] - 2026-03-31
* Misc: Please I'm begging for the build scripts to be working now
## [3.6.5] - 2026-03-31
* Bugfix: Maybe fix problem with publish script

View File

@@ -1,7 +1,7 @@
{
"name": "remoteterm-meshcore-frontend",
"private": true,
"version": "3.6.5",
"version": "3.6.6",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,6 +1,6 @@
[project]
name = "remoteterm-meshcore"
version = "3.6.5"
version = "3.6.6"
description = "RemoteTerm - Web interface for MeshCore radio mesh networks"
readme = "README.md"
requires-python = ">=3.10"

View File

@@ -0,0 +1,106 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
# shellcheck source=scripts/build/release_common.sh
source "$SCRIPT_DIR/release_common.sh"
usage() {
cat <<'EOF'
Usage: scripts/build/create_github_release.sh --version X.Y.Z --asset PATH [options]
Options:
--version VERSION Release version / tag (required)
--asset PATH Asset to attach; may be specified multiple times
--notes-file PATH Markdown release notes file; defaults to CHANGELOG section
--full-git-hash HASH Commit to tag if the tag does not already exist locally
--title TITLE Release title (default: version)
--help Show this message
EOF
}
VERSION=""
TITLE=""
NOTES_FILE=""
FULL_GIT_HASH=""
ASSETS=()
TEMP_NOTES_FILE=""
cleanup() {
if [ -n "$TEMP_NOTES_FILE" ] && [ -f "$TEMP_NOTES_FILE" ]; then
rm -f "$TEMP_NOTES_FILE"
fi
}
trap cleanup EXIT
while [ $# -gt 0 ]; do
case "$1" in
--version)
VERSION="${2:-}"
shift 2
;;
--asset)
ASSETS+=("${2:-}")
shift 2
;;
--notes-file)
NOTES_FILE="${2:-}"
shift 2
;;
--full-git-hash)
FULL_GIT_HASH="${2:-}"
shift 2
;;
--title)
TITLE="${2:-}"
shift 2
;;
--help)
usage
exit 0
;;
*)
usage >&2
release_die "Unknown argument: $1"
;;
esac
done
[ -n "$VERSION" ] || release_die "--version is required"
[ "${#ASSETS[@]}" -gt 0 ] || release_die "At least one --asset is required"
release_validate_version "$VERSION"
REPO_ROOT="$(release_repo_root)"
TITLE="${TITLE:-$VERSION}"
FULL_GIT_HASH="${FULL_GIT_HASH:-$(release_resolve_full_hash "$REPO_ROOT")}"
for asset in "${ASSETS[@]}"; do
[ -f "$asset" ] || release_die "Asset not found: $asset"
done
if [ -z "$NOTES_FILE" ]; then
TEMP_NOTES_FILE="$(mktemp)"
release_extract_changelog_section "$REPO_ROOT" "$VERSION" "$TEMP_NOTES_FILE"
NOTES_FILE="$TEMP_NOTES_FILE"
fi
[ -f "$NOTES_FILE" ] || release_die "Notes file not found: $NOTES_FILE"
if ! git -C "$REPO_ROOT" rev-parse -q --verify "refs/tags/$VERSION" >/dev/null; then
echo "[create_github_release] Creating local tag $VERSION at $FULL_GIT_HASH..." >&2
git -C "$REPO_ROOT" tag -a "$VERSION" "$FULL_GIT_HASH" -F "$NOTES_FILE"
fi
if ! git -C "$REPO_ROOT" ls-remote --exit-code --tags origin "refs/tags/$VERSION" >/dev/null 2>&1; then
echo "[create_github_release] Pushing tag $VERSION to origin..." >&2
git -C "$REPO_ROOT" push origin "$VERSION"
fi
if gh release view "$VERSION" >/dev/null 2>&1; then
echo "[create_github_release] Updating existing GitHub release $VERSION..." >&2
gh release upload "$VERSION" "${ASSETS[@]}" --clobber
gh release edit "$VERSION" --title "$TITLE" --notes-file "$NOTES_FILE"
else
echo "[create_github_release] Creating GitHub release $VERSION..." >&2
gh release create "$VERSION" "${ASSETS[@]}" --title "$TITLE" --notes-file "$NOTES_FILE" --verify-tag
fi

View File

@@ -0,0 +1,54 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
# shellcheck source=scripts/build/release_common.sh
source "$SCRIPT_DIR/release_common.sh"
usage() {
cat <<'EOF'
Usage: scripts/build/extract_release_notes.sh --version X.Y.Z --output PATH
Options:
--version VERSION Release version to extract from CHANGELOG.md
--output PATH Output markdown file path
--changelog PATH Override changelog path
--help Show this message
EOF
}
VERSION=""
OUTPUT_FILE=""
CHANGELOG_PATH=""
while [ $# -gt 0 ]; do
case "$1" in
--version)
VERSION="${2:-}"
shift 2
;;
--output)
OUTPUT_FILE="${2:-}"
shift 2
;;
--changelog)
CHANGELOG_PATH="${2:-}"
shift 2
;;
--help)
usage
exit 0
;;
*)
usage >&2
release_die "Unknown argument: $1"
;;
esac
done
[ -n "$VERSION" ] || release_die "--version is required"
[ -n "$OUTPUT_FILE" ] || release_die "--output is required"
release_validate_version "$VERSION"
REPO_ROOT="$(release_repo_root)"
release_extract_changelog_section "$REPO_ROOT" "$VERSION" "$OUTPUT_FILE" "${CHANGELOG_PATH:-$REPO_ROOT/CHANGELOG.md}"

View File

@@ -0,0 +1,111 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
# shellcheck source=scripts/build/release_common.sh
source "$SCRIPT_DIR/release_common.sh"
usage() {
cat <<'EOF'
Usage: scripts/build/package_release_artifact.sh --version X.Y.Z [options]
Options:
--version VERSION Release version (required)
--git-hash HASH Short git hash to embed in artifact naming
--full-git-hash HASH Full git hash to archive
--output PATH Output zip path
--bundle-name NAME Bundle folder name inside the zip
--skip-prebuilt-build Reuse existing frontend/prebuilt instead of rebuilding it
--help Show this message
EOF
}
VERSION=""
GIT_HASH=""
FULL_GIT_HASH=""
OUTPUT_PATH=""
BUNDLE_NAME="Remote-Terminal-for-MeshCore"
SKIP_PREBUILT_BUILD=0
while [ $# -gt 0 ]; do
case "$1" in
--version)
VERSION="${2:-}"
shift 2
;;
--git-hash)
GIT_HASH="${2:-}"
shift 2
;;
--full-git-hash)
FULL_GIT_HASH="${2:-}"
shift 2
;;
--output)
OUTPUT_PATH="${2:-}"
shift 2
;;
--bundle-name)
BUNDLE_NAME="${2:-}"
shift 2
;;
--skip-prebuilt-build)
SKIP_PREBUILT_BUILD=1
shift
;;
--help)
usage
exit 0
;;
*)
usage >&2
release_die "Unknown argument: $1"
;;
esac
done
[ -n "$VERSION" ] || release_die "--version is required"
release_validate_version "$VERSION"
REPO_ROOT="$(release_repo_root)"
FULL_GIT_HASH="${FULL_GIT_HASH:-$(release_resolve_full_hash "$REPO_ROOT")}"
GIT_HASH="${GIT_HASH:-$(release_resolve_short_hash "$REPO_ROOT" "$FULL_GIT_HASH")}"
OUTPUT_PATH="${OUTPUT_PATH:-$REPO_ROOT/remoteterm-prebuilt-frontend-v${VERSION}-${GIT_HASH}.zip}"
WORK_DIR="$(mktemp -d)"
BUNDLE_DIR="$WORK_DIR/$BUNDLE_NAME"
cleanup() {
rm -rf "$WORK_DIR"
}
trap cleanup EXIT
if [ "$SKIP_PREBUILT_BUILD" -eq 0 ]; then
echo "[package_release_artifact] Building frontend prebuilt bundle..." >&2
(
cd "$REPO_ROOT/frontend"
npm run packaged-build
)
fi
[ -d "$REPO_ROOT/frontend/prebuilt" ] || release_die "frontend/prebuilt is missing; run with frontend built or omit --skip-prebuilt-build"
mkdir -p "$BUNDLE_DIR/frontend"
git -C "$REPO_ROOT" archive "$FULL_GIT_HASH" | tar -x -C "$BUNDLE_DIR"
cp -R "$REPO_ROOT/frontend/prebuilt" "$BUNDLE_DIR/frontend/prebuilt"
cat > "$BUNDLE_DIR/build_info.json" <<EOF
{
"version": "$VERSION",
"commit_hash": "$GIT_HASH",
"build_source": "prebuilt-release"
}
EOF
rm -f "$OUTPUT_PATH"
(
cd "$WORK_DIR"
zip -qr "$OUTPUT_PATH" "$BUNDLE_NAME"
)
echo "$OUTPUT_PATH"

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env bash
set -e
set -euo pipefail
# Colors for output
RED='\033[0;31m'
@@ -10,73 +10,63 @@ NC='\033[0m' # No Color
REPO_ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
cd "$REPO_ROOT"
RELEASE_WORK_DIR=""
RELEASE_BUNDLE_DIR_NAME="Remote-Terminal-for-MeshCore"
RELEASE_ASSET=""
DOCKER_IMAGE="jkingsman/remoteterm-meshcore"
DOCKER_PLATFORMS="linux/amd64,linux/arm64"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
# shellcheck source=scripts/build/release_common.sh
source "$SCRIPT_DIR/release_common.sh"
cleanup_release_build_artifacts() {
if [ -d "$REPO_ROOT/frontend/prebuilt" ]; then
rm -rf "$REPO_ROOT/frontend/prebuilt"
fi
if [ -n "$RELEASE_WORK_DIR" ] && [ -d "$RELEASE_WORK_DIR" ]; then
rm -rf "$RELEASE_WORK_DIR"
fi
if [ -n "$RELEASE_ASSET" ] && [ -f "$REPO_ROOT/$RELEASE_ASSET" ]; then
rm -f "$REPO_ROOT/$RELEASE_ASSET"
fi
DOCKER_IMAGE="docker.io/jkingsman/remoteterm-meshcore"
DOCKER_PLATFORMS="linux/amd64,linux/arm64,linux/arm/v7"
VERSION=""
NOTES_FILE=""
SKIP_QUALITY=0
RELEASE_ASSET_PATH=""
usage() {
cat <<'EOF'
Usage: scripts/build/publish.sh [options]
Options:
--version VERSION Release version; prompts if omitted
--notes-file PATH File containing changelog entry lines; prompts if omitted
--skip-quality Skip ./scripts/quality/all_quality.sh
--help Show this message
EOF
}
trap cleanup_release_build_artifacts EXIT
while [ $# -gt 0 ]; do
case "$1" in
--version)
VERSION="${2:-}"
shift 2
;;
--notes-file)
NOTES_FILE="${2:-}"
shift 2
;;
--skip-quality)
SKIP_QUALITY=1
shift
;;
--help)
usage
exit 0
;;
*)
usage >&2
release_die "Unknown argument: $1"
;;
esac
done
echo -e "${YELLOW}=== RemoteTerm for MeshCore Publish Script ===${NC}"
echo
# Run backend linting and type checking
echo -e "${YELLOW}Running backend lint (Ruff)...${NC}"
uv run ruff check app/ tests/ --fix
uv run ruff format app/ tests/
# validate
uv run ruff check app/ tests/
uv run ruff format --check app/ tests/
echo -e "${GREEN}Backend lint passed!${NC}"
echo
echo -e "${YELLOW}Running backend type check (Pyright)...${NC}"
uv run pyright app/
echo -e "${GREEN}Backend type check passed!${NC}"
echo
# Run backend tests
echo -e "${YELLOW}Running backend tests...${NC}"
PYTHONPATH=. uv run pytest tests/ -v
echo -e "${GREEN}Backend tests passed!${NC}"
echo
# Run frontend linting and formatting check
echo -e "${YELLOW}Running frontend lint (ESLint)...${NC}"
cd "$REPO_ROOT/frontend"
npm run lint
echo -e "${GREEN}Frontend lint passed!${NC}"
echo
echo -e "${YELLOW}Checking frontend formatting (Prettier)...${NC}"
npm run format:check
echo -e "${GREEN}Frontend formatting OK!${NC}"
echo
# Run frontend tests and build
echo -e "${YELLOW}Running frontend tests...${NC}"
npm run test:run
echo -e "${GREEN}Frontend tests passed!${NC}"
echo
echo -e "${YELLOW}Building frontend...${NC}"
npm run build
echo -e "${GREEN}Frontend build complete!${NC}"
cd "$REPO_ROOT"
echo
if [ "$SKIP_QUALITY" -eq 0 ]; then
echo -e "${YELLOW}Running repo quality gate...${NC}"
./scripts/quality/all_quality.sh
echo -e "${GREEN}Quality gate passed!${NC}"
echo
fi
echo -e "${YELLOW}Regenerating LICENSES.md...${NC}"
bash scripts/build/collect_licenses.sh LICENSES.md
@@ -91,13 +81,11 @@ echo -n " package.json: "
grep '"version"' frontend/package.json | head -1 | sed 's/.*"version": "\(.*\)".*/\1/'
echo
read -r -p "Enter new version (e.g., 1.2.3): " VERSION
VERSION="$(printf '%s' "$VERSION" | tr -d '\r' | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')"
if [[ ! $VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo -e "${RED}Error: Version must be in format X.Y.Z${NC}"
exit 1
if [ -z "$VERSION" ]; then
read -r -p "Enter new version (e.g., 1.2.3): " VERSION
fi
VERSION="$(release_trim "$VERSION")"
release_validate_version "$VERSION"
# Update pyproject.toml
echo -e "${YELLOW}Updating pyproject.toml...${NC}"
@@ -115,18 +103,28 @@ echo -e "${GREEN}Version updated to $VERSION${NC}"
echo
# Prompt for changelog entry
echo -e "${YELLOW}Enter changelog entry for version $VERSION${NC}"
echo -e "${YELLOW}(Enter your changes, then press Ctrl+D when done):${NC}"
echo
CHANGELOG_ENTRY=$(cat)
format_changelog_entry() {
local entry="$1"
printf '%s\n' "$entry" | sed '/^[[:space:]]*$/d; s/^[[:space:]]*//; s/^/* /'
RAW_CHANGELOG_INPUT_FILE="$(mktemp)"
FORMATTED_CHANGELOG_INPUT_FILE="$(mktemp)"
cleanup() {
rm -f "$RAW_CHANGELOG_INPUT_FILE" "$FORMATTED_CHANGELOG_INPUT_FILE"
rm -rf "${REPO_ROOT:?}/frontend/prebuilt"
if [ -n "$RELEASE_ASSET_PATH" ] && [ -f "$RELEASE_ASSET_PATH" ]; then
rm -f "$RELEASE_ASSET_PATH"
fi
}
trap cleanup EXIT
FORMATTED_CHANGELOG_ENTRY=$(format_changelog_entry "$CHANGELOG_ENTRY")
if [ -n "$NOTES_FILE" ]; then
cp "$NOTES_FILE" "$RAW_CHANGELOG_INPUT_FILE"
else
echo -e "${YELLOW}Enter changelog entry for version $VERSION${NC}"
echo -e "${YELLOW}(Enter your changes, then press Ctrl+D when done):${NC}"
echo
cat > "$RAW_CHANGELOG_INPUT_FILE"
fi
release_format_markdown_list "$RAW_CHANGELOG_INPUT_FILE" "$FORMATTED_CHANGELOG_INPUT_FILE"
[ -s "$FORMATTED_CHANGELOG_INPUT_FILE" ] || release_die "Changelog entry cannot be empty"
# Create changelog entry with date
DATE=$(date +%Y-%m-%d)
@@ -142,7 +140,7 @@ if [ -f CHANGELOG.md ]; then
echo
echo "$CHANGELOG_HEADER"
echo
echo "$FORMATTED_CHANGELOG_ENTRY"
cat "$FORMATTED_CHANGELOG_INPUT_FILE"
echo
tail -n +2 CHANGELOG.md
} > CHANGELOG.md.tmp
@@ -152,7 +150,7 @@ if [ -f CHANGELOG.md ]; then
{
echo "$CHANGELOG_HEADER"
echo
echo "$FORMATTED_CHANGELOG_ENTRY"
cat "$FORMATTED_CHANGELOG_INPUT_FILE"
echo
cat CHANGELOG.md
} > CHANGELOG.md.tmp
@@ -165,7 +163,7 @@ else
echo
echo "$CHANGELOG_HEADER"
echo
echo "$FORMATTED_CHANGELOG_ENTRY"
cat "$FORMATTED_CHANGELOG_INPUT_FILE"
} > CHANGELOG.md
fi
@@ -185,93 +183,33 @@ echo
GIT_HASH=$(git rev-parse --short HEAD)
FULL_GIT_HASH=$(git rev-parse HEAD)
RELEASE_ASSET="remoteterm-prebuilt-frontend-v${VERSION}-${GIT_HASH}.zip"
RELEASE_ASSET_PATH="$REPO_ROOT/$RELEASE_ASSET"
echo -e "${YELLOW}Building packaged frontend artifact...${NC}"
cd "$REPO_ROOT/frontend"
npm run packaged-build
cd "$REPO_ROOT"
RELEASE_WORK_DIR=$(mktemp -d)
RELEASE_BUNDLE_DIR="$RELEASE_WORK_DIR/$RELEASE_BUNDLE_DIR_NAME"
mkdir -p "$RELEASE_BUNDLE_DIR"
git archive "$FULL_GIT_HASH" | tar -x -C "$RELEASE_BUNDLE_DIR"
mkdir -p "$RELEASE_BUNDLE_DIR/frontend"
cp -R "$REPO_ROOT/frontend/prebuilt" "$RELEASE_BUNDLE_DIR/frontend/prebuilt"
cat > "$RELEASE_BUNDLE_DIR/build_info.json" <<EOF
{
"version": "$VERSION",
"commit_hash": "$GIT_HASH",
"build_source": "prebuilt-release"
}
EOF
rm -f "$REPO_ROOT/$RELEASE_ASSET"
(
cd "$RELEASE_WORK_DIR"
zip -qr "$REPO_ROOT/$RELEASE_ASSET" "$(basename "$RELEASE_BUNDLE_DIR")"
)
scripts/build/package_release_artifact.sh \
--version "$VERSION" \
--git-hash "$GIT_HASH" \
--full-git-hash "$FULL_GIT_HASH" \
--output "$RELEASE_ASSET_PATH"
echo -e "${GREEN}Packaged release artifact created: $RELEASE_ASSET${NC}"
echo
# Build and push multi-arch docker image
echo -e "${YELLOW}Building and pushing multi-arch Docker image...${NC}"
if ! docker buildx version >/dev/null 2>&1; then
echo -e "${RED}Error: docker buildx is required for multi-arch Docker builds.${NC}"
exit 1
fi
CURRENT_BUILDER="$(docker buildx inspect --format '{{ .Name }}' 2>/dev/null || true)"
if [ -n "$CURRENT_BUILDER" ]; then
docker buildx inspect --bootstrap >/dev/null
elif docker buildx inspect remoteterm-multiarch >/dev/null 2>&1; then
docker buildx use remoteterm-multiarch >/dev/null
docker buildx inspect --bootstrap >/dev/null
else
docker buildx create --name remoteterm-multiarch --use >/dev/null
docker buildx inspect --bootstrap >/dev/null
fi
docker buildx build \
--platform "$DOCKER_PLATFORMS" \
--build-arg COMMIT_HASH="$GIT_HASH" \
-t "$DOCKER_IMAGE:latest" \
-t "$DOCKER_IMAGE:$VERSION" \
-t "$DOCKER_IMAGE:$GIT_HASH" \
--push \
.
scripts/build/push_docker_multiarch.sh \
--version "$VERSION" \
--git-hash "$GIT_HASH" \
--image "$DOCKER_IMAGE" \
--platforms "$DOCKER_PLATFORMS"
echo -e "${GREEN}Multi-arch Docker build + push complete!${NC}"
echo
# Create GitHub release using the changelog notes for this version.
echo -e "${YELLOW}Creating GitHub release...${NC}"
RELEASE_NOTES_FILE=$(mktemp)
{
echo "$CHANGELOG_HEADER"
echo
echo "$FORMATTED_CHANGELOG_ENTRY"
} > "$RELEASE_NOTES_FILE"
# Create and push the release tag first so GitHub release creation does not
# depend on resolving a symbolic ref like HEAD on the remote side. Use the same
# changelog-derived notes for the annotated tag message.
if git rev-parse -q --verify "refs/tags/$VERSION" >/dev/null; then
echo -e "${YELLOW}Tag $VERSION already exists locally; reusing it.${NC}"
else
git tag -a "$VERSION" "$FULL_GIT_HASH" -F "$RELEASE_NOTES_FILE"
fi
if git ls-remote --exit-code --tags origin "refs/tags/$VERSION" >/dev/null 2>&1; then
echo -e "${YELLOW}Tag $VERSION already exists on origin; not pushing it again.${NC}"
else
git push origin "$VERSION"
fi
gh release create "$VERSION" \
"$RELEASE_ASSET" \
--title "$VERSION" \
--notes-file "$RELEASE_NOTES_FILE" \
--verify-tag
rm -f "$RELEASE_NOTES_FILE"
scripts/build/create_github_release.sh \
--version "$VERSION" \
--full-git-hash "$FULL_GIT_HASH" \
--asset "$RELEASE_ASSET_PATH"
echo -e "${GREEN}GitHub release created!${NC}"
echo
@@ -285,6 +223,7 @@ echo -e " - $DOCKER_IMAGE:$GIT_HASH"
echo -e "Platforms:"
echo -e " - linux/amd64"
echo -e " - linux/arm64"
echo -e " - linux/arm/v7"
echo -e "GitHub release:"
echo -e " - $VERSION"
echo -e "Release artifact:"

View File

@@ -0,0 +1,79 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
# shellcheck source=scripts/build/release_common.sh
source "$SCRIPT_DIR/release_common.sh"
usage() {
cat <<'EOF'
Usage: scripts/build/push_docker_multiarch.sh --version X.Y.Z [options]
Options:
--version VERSION Release version (required)
--git-hash HASH Short git hash to tag alongside the version
--image IMAGE Docker image name (default: docker.io/jkingsman/remoteterm-meshcore)
--platforms CSV Buildx platforms CSV (default: linux/amd64,linux/arm64,linux/arm/v7)
--help Show this message
EOF
}
VERSION=""
GIT_HASH=""
IMAGE="docker.io/jkingsman/remoteterm-meshcore"
PLATFORMS="linux/amd64,linux/arm64,linux/arm/v7"
while [ $# -gt 0 ]; do
case "$1" in
--version)
VERSION="${2:-}"
shift 2
;;
--git-hash)
GIT_HASH="${2:-}"
shift 2
;;
--image)
IMAGE="${2:-}"
shift 2
;;
--platforms)
PLATFORMS="${2:-}"
shift 2
;;
--help)
usage
exit 0
;;
*)
usage >&2
release_die "Unknown argument: $1"
;;
esac
done
[ -n "$VERSION" ] || release_die "--version is required"
release_validate_version "$VERSION"
REPO_ROOT="$(release_repo_root)"
GIT_HASH="${GIT_HASH:-$(release_resolve_short_hash "$REPO_ROOT")}"
echo "[push_docker_multiarch] Ensuring docker buildx builder..." >&2
release_ensure_buildx_builder
docker_buildx_args=(
build
--platform "$PLATFORMS"
--build-arg "COMMIT_HASH=$GIT_HASH"
-t "$IMAGE:latest"
-t "$IMAGE:$VERSION"
-t "$IMAGE:$GIT_HASH"
--push
.
)
echo "[push_docker_multiarch] Building and pushing $IMAGE for $PLATFORMS..." >&2
(
cd "$REPO_ROOT"
docker buildx "${docker_buildx_args[@]}"
)

View File

@@ -0,0 +1,93 @@
#!/usr/bin/env bash
release_repo_root() {
(
cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd
)
}
release_die() {
echo "Error: $*" >&2
exit 1
}
release_trim() {
printf '%s' "$1" | tr -d '\r' | sed 's/^[[:space:]]*//; s/[[:space:]]*$//'
}
release_validate_version() {
local version="$1"
[[ $version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || release_die "Version must be in format X.Y.Z"
}
release_resolve_full_hash() {
local repo_root="$1"
local ref="${2:-HEAD}"
git -C "$repo_root" rev-parse "$ref"
}
release_resolve_short_hash() {
local repo_root="$1"
local ref="${2:-HEAD}"
git -C "$repo_root" rev-parse --short "$ref"
}
release_format_markdown_list() {
local input_file="$1"
local output_file="$2"
awk '
/^[[:space:]]*$/ { next }
{
sub(/^[[:space:]]+/, "", $0)
if ($0 ~ /^\* /) {
print
} else if ($0 ~ /^- /) {
sub(/^- /, "* ", $0)
print
} else {
print "* " $0
}
}
' "$input_file" > "$output_file"
}
release_extract_changelog_section() {
local repo_root="$1"
local version="$2"
local output_file="$3"
local changelog_path="${4:-$repo_root/CHANGELOG.md}"
# Use index() for literal matching so dots in version strings are not
# treated as regex wildcards (e.g. 3.6.5 won't match 31615).
awk -v ver="$version" '
BEGIN { header = "## [" ver "]" }
index($0, header) == 1 { capture = 1; print; next }
capture && /^## \[/ { exit }
capture { print }
' "$changelog_path" > "$output_file"
[ -s "$output_file" ] || release_die "Could not find CHANGELOG entry for version $version"
}
release_ensure_buildx_builder() {
if ! docker buildx version >/dev/null 2>&1; then
release_die "docker buildx is required for multi-arch Docker builds"
fi
# Multi-platform builds require the docker-container driver. The default
# builder uses the "docker" driver which only supports the host platform.
# Check the current builder's driver first; only create a new one if needed.
local current_driver
current_driver="$(docker buildx inspect --format '{{ .Driver }}' 2>/dev/null || true)"
if [ "$current_driver" = "docker-container" ]; then
docker buildx inspect --bootstrap >/dev/null
return
fi
if docker buildx inspect remoteterm-multiarch >/dev/null 2>&1; then
docker buildx use remoteterm-multiarch >/dev/null
else
docker buildx create --name remoteterm-multiarch --use >/dev/null
fi
docker buildx inspect --bootstrap >/dev/null
}

2
uv.lock generated
View File

@@ -1098,7 +1098,7 @@ wheels = [
[[package]]
name = "remoteterm-meshcore"
version = "3.6.5"
version = "3.6.6"
source = { virtual = "." }
dependencies = [
{ name = "aiomqtt" },