diff --git a/gitfield-bitbucket b/gitfield-bitbucket index acedb35..0360936 100755 --- a/gitfield-bitbucket +++ b/gitfield-bitbucket @@ -2,143 +2,126 @@ set -euo pipefail IFS=$'\n\t' -# ───────────────────────────────────────────── -# ▓▓ CONFIG -# ───────────────────────────────────────────── -GIT_REMOTE_NAME="bitbucket" +# ╭───────────────────────────────╮ +# │ CONFIG & PATHS │ +# ╰───────────────────────────────╯ +REMOTE_NAME="bitbucket" REPO_NAME=$(basename "$(pwd)") +BB_USER="mrhavens" 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" +APP_PASS_FILE="$HOME/.bitbucket_app_password" -# ───────────────────────────────────────────── -# ▓▓ LOGGING -# ───────────────────────────────────────────── +# ╭───────────────────────────────╮ +# │ 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 -# ───────────────────────────────────────────── +# ╭───────────────────────────────╮ +# │ GIT + SSH PREREQUISITES │ +# ╰───────────────────────────────╯ info "Checking prerequisites..." sudo apt update -qq -sudo apt install -y git curl jq openssh-client >/dev/null +sudo apt install -y git openssh-client curl jq || error "Install failed" -# ───────────────────────────────────────────── -# ▓▓ 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)>" +info "Git identity: $DEFAULT_NAME <$DEFAULT_EMAIL>" -# ───────────────────────────────────────────── -# ▓▓ SSH KEY MANAGEMENT -# ───────────────────────────────────────────── -if [ ! -f "$SSH_KEY" ]; then +# ╭───────────────────────────────╮ +# │ SSH KEY SETUP │ +# ╰───────────────────────────────╯ +if [ ! -f "$HOME/.ssh/id_rsa" ]; then info "Generating new SSH key..." - ssh-keygen -t rsa -b 4096 -C "$DEFAULT_EMAIL" -f "$SSH_KEY" -N "" + ssh-keygen -t rsa -b 4096 -C "$DEFAULT_EMAIL" -f "$HOME/.ssh/id_rsa" -N "" fi eval "$(ssh-agent -s)" -ssh-add "$SSH_KEY" || warn "SSH key already loaded" +ssh-add "$HOME/.ssh/id_rsa" -# ───────────────────────────────────────────── -# ▓▓ 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 +if ! ssh -T git@bitbucket.org 2>&1 | grep -q "authenticated"; then + PUBKEY=$(<"$HOME/.ssh/id_rsa.pub") + info "❗ SSH connection not verified." + echo -e "\n🔐 Add this public key to your Bitbucket account:\n" echo "$PUBKEY" - echo - read -rp "✅ Press [Enter] once you've uploaded the key..." + echo -e "\n→ https://bitbucket.org/account/settings/ssh-keys/" + exit 1 fi -# ───────────────────────────────────────────── -# ▓▓ BITBUCKET AUTH (App Password) -# ───────────────────────────────────────────── -if [ ! -f "$TOKEN_FILE" ]; then +# ╭───────────────────────────────╮ +# │ APP PASSWORD SETUP │ +# ╰───────────────────────────────╯ +if [ ! -f "$APP_PASS_FILE" ]; then + echo -e "\n🔐 Create a Bitbucket App Password with:" + echo " ✅ permissions: Repositories (Read+Write), SSH, and Webhooks" + echo " 🔗 https://bitbucket.org/account/settings/app-passwords/\n" + read -rsp "Paste your Bitbucket App Password: " BB_APP_PASS + echo "$BB_APP_PASS" > "$APP_PASS_FILE" + chmod 600 "$APP_PASS_FILE" 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" +else + BB_APP_PASS=$(<"$APP_PASS_FILE") fi -AUTH=$(<"$TOKEN_FILE") -AUTH_HEADER="Authorization: Basic $(echo -n "$AUTH" | base64)" +# ╭───────────────────────────────╮ +# │ BITBUCKET API CALL │ +# ╰───────────────────────────────╯ +API_URL="https://api.bitbucket.org/2.0/repositories/$BB_USER/$REPO_NAME" -# ───────────────────────────────────────────── -# ▓▓ INIT GIT REPO -# ───────────────────────────────────────────── -if [ ! -d ".git" ]; then - info "Initializing Git repository..." +REPO_EXISTS=$(curl -s -u "$BB_USER:$BB_APP_PASS" "$API_URL" | jq -r .type || echo "none") +if [[ "$REPO_EXISTS" != "repository" ]]; then + info "Creating Bitbucket repository '$REPO_NAME' via API..." + curl -s -X POST "$API_URL" \ + -u "$BB_USER:$BB_APP_PASS" \ + -H "Content-Type: application/json" \ + -d "{\"scm\": \"git\", \"is_private\": false, \"project\": {\"key\": \"~$BB_USER\"}}" | + grep -q "\"type\": \"repository\"" || warn "⚠️ Repo may already exist or failed to create (HTTP 401)" +else + info "Bitbucket repository already exists." +fi + +REMOTE_URL="git@bitbucket.org:$BB_USER/$REPO_NAME.git" +if ! git remote get-url "$REMOTE_NAME" &>/dev/null; then + git remote add "$REMOTE_NAME" "$REMOTE_URL" + info "Remote added: $REMOTE_NAME → $REMOTE_URL" +else + info "Remote already set: $REMOTE_NAME → $(git remote get-url "$REMOTE_NAME")" +fi + +# ╭───────────────────────────────╮ +# │ GIT INITIALIZATION │ +# ╰───────────────────────────────╯ +if [ ! -d .git ]; then git init git add . || warn "Nothing to add" git commit -m "Initial commit" || warn "Nothing to commit" -else - info "Git repository already exists." + info "Git repository initialized and committed" 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")" +if ! git rev-parse HEAD &>/dev/null; then + git add . && git commit -m "Initial commit" fi -# ───────────────────────────────────────────── -# ▓▓ COMMIT & PUSH -# ───────────────────────────────────────────── +# ╭───────────────────────────────╮ +# │ COMMIT + PUSH LOGIC │ +# ╰───────────────────────────────╯ 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" + 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) +BRANCH=$(git rev-parse --abbrev-ref 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" + info "Pushing with upstream..." + git push -u "$REMOTE_NAME" "$BRANCH" || error "Push failed" else - info "Pushing to '$GIT_REMOTE_NAME/$BRANCH'..." - git push "$GIT_REMOTE_NAME" "$BRANCH" || error "Push failed" + info "Pushing to $REMOTE_NAME/$BRANCH..." + git push "$REMOTE_NAME" "$BRANCH" || error "Push failed" fi -info "🎉 Bitbucket publish complete!" +info "✓ Bitbucket push completed successfully."