#!/bin/bash set -euo pipefail IFS=$'\n\t' # ───────────────────────────────────────────── # ▓▓ CONFIG # ───────────────────────────────────────────── GIT_REMOTE_NAME="bitbucket" REPO_NAME=$(basename "$(pwd)") DEFAULT_NAME="Mark Randall Havens" DEFAULT_EMAIL="mark.r.havens@gmail.com" USERNAME="mrhavens" BITBUCKET_API="https://api.bitbucket.org/2.0" BITBUCKET_SSH="git@bitbucket.org:$USERNAME/$REPO_NAME.git" TOKEN_FILE="$HOME/.bitbucket_app_password" SSH_KEY="$HOME/.ssh/id_rsa" SSH_PUB="$HOME/.ssh/id_rsa.pub" # ───────────────────────────────────────────── # ▓▓ LOGGING # ───────────────────────────────────────────── info() { echo -e "\e[1;34m[INFO]\e[0m $*"; } warn() { echo -e "\e[1;33m[WARN]\e[0m $*"; } error() { echo -e "\e[1;31m[ERROR]\e[0m $*" >&2; exit 1; } # ───────────────────────────────────────────── # ▓▓ DEPENDENCIES # ───────────────────────────────────────────── info "Checking prerequisites..." sudo apt update -qq sudo apt install -y git curl jq openssh-client >/dev/null # ───────────────────────────────────────────── # ▓▓ GIT CONFIGURATION # ───────────────────────────────────────────── git config --global user.name "$DEFAULT_NAME" git config --global user.email "$DEFAULT_EMAIL" info "Git identity: $(git config --global user.name) <$(git config --global user.email)>" # ───────────────────────────────────────────── # ▓▓ SSH KEY MANAGEMENT # ───────────────────────────────────────────── if [ ! -f "$SSH_KEY" ]; then info "Generating new SSH key..." ssh-keygen -t rsa -b 4096 -C "$DEFAULT_EMAIL" -f "$SSH_KEY" -N "" fi eval "$(ssh-agent -s)" ssh-add "$SSH_KEY" || warn "SSH key already loaded" # ───────────────────────────────────────────── # ▓▓ TEST SSH TO BITBUCKET # ───────────────────────────────────────────── info "Testing SSH connection to Bitbucket..." if ! ssh -o StrictHostKeyChecking=no -T git@bitbucket.org 2>&1 | grep -q "authenticated"; then PUBKEY=$(<"$SSH_PUB") echo warn "SSH key not yet registered with Bitbucket." echo "🔐 Please upload the following key manually to:" echo " https://bitbucket.org/account/settings/ssh-keys/" echo echo "$PUBKEY" echo read -rp "✅ Press [Enter] once you've uploaded the key..." fi # ───────────────────────────────────────────── # ▓▓ BITBUCKET AUTH (App Password) # ───────────────────────────────────────────── if [ ! -f "$TOKEN_FILE" ]; then echo echo "🔑 Create a Bitbucket App Password with:" echo " ✅ permissions: Repositories (Read+Write), SSH, and Webhooks" echo " 🌐 https://bitbucket.org/account/settings/app-passwords/" echo read -rp "🧑 Username [$USERNAME]: " input_user read -rsp "🔐 App Password: " input_pass && echo echo "$input_user:$input_pass" > "$TOKEN_FILE" chmod 600 "$TOKEN_FILE" info "✓ App password stored at $TOKEN_FILE" fi AUTH=$(<"$TOKEN_FILE") AUTH_HEADER="Authorization: Basic $(echo -n "$AUTH" | base64)" # ───────────────────────────────────────────── # ▓▓ INIT GIT REPO # ───────────────────────────────────────────── if [ ! -d ".git" ]; then info "Initializing Git repository..." git init git add . || warn "Nothing to add" git commit -m "Initial commit" || warn "Nothing to commit" else info "Git repository already exists." fi # Ensure HEAD exists git rev-parse HEAD >/dev/null 2>&1 || { git add . && git commit -m "Initial commit" || warn "Nothing to commit" } # ───────────────────────────────────────────── # ▓▓ CREATE REMOTE REPO # ───────────────────────────────────────────── if ! git remote get-url "$GIT_REMOTE_NAME" &>/dev/null; then info "Creating Bitbucket repository '$REPO_NAME' via API..." CREATE_RESPONSE=$(curl -s -w "%{http_code}" -o /tmp/bb_create.json \ -X POST "$BITBUCKET_API/repositories/$USERNAME/$REPO_NAME" \ -H "$AUTH_HEADER" -H "Content-Type: application/json" \ -d "{\"scm\": \"git\", \"is_private\": false}") HTTP_CODE="${CREATE_RESPONSE:(-3)}" if [ "$HTTP_CODE" == "200" ] || [ "$HTTP_CODE" == "201" ]; then info "✓ Bitbucket repo created." else warn "⚠️ Repo may already exist or failed to create (HTTP $HTTP_CODE)" fi git remote add "$GIT_REMOTE_NAME" "$BITBUCKET_SSH" info "Remote added: $BITBUCKET_SSH" else info "Remote already set: $(git remote get-url "$GIT_REMOTE_NAME")" fi # ───────────────────────────────────────────── # ▓▓ COMMIT & PUSH # ───────────────────────────────────────────── if ! git diff --quiet || ! git diff --cached --quiet; then git add . && git commit -m "Update: $(date '+%Y-%m-%d %H:%M:%S')" || warn "Nothing to commit" else info "No uncommitted changes." fi BRANCH=$(git symbolic-ref --short HEAD) if ! git config --get branch."$BRANCH".remote &>/dev/null; then info "Setting upstream and pushing branch '$BRANCH'..." git push -u "$GIT_REMOTE_NAME" "$BRANCH" || error "Push failed" else info "Pushing to '$GIT_REMOTE_NAME/$BRANCH'..." git push "$GIT_REMOTE_NAME" "$BRANCH" || error "Push failed" fi info "🎉 Bitbucket publish complete!"