Post-Radicle sync at 2025-06-05 01:07:56
This commit is contained in:
parent
d4edf2afd8
commit
bf03d19403
29 changed files with 351 additions and 1 deletions
|
@ -1 +1 @@
|
||||||
17afc86d259877d4000eb078fb7428f8da239673
|
a5758991d67b10e72bb9b8da4131e59461a3bb4b
|
||||||
|
|
|
@ -179,3 +179,4 @@
|
||||||
[2025-05-31 19:12:53] Radicle: https://app.radicle.xyz/nodes/ash.radicle.garden/rad:z45QC21eWL1F43VSbnV9AZbCZrHQJ
|
[2025-05-31 19:12:53] Radicle: https://app.radicle.xyz/nodes/ash.radicle.garden/rad:z45QC21eWL1F43VSbnV9AZbCZrHQJ
|
||||||
[2025-05-31 19:13:04] GitLab: https://gitlab.com/mrhavens/git-sigil
|
[2025-05-31 19:13:04] GitLab: https://gitlab.com/mrhavens/git-sigil
|
||||||
[2025-05-31 19:13:18] Bitbucket: https://bitbucket.org/thefoldwithin/git-sigil
|
[2025-05-31 19:13:18] Bitbucket: https://bitbucket.org/thefoldwithin/git-sigil
|
||||||
|
[2025-06-05 01:07:57] Radicle: https://app.radicle.xyz/nodes/ash.radicle.garden/rad:z45QC21eWL1F43VSbnV9AZbCZrHQJ
|
||||||
|
|
218
bin/gitfield-sync
Executable file
218
bin/gitfield-sync
Executable file
|
@ -0,0 +1,218 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
IFS=$'\n\t'
|
||||||
|
|
||||||
|
# ╭─────────────────────────────────────╮
|
||||||
|
# │ CONFIGURATION │
|
||||||
|
# ╰─────────────────────────────────────╯
|
||||||
|
REPO_PATH=$(git rev-parse --show-toplevel 2>/dev/null) || error "Not inside a Git repository"
|
||||||
|
REPO_NAME=$(basename "$REPO_PATH")
|
||||||
|
GITFIELD_DIR="$REPO_PATH/.gitfield"
|
||||||
|
LOG_FILE="$GITFIELD_DIR/pushed.log"
|
||||||
|
GITFIELD_MD="$REPO_PATH/GITFIELD.md"
|
||||||
|
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
|
||||||
|
SCRIPT_VERSION="1.0"
|
||||||
|
|
||||||
|
# URLs for each platform (derived from existing scripts)
|
||||||
|
GITHUB_URL="https://github.com/mrhavens/$REPO_NAME"
|
||||||
|
GITLAB_URL="https://gitlab.com/mrhavens/$REPO_NAME"
|
||||||
|
BITBUCKET_URL="https://bitbucket.org/thefoldwithin/$REPO_NAME"
|
||||||
|
RADICLE_PROJECT_ID="z45QC21eWL1F43VSbnV9AZbCZrHQJ"
|
||||||
|
RADICLE_URL="https://app.radicle.xyz/nodes/ash.radicle.garden/rad:$RADICLE_PROJECT_ID"
|
||||||
|
|
||||||
|
# ╭─────────────────────────────────────╮
|
||||||
|
# │ LOGGING UTILS │
|
||||||
|
# ╰─────────────────────────────────────╮
|
||||||
|
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; }
|
||||||
|
|
||||||
|
# ╭─────────────────────────────────────╮
|
||||||
|
# │ SCRIPT LOOKUP FUNCTION │
|
||||||
|
# ╰─────────────────────────────────────╮
|
||||||
|
find_script() {
|
||||||
|
local script_name=$1
|
||||||
|
local search_paths=(
|
||||||
|
"."
|
||||||
|
"$REPO_PATH/bin"
|
||||||
|
"$REPO_PATH/gitfield"
|
||||||
|
"$REPO_PATH/gitfieldbin"
|
||||||
|
"$HOME/.local/bin"
|
||||||
|
"$HOME/.local/gitfield"
|
||||||
|
"$HOME/.local/gitfieldbin"
|
||||||
|
"$HOME/.local/bin/gitfield"
|
||||||
|
"$HOME/.local/bin/gitfieldbin"
|
||||||
|
)
|
||||||
|
|
||||||
|
for path in "${search_paths[@]}"; do
|
||||||
|
if [ -x "$path/$script_name" ]; then
|
||||||
|
echo "$path/$script_name"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
error "Script $script_name not found in any search path"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ╭─────────────────────────────────────╮
|
||||||
|
# │ INITIAL SETUP │
|
||||||
|
# ╰─────────────────────────────────────╮
|
||||||
|
# Ensure .gitfield directory exists
|
||||||
|
mkdir -p "$GITFIELD_DIR"
|
||||||
|
|
||||||
|
# Initialize log file if it doesn't exist
|
||||||
|
if [ ! -f "$LOG_FILE" ]; then
|
||||||
|
echo "# Push Log for $REPO_NAME" > "$LOG_FILE"
|
||||||
|
echo "# Generated by gitfield-sync" >> "$LOG_FILE"
|
||||||
|
echo "" >> "$LOG_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ╭─────────────────────────────────────╮
|
||||||
|
# │ GENERATE GITFIELD.MD │
|
||||||
|
# ╰─────────────────────────────────────╮
|
||||||
|
generate_gitfield_md() {
|
||||||
|
info "Generating $GITFIELD_MD..."
|
||||||
|
cat > "$GITFIELD_MD" <<EOF
|
||||||
|
# 🌐 GitField Recursive Multi-Repository Strategy
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The \`$REPO_NAME\` project employs a multi-repository strategy across four distinct platforms: **GitHub**, **GitLab**, **Bitbucket**, and **Radicle**. This approach ensures **redundancy**, **resilience**, and **sovereignty** of the project's data and metadata, protecting against deplatforming risks and preserving the integrity of the work. The strategy is a deliberate response to past deplatforming attempts by individuals such as **Mr. Joel Johnson** ([Mirror post](https://mirror.xyz/neutralizingnarcissism.eth/x40_zDWWrYOJ7nh8Y0fk06_3kNEP0KteSSRjPmXkiGg?utm_medium=social&utm_source=heylink.me)) and **Dr. Peter Gaied** ([Paragraph post](https://paragraph.com/@neutralizingnarcissism/%F0%9F%9C%81-the-narcissistic-messiah)), who have sought to undermine or suppress the work of **Mark Randall Havens** ([Substack post](https://theempathictechnologist.substack.com/p/mark-randall-havens-the-architect)). By distributing the repository across multiple platforms, we ensure its persistence and accessibility.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📍 Repository Platforms
|
||||||
|
|
||||||
|
The following platforms host the \`$REPO_NAME\` repository, each chosen for its unique strengths and contributions to the project's goals.
|
||||||
|
|
||||||
|
### 1. Radicle
|
||||||
|
- **URL**: [$RADICLE_URL]($RADICLE_URL)
|
||||||
|
- **Purpose**: Radicle is a decentralized, peer-to-peer git platform that ensures sovereignty and censorship resistance. It hosts the repository in a distributed network, independent of centralized servers.
|
||||||
|
- **Value**: Protects against deplatforming by eliminating reliance on centralized infrastructure, ensuring the project remains accessible in a decentralized ecosystem.
|
||||||
|
|
||||||
|
### 2. GitLab
|
||||||
|
- **URL**: [$GITLAB_URL]($GITLAB_URL)
|
||||||
|
- **Purpose**: GitLab offers a comprehensive DevOps platform with advanced CI/CD capabilities, private repository options, and robust access controls. It serves as a reliable backup and a platform for advanced automation workflows.
|
||||||
|
- **Value**: Enhances project resilience with its integrated CI/CD pipelines and independent infrastructure, reducing reliance on a single provider.
|
||||||
|
|
||||||
|
### 3. Bitbucket
|
||||||
|
- **URL**: [$BITBUCKET_URL]($BITBUCKET_URL)
|
||||||
|
- **Purpose**: Bitbucket provides a secure environment for repository hosting with strong integration into Atlassian’s ecosystem (e.g., Jira, Trello). It serves as an additional layer of redundancy and a professional-grade hosting option.
|
||||||
|
- **Value**: Offers enterprise-grade security and integration capabilities, ensuring the project remains accessible even if other platforms face disruptions.
|
||||||
|
|
||||||
|
### 4. GitHub
|
||||||
|
- **URL**: [$GITHUB_URL]($GITHUB_URL)
|
||||||
|
- **Purpose**: GitHub serves as the primary platform for visibility, collaboration, and community engagement. Its widespread adoption and robust tooling make it ideal for public-facing development, issue tracking, and integration with CI/CD pipelines.
|
||||||
|
- **Value**: Provides a centralized hub for open-source contributions, pull requests, and project management, ensuring broad accessibility and developer familiarity.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛡️ Rationale for Redundancy
|
||||||
|
|
||||||
|
The decision to maintain multiple repositories stems from the need to safeguard the project against **deplatforming attempts** and ensure its **long-term availability**. Past incidents involving **Mr. Joel Johnson** and **Dr. Peter Gaied** have highlighted the vulnerability of relying on a single platform. By distributing the repository across GitHub, GitLab, Bitbucket, and Radicle, we achieve:
|
||||||
|
|
||||||
|
- **Resilience**: If one platform removes or restricts access, the project remains accessible on others.
|
||||||
|
- **Sovereignty**: Radicle’s decentralized nature ensures the project cannot be fully censored or controlled by any single entity.
|
||||||
|
- **Diversity**: Each platform’s unique features (e.g., GitHub’s community, GitLab’s CI/CD, Bitbucket’s integrations, Radicle’s decentralization) enhance the project’s functionality and reach.
|
||||||
|
- **Transparency**: Metadata snapshots in the \`.gitfield\` directory provide a verifiable record of the project’s state across all platforms.
|
||||||
|
|
||||||
|
This multi-repository approach reflects a commitment to preserving the integrity and accessibility of \`$REPO_NAME\`, ensuring it remains available to contributors and users regardless of external pressures.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📜 Metadata and Logs
|
||||||
|
|
||||||
|
- **Metadata Files**: Each platform generates a metadata snapshot in the \`.gitfield\` directory (e.g., \`github.sigil.md\`, \`gitlab.sigil.md\`, etc.), capturing commit details, environment information, and hardware fingerprints.
|
||||||
|
- **Push Log**: The \`.gitfield/pushed.log\` file records the date, time, and URL of every push operation across all platforms, providing a transparent audit trail.
|
||||||
|
- **Recursive Sync**: The repository is synchronized across all platforms in a recursive loop (three cycles) to ensure interconnected metadata captures the latest state of the project.
|
||||||
|
- **Push Order**: The repository is synchronized in the following order: **Radicle → GitLab → Bitbucket → GitHub**. This prioritizes Radicle’s decentralized, censorship-resistant network as the primary anchor, followed by GitLab’s robust DevOps features, Bitbucket’s enterprise redundancy, and GitHub’s broad visibility, ensuring a resilient and accessible metadata chain.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
_Auto-generated by \`gitfield-sync\` at $TIMESTAMP (v$SCRIPT_VERSION)._
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Add and commit GITFIELD.md
|
||||||
|
git -C "$REPO_PATH" add "$GITFIELD_MD"
|
||||||
|
git -C "$REPO_PATH" commit -m "Generated GITFIELD.md at $TIMESTAMP" || warn "No changes to commit for $GITFIELD_MD"
|
||||||
|
info "Generated and committed $GITFIELD_MD"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ╭─────────────────────────────────────╮
|
||||||
|
# │ LOG URL FUNCTION │
|
||||||
|
# ╰─────────────────────────────────────╮
|
||||||
|
log_url() {
|
||||||
|
local platform=$1
|
||||||
|
local url=$2
|
||||||
|
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||||
|
echo "[$timestamp] $platform: $url" >> "$LOG_FILE"
|
||||||
|
info "Logged push to $LOG_FILE: [$timestamp] $platform: $url"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ╭─────────────────────────────────────╮
|
||||||
|
# │ EXECUTE PUSH SCRIPT │
|
||||||
|
# ╰─────────────────────────────────────╮
|
||||||
|
execute_push() {
|
||||||
|
local script_name=$1
|
||||||
|
local platform=$2
|
||||||
|
local url=$3
|
||||||
|
local script_path
|
||||||
|
script_path=$(find_script "$script_name") || error "Failed to find $script_name"
|
||||||
|
info "Running $script_path for $platform..."
|
||||||
|
if [ -x "$script_path" ]; then
|
||||||
|
# Change to repo root to ensure consistent execution context
|
||||||
|
pushd "$REPO_PATH" >/dev/null
|
||||||
|
"$script_path" || warn "Execution of $script_path failed, continuing..."
|
||||||
|
# Log the URL after successful push
|
||||||
|
log_url "$platform" "$url"
|
||||||
|
# Add and commit any new files generated by the script
|
||||||
|
git add . || warn "Nothing to add after $script_path"
|
||||||
|
git commit -m "Post-$platform sync at $TIMESTAMP" || warn "No changes to commit after $script_path"
|
||||||
|
popd >/dev/null
|
||||||
|
else
|
||||||
|
error "Script $script_path is not executable"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ╭─────────────────────────────────────╮
|
||||||
|
# │ RECURSIVE PUSH LOOP │
|
||||||
|
# ╰─────────────────────────────────────╮
|
||||||
|
run_push_cycle() {
|
||||||
|
local cycle_number=$1
|
||||||
|
info "Starting push cycle $cycle_number..."
|
||||||
|
|
||||||
|
# Push to each platform in order
|
||||||
|
execute_push "gitfield-radicle" "Radicle" "$RADICLE_URL"
|
||||||
|
execute_push "gitfield-gitlab" "GitLab" "$GITLAB_URL"
|
||||||
|
execute_push "gitfield-bitbucket" "Bitbucket" "$BITBUCKET_URL"
|
||||||
|
execute_push "gitfield-github" "GitHub" "$GITHUB_URL"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ╭─────────────────────────────────────╮
|
||||||
|
# │ MAIN EXECUTION │
|
||||||
|
# ╰─────────────────────────────────────╮
|
||||||
|
info "Starting gitfield-sync for $REPO_NAME..."
|
||||||
|
|
||||||
|
# Ensure the repository is initialized
|
||||||
|
if [ ! -d "$REPO_PATH/.git" ]; then
|
||||||
|
pushd "$REPO_PATH" >/dev/null
|
||||||
|
git init
|
||||||
|
git add .
|
||||||
|
git commit -m "Initial commit" || warn "Nothing to commit"
|
||||||
|
popd >/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Run the first push cycle
|
||||||
|
run_push_cycle 1
|
||||||
|
|
||||||
|
# Generate GITFIELD.md after the first cycle
|
||||||
|
generate_gitfield_md
|
||||||
|
|
||||||
|
# Run the second push cycle to include GITFIELD.md
|
||||||
|
run_push_cycle 2
|
||||||
|
|
||||||
|
# Run the third push cycle for final metadata sync
|
||||||
|
run_push_cycle 3
|
||||||
|
|
||||||
|
info "✅ gitfield-sync completed successfully."
|
||||||
|
info "🔗 View logs: $LOG_FILE"
|
||||||
|
info "🔗 View multi-repo manifest: $GITFIELD_MD"
|
44
bin/gitfield-sync-gdrive.sh
Executable file
44
bin/gitfield-sync-gdrive.sh
Executable file
|
@ -0,0 +1,44 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# ──────────────────────────────────────────────────────────────
|
||||||
|
# ⚙️ GitField GDrive Sync Script
|
||||||
|
# Ensures Google Drive is mounted at ~/gdrive and syncs
|
||||||
|
# the current Git repo into ~/gdrive/gitfield/<repo_name>
|
||||||
|
# ──────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# ⛓ Ensure rsync is installed
|
||||||
|
if ! command -v rsync &> /dev/null; then
|
||||||
|
echo "rsync not found. Attempting to install..."
|
||||||
|
sudo apt update && sudo apt install -y rsync
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ⛓ Ensure ~/gdrive exists and is mounted
|
||||||
|
GDRIVE_PATH="$HOME/gdrive"
|
||||||
|
GITFIELD_PATH="$GDRIVE_PATH/gitfield"
|
||||||
|
|
||||||
|
if [ ! -d "$GDRIVE_PATH" ]; then
|
||||||
|
echo "Google Drive folder not found at $GDRIVE_PATH."
|
||||||
|
echo "Create it or mount your gdrive before syncing."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$GITFIELD_PATH"
|
||||||
|
|
||||||
|
# ⛓ Ensure current directory is inside a Git repo
|
||||||
|
if ! git rev-parse --is-inside-work-tree &> /dev/null; then
|
||||||
|
echo "Not inside a Git repository. Aborting sync."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 🏷 Determine repo name and paths
|
||||||
|
REPO_ROOT=$(git rev-parse --show-toplevel)
|
||||||
|
REPO_NAME=$(basename "$REPO_ROOT")
|
||||||
|
DEST="$GITFIELD_PATH/$REPO_NAME"
|
||||||
|
|
||||||
|
# ♻️ Perform rsync (mirror entire repo, preserve structure, show progress)
|
||||||
|
echo "Syncing '$REPO_NAME' to $DEST..."
|
||||||
|
rsync -av --delete "$REPO_ROOT/" "$DEST/"
|
||||||
|
|
||||||
|
echo "✅ GitField sync complete: $REPO_NAME ➝ $DEST"
|
2
bin/mount-gdrive.sh
Executable file
2
bin/mount-gdrive.sh
Executable file
|
@ -0,0 +1,2 @@
|
||||||
|
#!/bin/bash
|
||||||
|
rclone mount gdrive: ~/gdrive --vfs-cache-mode writes
|
85
bin/sync-metadata.sh
Executable file
85
bin/sync-metadata.sh
Executable file
|
@ -0,0 +1,85 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# ----------------------------
|
||||||
|
# Gitfield Metadata Sync Tool
|
||||||
|
# ----------------------------
|
||||||
|
|
||||||
|
# CONFIGURATION
|
||||||
|
DRIVE_REMOTE="gdrive"
|
||||||
|
GITFIELD_ROOT="$HOME/gdrive/gitfield"
|
||||||
|
SCRIPT_NAME="sync-metadata.sh"
|
||||||
|
|
||||||
|
# Ensure rclone is installed
|
||||||
|
if ! command -v rclone &> /dev/null; then
|
||||||
|
echo "rclone is not installed. Installing..."
|
||||||
|
sudo apt update && sudo apt install -y rclone
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Ensure jq is installed
|
||||||
|
if ! command -v jq &> /dev/null; then
|
||||||
|
echo "jq is not installed. Installing..."
|
||||||
|
sudo apt update && sudo apt install -y jq
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get Git repo root
|
||||||
|
REPO_DIR=$(git rev-parse --show-toplevel 2>/dev/null)
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "❌ Not inside a Git repository."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
REPO_NAME=$(basename "$REPO_DIR")
|
||||||
|
GDRIVE_PATH="gitfield/$REPO_NAME"
|
||||||
|
SYNC_LOG="$REPO_DIR/.gitfield/sync-log.md"
|
||||||
|
README="$REPO_DIR/README.md"
|
||||||
|
|
||||||
|
echo "🔍 Detecting Google Drive folder: $GDRIVE_PATH..."
|
||||||
|
|
||||||
|
# Mount ~/gdrive if not mounted
|
||||||
|
MOUNTPOINT="$HOME/gdrive"
|
||||||
|
if ! mount | grep -q "$MOUNTPOINT"; then
|
||||||
|
echo "⚙️ Mounting Google Drive to $MOUNTPOINT..."
|
||||||
|
mkdir -p "$MOUNTPOINT"
|
||||||
|
rclone mount "$DRIVE_REMOTE:/" "$MOUNTPOINT" --vfs-cache-mode writes --daemon
|
||||||
|
sleep 3
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Share link generation
|
||||||
|
SHARE_URL=$(rclone link "$DRIVE_REMOTE:$GDRIVE_PATH")
|
||||||
|
if [ -z "$SHARE_URL" ]; then
|
||||||
|
echo "❌ Could not generate Google Drive share link."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Optional: Construct drv.tw link (manual fallback example)
|
||||||
|
DRV_URL="https://drv.tw/view/$(basename "$SHARE_URL")"
|
||||||
|
|
||||||
|
# Write metadata to sync log
|
||||||
|
mkdir -p "$(dirname "$SYNC_LOG")"
|
||||||
|
cat <<EOF >> "$SYNC_LOG"
|
||||||
|
|
||||||
|
## 🔄 Sync Metadata — $(date +%F)
|
||||||
|
|
||||||
|
- 📁 **Google Drive Folder**: [$REPO_NAME]($SHARE_URL)
|
||||||
|
- 🌐 **Published View**: [$DRV_URL]($DRV_URL)
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Append to README if not already present
|
||||||
|
if ! grep -q "$SHARE_URL" "$README"; then
|
||||||
|
echo "📘 Updating README..."
|
||||||
|
cat <<EOF >> "$README"
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔍 External Access
|
||||||
|
|
||||||
|
- 🔗 **Google Drive Folder**: [$REPO_NAME]($SHARE_URL)
|
||||||
|
- 🌐 **Published View**: [$DRV_URL]($DRV_URL)
|
||||||
|
|
||||||
|
EOF
|
||||||
|
else
|
||||||
|
echo "✅ README already contains sync links."
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✅ Metadata sync complete."
|
0
test
0
test
Loading…
Add table
Add a link
Reference in a new issue