| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- #!/usr/bin/env bash
- # =============================================================================
- # create_github_repo.sh
- # One-shot script to:
- # 1) Create the GitHub repository conexocasa/solar-of-things-ha (if missing)
- # 2) Push main branch + all tags (v2.1.0, v2.1.1)
- # 3) Create a DRAFT GitHub Release for v2.1.1 and upload solar-of-things-ha.zip
- #
- # Usage:
- # export GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxx
- # bash create_github_repo.sh
- #
- # Requirements: git, curl, jq (installed by script if missing)
- # =============================================================================
- set -euo pipefail
- # ── Config ────────────────────────────────────────────────────────────────────
- GITHUB_USERNAME="conexocasa"
- GITHUB_EMAIL="bob@conexo.casa"
- REPO_NAME="solar-of-things-ha"
- REPO_DESC="Home Assistant custom integration for Solar of Things (Siseli) solar inverters — monitoring + control"
- RELEASE_TAG="v2.1.1"
- RELEASE_TITLE="v2.1.1 — HACS metadata, GitHub Actions, issue templates"
- ZIP_ASSET="solar-of-things-ha.zip"
- # ─────────────────────────────────────────────────────────────────────────────
- RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
- ok() { echo -e "${GREEN}✓${NC} $*"; }
- warn() { echo -e "${YELLOW}⚠${NC} $*"; }
- err() { echo -e "${RED}✗${NC} $*"; exit 1; }
- # ── Token ─────────────────────────────────────────────────────────────────────
- if [ -z "${GITHUB_TOKEN:-}" ]; then
- echo -n "GitHub Personal Access Token (repo scope): "
- read -s GITHUB_TOKEN
- echo
- fi
- [ -z "$GITHUB_TOKEN" ] && err "GITHUB_TOKEN is required."
- API="https://api.github.com"
- AUTH_HEADER="Authorization: token $GITHUB_TOKEN"
- ACCEPT="Accept: application/vnd.github.v3+json"
- # ── Dependencies ──────────────────────────────────────────────────────────────
- if ! command -v jq &>/dev/null; then
- warn "jq not found — installing…"
- apt-get install -y -q jq 2>/dev/null || brew install jq 2>/dev/null || err "Install jq manually."
- fi
- # ── Git identity ──────────────────────────────────────────────────────────────
- git config --global user.email "$GITHUB_EMAIL"
- git config --global user.name "$GITHUB_USERNAME"
- ok "Git identity set ($GITHUB_EMAIL)"
- # ── Step 1: Create repository (idempotent) ────────────────────────────────────
- echo ""
- echo "══════════════════════════════════════════════"
- echo " STEP 1 · Create GitHub repository"
- echo "══════════════════════════════════════════════"
- RESP=$(curl -s -o /tmp/gh_create.json -w "%{http_code}" \
- -X POST "$API/user/repos" \
- -H "$AUTH_HEADER" -H "$ACCEPT" \
- -d "{
- \"name\":\"$REPO_NAME\",
- \"description\":\"$REPO_DESC\",
- \"private\":false,
- \"has_issues\":true,
- \"has_projects\":false,
- \"has_wiki\":false,
- \"default_branch\":\"main\"
- }")
- if [ "$RESP" = "201" ]; then
- ok "Repository created: https://github.com/$GITHUB_USERNAME/$REPO_NAME"
- elif [ "$RESP" = "422" ]; then
- warn "Repository already exists — continuing."
- else
- cat /tmp/gh_create.json
- err "Unexpected HTTP $RESP from repo creation."
- fi
- # ── Step 2: Push main + all tags ──────────────────────────────────────────────
- echo ""
- echo "══════════════════════════════════════════════"
- echo " STEP 2 · Push main branch + tags"
- echo "══════════════════════════════════════════════"
- REMOTE_URL="https://${GITHUB_TOKEN}@github.com/${GITHUB_USERNAME}/${REPO_NAME}.git"
- git remote remove origin 2>/dev/null || true
- git remote add origin "$REMOTE_URL"
- git branch -M main
- if git push origin main --force; then
- ok "Pushed branch main"
- else
- err "Failed to push main"
- fi
- if git push origin --tags --force; then
- ok "Pushed all tags ($(git tag --list | tr '\n' ' '))"
- else
- err "Failed to push tags"
- fi
- # Clean up token from remote URL
- git remote set-url origin "https://github.com/${GITHUB_USERNAME}/${REPO_NAME}.git"
- # ── Step 3: Create draft GitHub Release for RELEASE_TAG ───────────────────────
- echo ""
- echo "══════════════════════════════════════════════"
- echo " STEP 3 · Create draft release $RELEASE_TAG"
- echo "══════════════════════════════════════════════"
- # Extract changelog section for RELEASE_TAG
- VER="${RELEASE_TAG#v}"
- RELEASE_BODY=$(awk "/^## \[$VER\]/{flag=1; next} /^## \[/{flag=0} flag" CHANGELOG.md || true)
- if [ -z "$RELEASE_BODY" ]; then
- RELEASE_BODY="See CHANGELOG.md for full details."
- fi
- RELEASE_BODY_JSON=$(jq -Rs . <<< "$RELEASE_BODY")
- # Delete existing draft for same tag if any
- EXISTING_ID=$(curl -s -H "$AUTH_HEADER" -H "$ACCEPT" \
- "$API/repos/$GITHUB_USERNAME/$REPO_NAME/releases" \
- | jq -r ".[] | select(.tag_name==\"$RELEASE_TAG\") | .id" | head -1)
- if [ -n "$EXISTING_ID" ]; then
- warn "Deleting existing release id=$EXISTING_ID for $RELEASE_TAG"
- curl -s -X DELETE "$API/repos/$GITHUB_USERNAME/$REPO_NAME/releases/$EXISTING_ID" \
- -H "$AUTH_HEADER" -H "$ACCEPT" > /dev/null
- fi
- RELEASE_RESP=$(curl -s -X POST \
- "$API/repos/$GITHUB_USERNAME/$REPO_NAME/releases" \
- -H "$AUTH_HEADER" -H "$ACCEPT" \
- -d "{
- \"tag_name\":\"$RELEASE_TAG\",
- \"target_commitish\":\"main\",
- \"name\":\"$RELEASE_TITLE\",
- \"body\":$RELEASE_BODY_JSON,
- \"draft\":true,
- \"prerelease\":false
- }")
- RELEASE_ID=$(echo "$RELEASE_RESP" | jq -r '.id // empty')
- UPLOAD_URL=$(echo "$RELEASE_RESP" | jq -r '.upload_url // empty' | sed 's/{.*}//')
- if [ -z "$RELEASE_ID" ]; then
- echo "$RELEASE_RESP"
- err "Failed to create draft release."
- fi
- ok "Draft release created (id=$RELEASE_ID)"
- # ── Step 4: Upload ZIP asset ──────────────────────────────────────────────────
- echo ""
- echo "══════════════════════════════════════════════"
- echo " STEP 4 · Upload $ZIP_ASSET"
- echo "══════════════════════════════════════════════"
- # Locate the zip file (same dir as script, or outputs dir)
- SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
- ZIP_PATH=""
- for candidate in \
- "$SCRIPT_DIR/$ZIP_ASSET" \
- "/mnt/user-data/outputs/$ZIP_ASSET" \
- "$(pwd)/$ZIP_ASSET"; do
- if [ -f "$candidate" ]; then
- ZIP_PATH="$candidate"
- break
- fi
- done
- if [ -z "$ZIP_PATH" ]; then
- warn "Could not find $ZIP_ASSET — skipping upload."
- warn "To upload manually: attach '$ZIP_ASSET' on the draft release page:"
- echo " https://github.com/$GITHUB_USERNAME/$REPO_NAME/releases/edit/$RELEASE_ID"
- else
- UPLOAD_RESP=$(curl -s -X POST \
- "${UPLOAD_URL}?name=${ZIP_ASSET}&label=${ZIP_ASSET}" \
- -H "$AUTH_HEADER" \
- -H "Content-Type: application/zip" \
- --data-binary @"$ZIP_PATH")
- ASSET_URL=$(echo "$UPLOAD_RESP" | jq -r '.browser_download_url // empty')
- if [ -n "$ASSET_URL" ]; then
- ok "Asset uploaded: $ASSET_URL"
- else
- warn "Asset upload may have failed:"
- echo "$UPLOAD_RESP" | jq '.' 2>/dev/null || echo "$UPLOAD_RESP"
- fi
- fi
- # ── Done ──────────────────────────────────────────────────────────────────────
- echo ""
- echo "══════════════════════════════════════════════"
- echo " SUCCESS"
- echo "══════════════════════════════════════════════"
- echo ""
- echo " Repository : https://github.com/$GITHUB_USERNAME/$REPO_NAME"
- echo " Branch : main"
- echo " Tags : $(git tag --list | tr '\n' ' ')"
- echo " Draft release page:"
- echo " https://github.com/$GITHUB_USERNAME/$REPO_NAME/releases/edit/$RELEASE_ID"
- echo ""
- echo " Next steps:"
- echo " 1. Visit the draft release link above."
- echo " 2. Review release notes and attached ZIP."
- echo " 3. Click 'Publish release' when ready."
- echo " 4. For HACS: Settings → Devices & Services → Add Integration → Solar of Things"
- echo ""
|