gitfield-gitlab
1 #!/bin/bash 2 IFS=$'\n\t' 3 4 # Configuration 5 GIT_REMOTE_NAME="gitlab" 6 REPO_NAME=$(basename "$(pwd)") || REPO_NAME="Unknown" 7 DEFAULT_NAME="Mark Randall Havens" 8 DEFAULT_EMAIL="mark.r.havens@gmail.com" 9 GITLAB_WEB="https://gitlab.com" 10 GITLAB_API="$GITLAB_WEB/api/v4" 11 GITLAB_SSH="git@gitlab.com" 12 TOKEN_FILE="$HOME/.gitfield_token" 13 SCRIPT_VERSION="1.0" 14 MARKDOWN_FILE="$(git rev-parse --show-toplevel)/.gitfield/gitlab.sigil.md" && mkdir -p "$(dirname "$MARKDOWN_FILE")" 15 16 info() { echo -e "\e[1;34m[INFO]\e[0m $*"; } 17 warn() { echo -e "\e[1;33m[WARN]\e[0m $*"; } 18 error() { echo -e "\e[1;31m[ERROR]\e[0m $*" >&2; exit 1; } 19 20 # Function to generate markdown file 21 generate_markdown() { 22 info "Generating markdown file: $MARKDOWN_FILE" 23 TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S' 2>/dev/null || echo "Unknown") 24 DEFAULT_BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null || echo "Unknown") 25 REPO_PATH=$(git rev-parse --show-toplevel) 26 LATEST_SHA=$(git rev-parse HEAD 2>/dev/null || echo "Unknown") 27 LAST_COMMIT_MSG=$(git log -1 --pretty=format:"%s" 2>/dev/null || echo "Unknown") 28 LAST_COMMIT_DATE=$(git log -1 --pretty=format:"%ad" 2>/dev/null || echo "Unknown") 29 LAST_COMMIT_AUTHOR=$(git log -1 --pretty=format:"%an <%ae>" 2>/dev/null || echo "Unknown") 30 TOTAL_COMMITS=$(git rev-list --count HEAD 2>/dev/null || echo "Unknown") 31 TRACKED_FILES=$(git ls-files 2>/dev/null | wc -l 2>/dev/null || echo "Unknown") 32 UNCOMMITTED=$(if ! git diff --quiet 2>/dev/null || ! git diff --cached --quiet 2>/dev/null; then echo "Yes"; else echo "No"; fi) 33 LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "None") 34 HOSTNAME=$(hostname 2>/dev/null || echo "Unknown") 35 CURRENT_USER=$(whoami 2>/dev/null || echo "Unknown") 36 TIMEZONE=$(date +%Z 2>/dev/null || echo "Unknown") 37 OS_NAME=$(uname -s 2>/dev/null || echo "Unknown") 38 KERNEL_VERSION=$(uname -r 2>/dev/null || echo "Unknown") 39 ARCHITECTURE=$(uname -m 2>/dev/null || echo "Unknown") 40 OS_PRETTY_NAME=$(grep PRETTY_NAME /etc/os-release 2>/dev/null | cut -d= -f2 | tr -d '"' || echo "Unknown") 41 DOCKER_CHECK=$(grep -qE '/docker|/lxc' /proc/1/cgroup 2>/dev/null && echo "Yes" || echo "No") 42 WSL_CHECK=$(grep -qi microsoft /proc/version 2>/dev/null && echo "Yes" || echo "No") 43 VM_CHECK=$(systemd-detect-virt 2>/dev/null || echo "Unknown") 44 UPTIME=$(uptime -p 2>/dev/null || echo "Unknown") 45 MAC_ADDR=$(ip link 2>/dev/null | awk '/ether/ {print $2}' | head -n 1 2>/dev/null || echo "Unknown") 46 LOCAL_IP=$(hostname -I 2>/dev/null | awk '{print $1}' 2>/dev/null || echo "Unknown") 47 CPU_MODEL=$(grep -m1 'model name' /proc/cpuinfo 2>/dev/null | cut -d: -f2 | sed 's/^ //' 2>/dev/null || echo "Unknown") 48 RAM_GB=$(awk '/MemTotal/ {printf "%.2f", $2/1024/1024}' /proc/meminfo 2>/dev/null || echo "Unknown") 49 WEB_LINK="$GITLAB_WEB/$USERNAME/$REPO_NAME" 50 51 cat > "$MARKDOWN_FILE" <<EOF 52 # š GitLab Repository Link 53 54 - **Repo Name**: \`$REPO_NAME\` 55 - **GitLab User**: \`$USERNAME\` 56 - **Remote URL**: [$WEB_LINK]($WEB_LINK) 57 - **Local Repo Path**: \`$REPO_PATH\` 58 - **Remote Label**: \`$GIT_REMOTE_NAME\` 59 - **Default Branch**: \`$DEFAULT_BRANCH\` 60 - **Repo Created**: \`$TIMESTAMP\` 61 62 --- 63 64 ## š¦ Commit Info 65 66 - **This Commit Timestamp**: \`$TIMESTAMP\` 67 - **This Commit SHA**: \`$LATEST_SHA\` 68 - **Last Commit Message**: \`$LAST_COMMIT_MSG\` 69 - **Last Commit Author**: \`$LAST_COMMIT_AUTHOR\` 70 - **Last Commit Date**: \`$LAST_COMMIT_DATE\` 71 - **This Commit URL**: [$WEB_LINK/-/commit/$LATEST_SHA]($WEB_LINK/-/commit/$LATEST_SHA) 72 73 --- 74 75 ## š Repo Status 76 77 - **Total Commits**: \`$TOTAL_COMMITS\` 78 - **Tracked Files**: \`$TRACKED_FILES\` 79 - **Uncommitted Changes**: \`$UNCOMMITTED\` 80 - **Latest Tag**: \`$LATEST_TAG\` 81 82 --- 83 84 ## š§½ Environment 85 86 - **Host Machine**: \`$HOSTNAME\` 87 - **Current User**: \`$CURRENT_USER\` 88 - **Time Zone**: \`$TIMEZONE\` 89 - **Script Version**: \`v$SCRIPT_VERSION\` 90 91 --- 92 93 ## 𧬠Hardware & OS Fingerprint 94 95 - **OS Name**: \`$OS_NAME\` 96 - **OS Version**: \`$OS_PRETTY_NAME\` 97 - **Kernel Version**: \`$KERNEL_VERSION\` 98 - **Architecture**: \`$ARCHITECTURE\` 99 - **Running in Docker**: \`$DOCKER_CHECK\` 100 - **Running in WSL**: \`$WSL_CHECK\` 101 - **Virtual Machine**: \`$VM_CHECK\` 102 - **System Uptime**: \`$UPTIME\` 103 - **MAC Address**: \`$MAC_ADDR\` 104 - **Local IP**: \`$LOCAL_IP\` 105 - **CPU Model**: \`$CPU_MODEL\` 106 - **Total RAM (GB)**: \`$RAM_GB\` 107 108 --- 109 110 _Auto-generated by \`gitfield-gitlab\` push script._ 111 EOF 112 } 113 114 # Main script 115 set -euo pipefail 116 117 # Token Handling 118 RESET_TOKEN=false 119 if [[ "${1:-}" == "--reset-token" ]]; then 120 RESET_TOKEN=true 121 rm -f "$TOKEN_FILE" 2>/dev/null || warn "Failed to remove token file" 122 info "Token reset requested." 123 fi 124 125 if [ -f "$TOKEN_FILE" ] && [ "$RESET_TOKEN" = false ]; then 126 TOKEN=$(cat "$TOKEN_FILE" 2>/dev/null || error "Failed to read token file") 127 info "Using cached token from $TOKEN_FILE" 128 else 129 echo 130 echo "š Paste your GitLab Personal Access Token (scopes: api, read_user, write_repository, write_ssh_key)" 131 echo "ā Generate at: $GITLAB_WEB/-/user_settings/personal_access_tokens" 132 read -rp "š Token: " TOKEN 133 echo "$TOKEN" > "$TOKEN_FILE" 2>/dev/null || warn "Failed to save token file" 134 chmod 600 "$TOKEN_FILE" 2>/dev/null || warn "Failed to set token file permissions" 135 info "Token saved for future use at $TOKEN_FILE" 136 fi 137 138 # Install Dependencies 139 sudo apt update -qq 2>/dev/null || warn "apt update failed, continuing..." 140 sudo apt install -y git curl jq openssh-client lsb-release 2>/dev/null || warn "Tool install failed, continuing..." 141 142 # Identity 143 git config --global user.name "$DEFAULT_NAME" 2>/dev/null || warn "Failed to set git user name" 144 git config --global user.email "$DEFAULT_EMAIL" 2>/dev/null || warn "Failed to set git user email" 145 info "Git identity set to: $DEFAULT_NAME <$DEFAULT_EMAIL>" 146 147 # Git Initialization 148 if [ ! -d .git ]; then 149 git init 2>/dev/null || warn "Git init failed, continuing..." 150 git add . 2>/dev/null || warn "Nothing to add" 151 git commit -m "Initial commit" 2>/dev/null || warn "Nothing to commit" 152 fi 153 154 if ! git rev-parse HEAD &>/dev/null; then 155 git add . 2>/dev/null && git commit -m "Initial commit" 2>/dev/null || warn "Nothing to commit" 156 fi 157 158 # SSH Setup 159 if [ ! -f ~/.ssh/id_rsa ]; then 160 ssh-keygen -t rsa -b 4096 -C "$DEFAULT_EMAIL" -f ~/.ssh/id_rsa -N "" 2>/dev/null || error "SSH keygen failed" 161 fi 162 163 eval "$(ssh-agent -s 2>/dev/null)" || warn "Failed to start ssh-agent, continuing..." 164 ssh-add ~/.ssh/id_rsa 2>/dev/null || error "Failed to add SSH key" 165 166 # Fetch GitLab Username 167 USERNAME=$(curl -s --header "PRIVATE-TOKEN: $TOKEN" "$GITLAB_API/user" | jq -r '.username' 2>/dev/null) || error "Invalid token" 168 info "GitLab username: $USERNAME" 169 170 # SSH Key Upload to GitLab 171 SSH_TEST_OUTPUT=$(ssh -T "$GITLAB_SSH" 2>&1) 172 if ! echo "$SSH_TEST_OUTPUT" | grep -q "Welcome"; then 173 warn "SSH test failed, attempting to upload SSH key. Output: $SSH_TEST_OUTPUT" 174 PUBKEY=$(cat ~/.ssh/id_rsa.pub 2>/dev/null || warn "Failed to read SSH public key, continuing...") 175 TITLE="AutoKey-$(hostname)-$(date +%s 2>/dev/null || echo 'unknown')" 176 CURL_OUTPUT=$(curl -s --fail -X POST "$GITLAB_API/user/keys" \ 177 -H "PRIVATE-TOKEN: $TOKEN" \ 178 -H "Content-Type: application/json" \ 179 -d "{\"title\": \"$TITLE\", \"key\": \"$PUBKEY\"}" 2>&1) 180 if [[ $? -ne 0 ]]; then 181 warn "SSH key upload failed: $CURL_OUTPUT" 182 else 183 info "SSH key uploaded successfully." 184 sleep 2 185 SSH_TEST_OUTPUT=$(ssh -T "$GITLAB_SSH" 2>&1) 186 if ! echo "$SSH_TEST_OUTPUT" | grep -q "Welcome"; then 187 warn "SSH test still failing after key upload. Output: $SSH_TEST_OUTPUT" 188 else 189 info "SSH test passed after key upload." 190 fi 191 fi 192 else 193 info "SSH test passed: $SSH_TEST_OUTPUT" 194 fi 195 196 # Set Up Remote Repository (non-critical, allow failures) 197 set +e 198 REMOTE_URL="$GITLAB_SSH:$USERNAME/$REPO_NAME.git" 199 info "Checking if remote '$GIT_REMOTE_NAME' exists..." 200 REMOTE_EXISTS=$(git remote get-url "$GIT_REMOTE_NAME" 2>&1) 201 REMOTE_EXIT_CODE=$? 202 info "git remote get-url output: $REMOTE_EXISTS" 203 info "git remote get-url exit code: $REMOTE_EXIT_CODE" 204 205 if [[ $REMOTE_EXIT_CODE -ne 0 ]]; then 206 info "Remote '$GIT_REMOTE_NAME' not found, setting up..." 207 CURL_OUTPUT=$(curl -s --fail -X POST "$GITLAB_API/projects" \ 208 -H "PRIVATE-TOKEN: $TOKEN" \ 209 -H "Content-Type: application/json" \ 210 -d "{\"name\": \"$REPO_NAME\", \"visibility\": \"public\"}" 2>&1) 211 if [[ $? -ne 0 ]]; then 212 warn "Failed to create GitLab project: $CURL_OUTPUT" 213 PROJECT_EXISTS=$(curl -s --header "PRIVATE-TOKEN: $TOKEN" "$GITLAB_API/projects?search=$REPO_NAME" | jq -r '.[] | select(.name == "'"$REPO_NAME"'") | .id' 2>&1) 214 if [[ $? -ne 0 || -z "$PROJECT_EXISTS" ]]; then 215 warn "Project creation failed and project does not exist: $PROJECT_EXISTS" 216 info "Proceeding with remote URL anyway: $REMOTE_URL" 217 else 218 info "Project already exists on GitLab." 219 fi 220 else 221 info "GitLab project created successfully." 222 fi 223 git remote add "$GIT_REMOTE_NAME" "$REMOTE_URL" 2>/dev/null || warn "Failed to add remote, but continuing..." 224 info "Remote set to: $REMOTE_URL" 225 else 226 info "Remote already configured: $REMOTE_EXISTS" 227 fi 228 set -e 229 230 # Generate markdown file (always run this step) 231 generate_markdown 232 233 # Commit and Push (non-critical, allow failures) 234 set +e 235 info "Committing markdown file..." 236 git add "$MARKDOWN_FILE" 2>/dev/null || warn "Failed to add markdown file" 237 git commit -m "GitLab metadata link commit at $TIMESTAMP ā $WEB_LINK/-/commit/$LATEST_SHA" 2>/dev/null || warn "No changes to commit" 238 239 info "Pushing to GitLab..." 240 git push -u "$GIT_REMOTE_NAME" "$DEFAULT_BRANCH" 2>/dev/null || warn "Push to GitLab failed" 241 echo -e "\nš View in browser: $WEB_LINK\n" 242 set -e