Initial commit: Add install scripts and README

This commit is contained in:
2026-04-03 01:04:30 +00:00
commit 8e50eef945
4 changed files with 598 additions and 0 deletions

4
.gitattributes vendored Normal file
View File

@@ -0,0 +1,4 @@
# Exclude all files from auto-generated source archives (zip/tar.gz)
# This ensures releases only contain the pre-built binaries, not source code
* export-ignore
.gitattributes export-ignore

34
README.md Normal file
View File

@@ -0,0 +1,34 @@
# Aideris CLI Distribution
Official distribution repository for Aideris CLI binaries and installation scripts.
## Quick Install
```bash
curl -fsSL https://gitea.clickthings.net/whuang/aideris-cli-dist/raw/branch/main/install.sh | sh
```
## Install Specific Version
```bash
curl -fsSL https://gitea.clickthings.net/whuang/aideris-cli-dist/raw/branch/main/install.sh | sh -s -- --version v1.0.0
```
## Manual Installation
1. Download the binary for your platform from [Releases](https://gitea.clickthings.net/whuang/aideris-cli-dist/releases)
2. Make it executable: `chmod +x aideris-cli-*`
3. Move to PATH: `sudo mv aideris-cli-* /usr/local/bin/aideris-cli`
## Supported Platforms
- Linux (amd64, arm64, armv7)
- macOS (amd64, arm64)
## Source Code
Source code is available at: [whuang/aideris-cli-go](https://gitea.clickthings.net/whuang/aideris-cli-go)
## Documentation
For full documentation, visit the [main repository](https://gitea.clickthings.net/whuang/aideris-cli-go).

359
install.sh Executable file
View File

@@ -0,0 +1,359 @@
#!/bin/sh
# install.sh - Install Aideris CLI from Gitea releases
# Usage: curl -fsSL https://gitea.clickthings.net/whuang/aideris-cli-dist/raw/branch/main/install.sh | sh
# Or: ./install.sh [--version VERSION] [--bin-dir DIR] [--dry-run] [--verbose]
set -e
# Configuration
REPO_OWNER="whuang"
REPO_NAME="aideris-cli-dist"
GITEA_URL="https://gitea.clickthings.net"
BINARY_NAME="aideris-cli"
DEFAULT_BIN_DIR="/usr/local/bin"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# Parse command line arguments
VERSION=""
BIN_DIR=""
DRY_RUN=false
VERBOSE=false
FORCE=false
usage() {
cat << 'EOF'
Usage: install.sh [OPTIONS]
Install Aideris CLI from Gitea releases.
Options:
--version VERSION Install specific version (default: latest)
--bin-dir DIR Installation directory (default: /usr/local/bin)
--dry-run Show what would be done without executing
--verbose Enable verbose output
--force Force reinstall even if already installed
-h, --help Show this help message
Examples:
# Install latest version
curl -fsSL https://gitea.clickthings.net/whuang/aideris-cli-dist/raw/branch/main/install.sh | sh
# Install specific version
./install.sh --version v1.0.0
# Install to custom directory
./install.sh --bin-dir ~/.local/bin
# Dry run to preview changes
./install.sh --dry-run
EOF
exit 0
}
while [ $# -gt 0 ]; do
case "$1" in
--version)
VERSION="$2"
shift 2
;;
--bin-dir)
BIN_DIR="$2"
shift 2
;;
--dry-run)
DRY_RUN=true
shift
;;
--verbose)
VERBOSE=true
shift
;;
--force)
FORCE=true
shift
;;
-h|--help)
usage
;;
*)
echo "Unknown option: $1"
echo "Use --help for usage information"
exit 1
;;
esac
done
# Set defaults
BIN_DIR="${BIN_DIR:-$DEFAULT_BIN_DIR}"
# Logging functions
log() {
printf "${BLUE}[INFO]${NC} %s\n" "$1"
}
log_success() {
printf "${GREEN}[SUCCESS]${NC} %s\n" "$1"
}
log_warn() {
printf "${YELLOW}[WARN]${NC} %s\n" "$1"
}
log_error() {
printf "${RED}[ERROR]${NC} %s\n" "$1"
}
debug() {
if [ "$VERBOSE" = true ]; then
printf "${BLUE}[DEBUG]${NC} %s\n" "$1"
fi
}
# Detect OS and Architecture
detect_platform() {
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m)
case "$ARCH" in
x86_64|amd64)
ARCH="amd64"
;;
aarch64|arm64)
ARCH="arm64"
;;
armv7l|armv7)
ARCH="armv7"
;;
i386|i686)
ARCH="386"
;;
*)
log_error "Unsupported architecture: $ARCH"
exit 1
;;
esac
case "$OS" in
linux)
OS="linux"
;;
darwin)
OS="darwin"
;;
*)
log_error "Unsupported operating system: $OS"
exit 1
;;
esac
debug "Detected platform: $OS/$ARCH"
}
# Check if binary is already installed
check_existing_installation() {
if [ -f "${BIN_DIR}/${BINARY_NAME}" ] && [ "$FORCE" = false ]; then
log_warn "${BINARY_NAME} is already installed at ${BIN_DIR}/${BINARY_NAME}"
log "Use --force to reinstall or --version to install a specific version"
exit 0
fi
}
# Get the latest version from Gitea
get_latest_version() {
if [ -n "$VERSION" ]; then
return 0
fi
log "Fetching latest version from Gitea..."
# Try to get latest release from Gitea API
API_URL="${GITEA_URL}/api/v1/repos/${REPO_OWNER}/${REPO_NAME}/releases/latest"
debug "API URL: $API_URL"
LATEST_RELEASE=$(curl -fsSL "$API_URL" 2>/dev/null || echo "")
if [ -n "$LATEST_RELEASE" ]; then
VERSION=$(echo "$LATEST_RELEASE" | grep -o '"tag_name":"[^"]*"' | head -1 | cut -d'"' -f4)
if [ -n "$VERSION" ]; then
debug "Latest version: $VERSION"
return 0
fi
fi
# Fallback: try to get from tags
TAGS_URL="${GITEA_URL}/api/v1/repos/${REPO_OWNER}/${REPO_NAME}/tags"
debug "Tags URL: $TAGS_URL"
TAGS=$(curl -fsSL "$TAGS_URL" 2>/dev/null || echo "")
if [ -n "$TAGS" ]; then
VERSION=$(echo "$TAGS" | grep -o '"name":"[^"]*"' | head -1 | cut -d'"' -f4)
if [ -n "$VERSION" ]; then
debug "Latest tag: $VERSION"
return 0
fi
fi
log_error "Could not determine latest version. Please specify --version."
exit 1
}
# Build download URL
build_download_url() {
# Remove 'v' prefix if present for filename
VERSION_NUM="${VERSION#v}"
# Construct the download URL
# Format: https://gitea.example.com/owner/repo/releases/download/v1.0.0/aideris-cli-linux-amd64
DOWNLOAD_URL="${GITEA_URL}/${REPO_OWNER}/${REPO_NAME}/releases/download/${VERSION}/${BINARY_NAME}-${OS}-${ARCH}"
debug "Download URL: $DOWNLOAD_URL"
}
# Download and install
download_and_install() {
if [ "$DRY_RUN" = true ]; then
log "[DRY RUN] Would download from: $DOWNLOAD_URL"
log "[DRY RUN] Would install to: ${BIN_DIR}/${BINARY_NAME}"
return 0
fi
# Create temp directory for download
TEMP_DIR=$(mktemp -d)
DOWNLOAD_PATH="${TEMP_DIR}/${BINARY_NAME}"
log "Downloading ${BINARY_NAME} ${VERSION} for ${OS}/${ARCH}..."
debug "Downloading to: $DOWNLOAD_PATH"
# Download the binary
HTTP_CODE=$(curl -fsSL -w "%{http_code}" -o "$DOWNLOAD_PATH" "$DOWNLOAD_URL" 2>/dev/null || echo "000")
if [ "$HTTP_CODE" != "200" ]; then
rm -f "$DOWNLOAD_PATH"
log_error "Failed to download binary (HTTP $HTTP_CODE)"
log_error "URL: $DOWNLOAD_URL"
log "Available platforms are typically:"
log " - aideris-cli-linux-amd64"
log " - aideris-cli-linux-arm64"
log " - aideris-cli-darwin-amd64"
log " - aideris-cli-darwin-arm64"
rm -rf "$TEMP_DIR"
exit 1
fi
# Make executable
chmod +x "$DOWNLOAD_PATH"
# Verify binary is valid ELF/Mach-O
if ! file "$DOWNLOAD_PATH" | grep -qE "(ELF|Mach-O)"; then
log_warn "Binary file type check failed (may still be valid)"
debug "File type: $(file "$DOWNLOAD_PATH")"
fi
# Create bin directory if it doesn't exist
if [ ! -d "$BIN_DIR" ]; then
log "Creating directory: $BIN_DIR"
if [ "$BIN_DIR" = "$DEFAULT_BIN_DIR" ]; then
# For system directories, need sudo
log "This requires root privileges."
echo -n "Use sudo? [y/N]: "
read -r answer
case "$answer" in
[yY]|[yY][eE][sS])
sudo mkdir -p "$BIN_DIR"
;;
*)
rm -rf "$TEMP_DIR"
log_error "Installation cancelled"
exit 1
;;
esac
else
mkdir -p "$BIN_DIR"
fi
fi
# Install the binary
log "Installing ${BINARY_NAME} to ${BIN_DIR}..."
if [ "$BIN_DIR" = "$DEFAULT_BIN_DIR" ] && [ ! -w "$BIN_DIR" ]; then
sudo cp "$DOWNLOAD_PATH" "${BIN_DIR}/${BINARY_NAME}"
sudo chmod 755 "${BIN_DIR}/${BINARY_NAME}"
else
cp "$DOWNLOAD_PATH" "${BIN_DIR}/${BINARY_NAME}"
chmod 755 "${BIN_DIR}/${BINARY_NAME}"
fi
# Cleanup
rm -rf "$TEMP_DIR"
}
# Verify installation
verify_installation() {
if [ "$DRY_RUN" = true ]; then
log "[DRY RUN] Would verify installation"
return 0
fi
if [ -f "${BIN_DIR}/${BINARY_NAME}" ]; then
log_success "Installation complete!"
# Check if bin dir is in PATH
case ":$PATH:" in
*":${BIN_DIR}:"*)
;;
*)
log_warn "${BIN_DIR} is not in your PATH"
log "Add it with: export PATH=\"${BIN_DIR}:\$PATH\""
;;
esac
# Show version
log "Installing ${BINARY_NAME} version ${VERSION} to ${BIN_DIR}"
echo ""
echo "Verify installation with:"
echo " ${BIN_DIR}/${BINARY_NAME} --help"
echo ""
echo "Quick start:"
echo " ${BINARY_NAME} onboard --email \"your@email.com\""
else
log_error "Installation failed - binary not found at ${BIN_DIR}/${BINARY_NAME}"
exit 1
fi
}
# Main execution
main() {
echo ""
echo "========================================"
echo " Aideris CLI Installer"
echo "========================================"
echo ""
# Detect platform
detect_platform
log "Platform detected: ${OS}/${ARCH}"
# Check existing installation
check_existing_installation
# Get version
get_latest_version
log "Target version: ${VERSION}"
# Build download URL
build_download_url
# Download and install
download_and_install
# Verify installation
verify_installation
}
# Run main
main

201
push-release.sh Executable file
View File

@@ -0,0 +1,201 @@
#!/bin/bash
# push-release.sh - Push an existing release to Gitea
# Usage: ./push-release.sh --version v1.0.0 --gitea-token TOKEN
set -e
# Configuration
BINARY_NAME="aideris-cli"
GITEA_URL="https://gitea.clickthings.net"
REPO_OWNER="whuang"
REPO_NAME="aideris-cli-dist"
# Parse arguments
VERSION=""
GITEA_TOKEN=""
while [ $# -gt 0 ]; do
case "$1" in
--version)
VERSION="$2"
shift 2
;;
--gitea-token)
GITEA_TOKEN="$2"
shift 2
;;
*)
echo "Unknown option: $1"
exit 1
;;
esac
done
if [ -z "$VERSION" ]; then
echo "Error: --version is required"
echo "Usage: ./push-release.sh --version v1.0.0 --gitea-token TOKEN"
exit 1
fi
if [ -z "$GITEA_TOKEN" ]; then
echo "Error: --gitea-token is required"
echo "Usage: ./push-release.sh --version v1.0.0 --gitea-token TOKEN"
exit 1
fi
BUILD_DIR="dist/${VERSION}"
if [ ! -d "$BUILD_DIR" ]; then
echo "Error: Build directory not found: $BUILD_DIR"
echo "Run the build first to create binaries"
exit 1
fi
echo "========================================"
echo " Aideris CLI Release Push"
echo "========================================"
echo ""
echo "Version: $VERSION"
echo "Build dir: $BUILD_DIR"
echo ""
# Check if release notes exist
RELEASE_NOTES="${BUILD_DIR}/RELEASE_NOTES.md"
if [ ! -f "$RELEASE_NOTES" ]; then
echo "Warning: Release notes not found at $RELEASE_NOTES"
echo "Creating default release notes..."
cat > "$RELEASE_NOTES" << EOF
# Aideris CLI ${VERSION}
## Installation
### Quick Install
\`\`\`bash
curl -fsSL https://gitea.clickthings.net/${REPO_OWNER}/${REPO_NAME}/raw/branch/main/install.sh | sh
\`\`\`
### Manual Download
Download the binary for your platform from the Assets below.
EOF
fi
# Check if checksums exist
CHECKSUMS_FILE="${BUILD_DIR}/checksums.txt"
if [ ! -f "$CHECKSUMS_FILE" ]; then
echo "Generating checksums..."
cd "$BUILD_DIR"
sha256sum ${BINARY_NAME}-* > checksums.txt 2>/dev/null || true
cd - > /dev/null
fi
echo "Pushing to Gitea..."
# Function to make API calls with error handling
gitea_api() {
local method=$1
local endpoint=$2
local data=$3
if [ -z "$data" ]; then
curl -fsSL -X "$method" \
-H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: application/json" \
"${GITEA_URL}/api/v1/repos/${REPO_OWNER}/${REPO_NAME}${endpoint}" 2>&1
else
curl -fsSL -X "$method" \
-H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: application/json" \
-d "$data" \
"${GITEA_URL}/api/v1/repos/${REPO_OWNER}/${REPO_NAME}${endpoint}" 2>&1
fi
}
# Check if release already exists
echo "Checking for existing release..."
EXISTING_RELEASE=$(gitea_api "GET" "/releases/tags/${VERSION}" 2>/dev/null || echo "{}")
RELEASE_ID=$(echo "$EXISTING_RELEASE" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2)
if [ -n "$RELEASE_ID" ]; then
echo " ✓ Found existing release: ID $RELEASE_ID"
else
echo " Creating new release..."
# Escape release notes for JSON
ESCAPED_BODY=$(cat "$RELEASE_NOTES" | python3 -c 'import json,sys; print(json.dumps(sys.stdin.read())[1:-1])' 2>/dev/null || cat "$RELEASE_NOTES" | sed 's/"/\\"/g' | tr '\n' ' ')
RELEASE_PAYLOAD=$(cat << EOF
{
"tag_name": "${VERSION}",
"name": "${VERSION}",
"body": "${ESCAPED_BODY}",
"draft": false,
"prerelease": false
}
EOF
)
CREATE_RESPONSE=$(gitea_api "POST" "/releases" "$RELEASE_PAYLOAD" 2>&1 || true)
RELEASE_ID=$(echo "$CREATE_RESPONSE" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2)
if [ -n "$RELEASE_ID" ]; then
echo " ✓ Release created: ID $RELEASE_ID"
else
echo " ✗ Failed to create release"
echo "Response: $CREATE_RESPONSE"
exit 1
fi
fi
# Get list of existing assets
echo ""
echo "Fetching existing assets..."
EXISTING_ASSETS=$(gitea_api "GET" "/releases/${RELEASE_ID}/assets" 2>/dev/null || echo "[]")
# Upload assets
echo ""
echo "Uploading assets..."
upload_count=0
skip_count=0
for asset in ${BUILD_DIR}/${BINARY_NAME}-* ${BUILD_DIR}/checksums.txt; do
if [ -f "$asset" ]; then
FILENAME=$(basename "$asset")
# Check if asset already exists
ASSET_EXISTS=$(echo "$EXISTING_ASSETS" | grep -o "\"name\":\"${FILENAME}\"" | head -1 || echo "")
if [ -n "$ASSET_EXISTS" ]; then
echo " ⊘ Skipping (exists): $FILENAME"
skip_count=$((skip_count + 1))
else
echo " ↑ Uploading: $FILENAME..."
UPLOAD_RESPONSE=$(curl -fsSL -X POST \
-H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: application/octet-stream" \
--data-binary @"$asset" \
"${GITEA_URL}/api/v1/repos/${REPO_OWNER}/${REPO_NAME}/releases/${RELEASE_ID}/assets?name=${FILENAME}" 2>&1 || true)
UPLOADED_ID=$(echo "$UPLOAD_RESPONSE" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2)
if [ -n "$UPLOADED_ID" ]; then
echo " ✓ Uploaded: $FILENAME"
upload_count=$((upload_count + 1))
else
echo " ✗ Failed to upload: $FILENAME"
echo " Response: $UPLOAD_RESPONSE"
fi
fi
fi
done
echo ""
echo "========================================"
echo " Push Complete"
echo "========================================"
echo ""
echo "Uploaded: $upload_count asset(s)"
echo "Skipped: $skip_count existing asset(s)"
echo ""
echo "Release URL: ${GITEA_URL}/${REPO_OWNER}/${REPO_NAME}/releases/tag/${VERSION}"