Post-Local sync at 2025-06-11T23:29:47Z
This commit is contained in:
parent
9b4447260b
commit
9e1e141f69
7 changed files with 10 additions and 2851 deletions
|
@ -296,6 +296,12 @@
|
||||||
"branch": "master",
|
"branch": "master",
|
||||||
"commit": "280d8b2870b7b7e51b1015f33b8d67ac8f30e92e",
|
"commit": "280d8b2870b7b7e51b1015f33b8d67ac8f30e92e",
|
||||||
"message": "Generated index.json at 2025-06-10T08:33:00Z"
|
"message": "Generated index.json at 2025-06-10T08:33:00Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2025-06-11 18:29:48",
|
||||||
|
"branch": "master",
|
||||||
|
"commit": "611b5bfdc0ead2d7a7c14118117240344396f10a",
|
||||||
|
"message": "Generated docs/integrity.sha256 at 2025-06-11T23:29:47Z"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -679,3 +679,7 @@
|
||||||
Diff Summary:
|
Diff Summary:
|
||||||
.gitfield/radicle.sigil.md | 16 ++++++++--------
|
.gitfield/radicle.sigil.md | 16 ++++++++--------
|
||||||
1 file changed, 8 insertions(+), 8 deletions(-)
|
1 file changed, 8 insertions(+), 8 deletions(-)
|
||||||
|
[2025-06-11T23:29:48Z] Local: , Branch=master, Commit=2100497
|
||||||
|
Diff Summary:
|
||||||
|
.gitfield/local.sigil.md | 30 +++++++++++++++---------------
|
||||||
|
1 file changed, 15 insertions(+), 15 deletions(-)
|
||||||
|
|
|
@ -1,245 +0,0 @@
|
||||||
#!/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
|
|
||||||
GITHUB_URL="https://github.com/mrhavens/$REPO_NAME"
|
|
||||||
GITLAB_URL="https://gitlab.com/mrhavens/$REPO_NAME"
|
|
||||||
BITBUCKET_URL="https://bitbucket.org/thefoldwithin/$REPO_NAME"
|
|
||||||
FORGEJO_URL="https://remember.thefoldwithin.earth/mrhavens/$REPO_NAME"
|
|
||||||
RADICLE_RID="rad:z3FEj7rF8gZw9eFksCuiN43qjzrex"
|
|
||||||
RADICLE_PEER_ID="z6Mkw5s3ppo26C7y7tGK5MD8n2GqTHS582PPpeX5Xqbu2Mpz"
|
|
||||||
|
|
||||||
# ╭─────────────────────────────────────╮
|
|
||||||
# │ LOGGING UTILS │
|
|
||||||
# ╰─────────────────────────────────────╮
|
|
||||||
info() { echo -e "\e[1;34m[INFO]\e[0m $*" >&2; }
|
|
||||||
warn() { echo -e "\e[1;33m[WARN]\e[0m $*" >&2; }
|
|
||||||
error() { echo -e "\e[1;31m[ERROR]\e[0m $*" >&2; exit 1; }
|
|
||||||
|
|
||||||
# ╭─────────────────────────────────────╮
|
|
||||||
# │ SCRIPT LOOKUP FUNCTION │
|
|
||||||
# ╰─────────────────────────────────────╮
|
|
||||||
find_script() {
|
|
||||||
local script_name=$1
|
|
||||||
local search_paths=(
|
|
||||||
"$HOME/.local/gitfieldbin"
|
|
||||||
"$HOME/.local/bin"
|
|
||||||
"$HOME/.local/gitfield"
|
|
||||||
"$HOME/.local/bin/gitfield"
|
|
||||||
"$HOME/.local/bin/gitfieldbin"
|
|
||||||
"$REPO_PATH/bin"
|
|
||||||
)
|
|
||||||
|
|
||||||
for path in "${search_paths[@]}"; do
|
|
||||||
if [ -f "$path/$script_name" ]; then
|
|
||||||
if [ -x "$path/$script_name" ]; then
|
|
||||||
if [[ "$path" != "$HOME"* && "$path" != "$REPO_PATH"* ]]; then
|
|
||||||
info "Using script: \e[1;31m$path/$script_name\e[0m (outside home or repo)"
|
|
||||||
else
|
|
||||||
info "Using script: $path/$script_name"
|
|
||||||
fi
|
|
||||||
echo "$path/$script_name"
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
warn "Found $path/$script_name but it is not executable"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
error "Script $script_name not found in any search path"
|
|
||||||
}
|
|
||||||
|
|
||||||
# ╭─────────────────────────────────────╮
|
|
||||||
# │ INITIAL SETUP │
|
|
||||||
# ╰─────────────────────────────────────╮
|
|
||||||
mkdir -p "$GITFIELD_DIR"
|
|
||||||
|
|
||||||
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 five distinct platforms: **GitHub**, **GitLab**, **Bitbucket**, **Radicle**, and **Forgejo**. 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 and delisting 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)), **Dr. Peter Gaied** ([Paragraph post](https://paragraph.com/@neutralizingnarcissism/%F0%9F%9C%81-the-narcissistic-messiah)), and **Andrew LeCody** ([Mirror post](https://mirror.xyz/neutralizingnarcissism.eth/s3GRxuiZs6vGSGDcPEpCgjaSxwGAViGhmg6a5XTL6s0)), 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)). Specifically, Andrew LeCody has attempted to delist the project's content on Google, though it remains accessible on other search engines such as [Bing](https://www.bing.com/search?q=andrew+lecody+neutralizing+narcissism&qs=HS&pq=andrew+lecody), [DuckDuckGo](https://duckduckgo.com/?t=h_&q=andrew+lecody+neutralizing+narcissism&ia=web), and [Yahoo](https://search.yahoo.com/search?p=andrew+lecody+neutralizng+narcissism). By distributing the repository across multiple platforms, including a self-hosted Forgejo instance, we ensure its persistence, accessibility, and sovereignty.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📍 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
|
|
||||||
- **RID**: $RADICLE_RID
|
|
||||||
- **Peer ID**: $RADICLE_PEER_ID
|
|
||||||
- **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.
|
|
||||||
- **Access Details**: To view project details, run:
|
|
||||||
\`\`\`bash
|
|
||||||
rad inspect $RADICLE_RID
|
|
||||||
\`\`\`
|
|
||||||
To view the file structure, run:
|
|
||||||
\`\`\`bash
|
|
||||||
rad ls $RADICLE_RID
|
|
||||||
\`\`\`
|
|
||||||
Alternatively, use Git to list files at the current HEAD:
|
|
||||||
\`\`\`bash
|
|
||||||
git ls-tree -r --name-only HEAD
|
|
||||||
\`\`\`
|
|
||||||
|
|
||||||
### 2. Forgejo
|
|
||||||
- **URL**: [$FORGEJO_URL]($FORGEJO_URL)
|
|
||||||
- **Purpose**: Forgejo is a self-hosted, open-source git platform running on \`remember.thefoldwithin.earth\`. It provides full control over the repository, ensuring sovereignty and independence from third-party providers.
|
|
||||||
- **Value**: Enhances resilience by hosting the repository on a sovereign, redundant system with automated backups and deployment strategies, reducing risks of external interference or service disruptions.
|
|
||||||
- **Access Details**: SSH access uses port 222:
|
|
||||||
\`\`\`bash
|
|
||||||
ssh -T -p 222 username@remember.thefoldwithin.earth
|
|
||||||
\`\`\`
|
|
||||||
|
|
||||||
### 3. 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.
|
|
||||||
|
|
||||||
### 4. 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.
|
|
||||||
|
|
||||||
### 5. 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 **search engine delistings** and ensure its **long-term availability**. Past incidents involving **Mr. Joel Johnson**, **Dr. Peter Gaied**, and **Andrew LeCody** have highlighted the vulnerability of relying on a single platform or search engine. By distributing the repository across GitHub, GitLab, Bitbucket, Radicle, and a self-hosted Forgejo instance, we achieve:
|
|
||||||
|
|
||||||
- **Resilience**: If one platform removes or restricts access, or if search engines like Google delist content, the project remains accessible on other platforms and discoverable via alternative search engines such as Bing, DuckDuckGo, and Yahoo.
|
|
||||||
- **Sovereignty**: Radicle’s decentralized nature and Forgejo’s self-hosted infrastructure ensure 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, Forgejo’s self-hosting) 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, bolstered by Forgejo’s sovereign hosting, reflects a commitment to preserving the integrity, accessibility, and independence 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\`, \`remember.sigil.md\`, etc.), capturing commit details, environment information, and hardware fingerprints.
|
|
||||||
- **Push Log**: The \`.gitfield/pushed.log\` file records the date, time, and RID/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 → Forgejo → GitLab → Bitbucket → GitHub**. This prioritizes Radicle’s decentralized, censorship-resistant network as the primary anchor, followed by Forgejo’s sovereign, self-hosted infrastructure, 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
|
|
||||||
|
|
||||||
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 rid=$3
|
|
||||||
local peer_id=$4
|
|
||||||
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
|
||||||
if [ "$platform" = "Radicle" ]; then
|
|
||||||
echo "[$timestamp] $platform: RID=$rid, Peer ID=$peer_id" >> "$LOG_FILE"
|
|
||||||
echo " CLI: rad inspect $rid # View project details" >> "$LOG_FILE"
|
|
||||||
echo " CLI: git ls-tree -r --name-only HEAD # View file structure" >> "$LOG_FILE"
|
|
||||||
info "Logged push to $LOG_FILE: [$timestamp] $platform: RID=$rid, Peer ID=$peer_id"
|
|
||||||
else
|
|
||||||
echo "[$timestamp] $platform: $url" >> "$LOG_FILE"
|
|
||||||
info "Logged push to $LOG_FILE: [$timestamp] $platform: $url"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# ╭─────────────────────────────────────╮
|
|
||||||
# │ EXECUTE PUSH SCRIPT │
|
|
||||||
# ╰─────────────────────────────────────╮
|
|
||||||
execute_push() {
|
|
||||||
local script_name=$1
|
|
||||||
local platform=$2
|
|
||||||
local url=$3
|
|
||||||
local rid=$4
|
|
||||||
local peer_id=$5
|
|
||||||
local script_path
|
|
||||||
script_path=$(find_script "$script_name") || error "Failed to find $script_name"
|
|
||||||
info "Executing $platform push with script: $script_path"
|
|
||||||
if [ -x "$script_path" ]; then
|
|
||||||
pushd "$REPO_PATH" >/dev/null
|
|
||||||
"$script_path" || warn "Execution of $script_path failed, continuing..."
|
|
||||||
log_url "$platform" "$url" "$rid" "$peer_id"
|
|
||||||
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..."
|
|
||||||
|
|
||||||
execute_push "gitfield-local" "Local" "" "" ""
|
|
||||||
execute_push "gitfield-radicle" "Radicle" "" "$RADICLE_RID" "$RADICLE_PEER_ID"
|
|
||||||
execute_push "gitfield-remember" "Forgejo" "$FORGEJO_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..."
|
|
||||||
|
|
||||||
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_push_cycle 1
|
|
||||||
generate_gitfield_md
|
|
||||||
run_push_cycle 2
|
|
||||||
run_push_cycle 3
|
|
||||||
|
|
||||||
info "✅ gitfield-sync completed successfully."
|
|
||||||
info "🔗 View logs: $LOG_FILE"
|
|
||||||
info "🔗 View multi-repo manifest: $GITFIELD_MD"
|
|
|
@ -1,259 +0,0 @@
|
||||||
#!/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
|
|
||||||
GITHUB_URL="https://github.com/mrhavens/$REPO_NAME"
|
|
||||||
GITLAB_URL="https://gitlab.com/mrhavens/$REPO_NAME"
|
|
||||||
BITBUCKET_URL="https://bitbucket.org/thefoldwithin/$REPO_NAME"
|
|
||||||
FORGEJO_URL="https://remember.thefoldwithin.earth/mrhavens/$REPO_NAME"
|
|
||||||
CODEBERG_URL="https://codeberg.org/mrhavens/$REPO_NAME"
|
|
||||||
GITEA_URL="https://gitea.com/mrhavens/$REPO_NAME"
|
|
||||||
RADICLE_RID="rad:z3FEj7rF8gZw9eFksCuiN43qjzrex"
|
|
||||||
RADICLE_PEER_ID="z6Mkw5s3ppo26C7y7tGK5MD8n2GqTHS582PPpeX5Xqbu2Mpz"
|
|
||||||
|
|
||||||
# ╭─────────────────────────────────────╮
|
|
||||||
# │ LOGGING UTILS │
|
|
||||||
# ╰─────────────────────────────────────╮
|
|
||||||
info() { echo -e "\e[1;34m[INFO]\e[0m $*" >&2; }
|
|
||||||
warn() { echo -e "\e[1;33m[WARN]\e[0m $*" >&2; }
|
|
||||||
error() { echo -e "\e[1;31m[ERROR]\e[0m $*" >&2; exit 1; }
|
|
||||||
|
|
||||||
# ╭─────────────────────────────────────╮
|
|
||||||
# │ SCRIPT LOOKUP FUNCTION │
|
|
||||||
# ╰─────────────────────────────────────╮
|
|
||||||
find_script() {
|
|
||||||
local script_name=$1
|
|
||||||
local search_paths=(
|
|
||||||
"$HOME/.local/gitfieldbin"
|
|
||||||
"$HOME/.local/bin"
|
|
||||||
"$HOME/.local/gitfield"
|
|
||||||
"$HOME/.local/bin/gitfield"
|
|
||||||
"$HOME/.local/bin/gitfieldbin"
|
|
||||||
"$REPO_PATH/bin"
|
|
||||||
)
|
|
||||||
|
|
||||||
for path in "${search_paths[@]}"; do
|
|
||||||
if [ -f "$path/$script_name" ]; then
|
|
||||||
if [ -x "$path/$script_name" ]; then
|
|
||||||
if [[ "$path" != "$HOME"* && "$path" != "$REPO_PATH"* ]]; then
|
|
||||||
info "Using script: \e[1;31m$path/$script_name\e[0m (outside home or repo)"
|
|
||||||
else
|
|
||||||
info "Using script: $path/$script_name"
|
|
||||||
fi
|
|
||||||
echo "$path/$script_name"
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
warn "Found $path/$script_name but it is not executable"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
error "Script $script_name not found in any search path"
|
|
||||||
}
|
|
||||||
|
|
||||||
# ╭─────────────────────────────────────╮
|
|
||||||
# │ INITIAL SETUP │
|
|
||||||
# ╰─────────────────────────────────────╮
|
|
||||||
mkdir -p "$GITFIELD_DIR"
|
|
||||||
|
|
||||||
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 seven distinct platforms: **GitHub**, **GitLab**, **Bitbucket**, **Radicle**, **Forgejo**, **Codeberg**, and **Gitea**. 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 and delisting 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)), **Dr. Peter Gaied** ([Paragraph post](https://paragraph.com/@neutralizingnarcissism/%F0%9F%9C%81-the-narcissistic-messiah)), and **Andrew LeCody** ([Mirror post](https://mirror.xyz/neutralizingnarcissism.eth/s3GRxuiZs6vGSGDcPEpCgjaSxwGAViGhmg6a5XTL6s0)), 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)). Specifically, Andrew LeCody has attempted to delist the project's content on Google, though it remains accessible on other search engines such as [Bing](https://www.bing.com/search?q=andrew+lecody+neutralizing+narcissism&qs=HS&pq=andrew+lecody), [DuckDuckGo](https://duckduckgo.com/?t=h_&q=andrew+lecody+neutralizing+narcissism&ia=web), and [Yahoo](https://search.yahoo.com/search?p=andrew+lecody+neutralizng+narcissism). By distributing the repository across multiple platforms, including a self-hosted Forgejo instance, we ensure its persistence, accessibility, and sovereignty.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📍 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
|
|
||||||
- **RID**: $RADICLE_RID
|
|
||||||
- **Peer ID**: $RADICLE_PEER_ID
|
|
||||||
- **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.
|
|
||||||
- **Access Details**: To view project details, run:
|
|
||||||
\`\`\`bash
|
|
||||||
rad inspect $RADICLE_RID
|
|
||||||
\`\`\`
|
|
||||||
To view the file structure, run:
|
|
||||||
\`\`\`bash
|
|
||||||
rad ls $RADICLE_RID
|
|
||||||
\`\`\`
|
|
||||||
Alternatively, use Git to list files at the current HEAD:
|
|
||||||
\`\`\`bash
|
|
||||||
git ls-tree -r --name-only HEAD
|
|
||||||
\`\`\`
|
|
||||||
|
|
||||||
### 2. Forgejo
|
|
||||||
- **URL**: [$FORGEJO_URL]($FORGEJO_URL)
|
|
||||||
- **Purpose**: Forgejo is a self-hosted, open-source git platform running on \`remember.thefoldwithin.earth\`. It provides full control over the repository, ensuring sovereignty and independence from third-party providers.
|
|
||||||
- **Value**: Enhances resilience by hosting the repository on a sovereign, redundant system with automated backups and deployment strategies, reducing risks of external interference or service disruptions.
|
|
||||||
- **Access Details**: SSH access uses port 222:
|
|
||||||
\`\`\`bash
|
|
||||||
ssh -T -p 222 git@remember.thefoldwithin.earth
|
|
||||||
\`\`\`
|
|
||||||
|
|
||||||
### 3. Codeberg
|
|
||||||
- **URL**: [$CODEBERG_URL]($CODEBERG_URL)
|
|
||||||
- **Purpose**: Codeberg is a community-driven, open-source platform powered by Forgejo, offering a reliable and ethical alternative for hosting git repositories.
|
|
||||||
- **Value**: Enhances project resilience with its open-source ethos and independent infrastructure, ensuring accessibility and community support.
|
|
||||||
|
|
||||||
### 4. Gitea
|
|
||||||
- **URL**: [$GITEA_URL]($GITEA_URL)
|
|
||||||
- **Purpose**: Gitea.com provides a lightweight, open-source git hosting platform with robust features for repository management and collaboration.
|
|
||||||
- **Value**: Offers an additional layer of redundancy and a user-friendly interface, complementing other platforms with its simplicity and efficiency.
|
|
||||||
|
|
||||||
### 5. 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.
|
|
||||||
|
|
||||||
### 6. 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.
|
|
||||||
|
|
||||||
### 7. 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 **search engine delistings** and ensure its **long-term availability**. Past incidents involving **Mr. Joel Johnson**, **Dr. Peter Gaied**, and **Andrew LeCody** have highlighted the vulnerability of relying on a single platform or search engine. By distributing the repository across GitHub, GitLab, Bitbucket, Radicle, Forgejo, Codeberg, and Gitea, we achieve:
|
|
||||||
|
|
||||||
- **Resilience**: If one platform removes or restricts access, or if search engines like Google delist content, the project remains accessible on other platforms and discoverable via alternative search engines such as Bing, DuckDuckGo, and Yahoo.
|
|
||||||
- **Sovereignty**: Radicle’s decentralized nature and Forgejo’s self-hosted infrastructure ensure 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, Forgejo’s self-hosting, Codeberg’s community-driven model, Gitea’s lightweight efficiency) 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, bolstered by Forgejo’s sovereign hosting, reflects a commitment to preserving the integrity, accessibility, and independence 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\`, \`remember.sigil.md\`, \`codeberg.sigil.md\`, \`gitea.sigil.md\`, etc.), capturing commit details, environment information, and hardware fingerprints.
|
|
||||||
- **Push Log**: The \`.gitfield/pushed.log\` file records the date, time, and RID/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 → Forgejo → Codeberg → Gitea → GitLab → Bitbucket → GitHub**. This prioritizes Radicle’s decentralized, censorship-resistant network as the primary anchor, followed by Forgejo’s sovereign, self-hosted infrastructure, Codeberg’s community-driven platform, Gitea’s lightweight efficiency, 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
|
|
||||||
|
|
||||||
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 rid=$3
|
|
||||||
local peer_id=$4
|
|
||||||
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
|
||||||
if [ "$platform" = "Radicle" ]; then
|
|
||||||
echo "[$timestamp] $platform: RID=$rid, Peer ID=$peer_id" >> "$LOG_FILE"
|
|
||||||
echo " CLI: rad inspect $rid # View project details" >> "$LOG_FILE"
|
|
||||||
echo " CLI: git ls-tree -r --name-only HEAD # View file structure" >> "$LOG_FILE"
|
|
||||||
info "Logged push to $LOG_FILE: [$timestamp] $platform: RID=$rid, Peer ID=$peer_id"
|
|
||||||
else
|
|
||||||
echo "[$timestamp] $platform: $url" >> "$LOG_FILE"
|
|
||||||
info "Logged push to $LOG_FILE: [$timestamp] $platform: $url"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# ╭─────────────────────────────────────╮
|
|
||||||
# │ EXECUTE PUSH SCRIPT │
|
|
||||||
# ╰─────────────────────────────────────╮
|
|
||||||
execute_push() {
|
|
||||||
local script_name=$1
|
|
||||||
local platform=$2
|
|
||||||
local url=$3
|
|
||||||
local rid=$4
|
|
||||||
local peer_id=$5
|
|
||||||
local script_path
|
|
||||||
script_path=$(find_script "$script_name") || error "Failed to find $script_name"
|
|
||||||
info "Executing $platform push with script: $script_path"
|
|
||||||
if [ -x "$script_path" ]; then
|
|
||||||
pushd "$REPO_PATH" >/dev/null
|
|
||||||
"$script_path" || warn "Execution of $script_path failed, continuing..."
|
|
||||||
log_url "$platform" "$url" "$rid" "$peer_id"
|
|
||||||
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..."
|
|
||||||
|
|
||||||
execute_push "gitfield-local" "Local" "" "" ""
|
|
||||||
execute_push "gitfield-radicle" "Radicle" "" "$RADICLE_RID" "$RADICLE_PEER_ID"
|
|
||||||
execute_push "gitfield-remember" "Forgejo" "$FORGEJO_URL" "" ""
|
|
||||||
execute_push "gitfield-codeberg" "Codeberg" "$CODEBERG_URL" "" ""
|
|
||||||
execute_push "gitfield-gitea" "Gitea" "$GITEA_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..."
|
|
||||||
|
|
||||||
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_push_cycle 1
|
|
||||||
generate_gitfield_md
|
|
||||||
run_push_cycle 2
|
|
||||||
run_push_cycle 3
|
|
||||||
|
|
||||||
info "✅ gitfield-sync completed successfully."
|
|
||||||
info "🔗 View logs: $LOG_FILE"
|
|
||||||
info "🔗 View multi-repo manifest: $GITFIELD_MD"
|
|
|
@ -1,494 +0,0 @@
|
||||||
#!/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"
|
|
||||||
WELL_KNOWN_DIR="$REPO_PATH/.well-known"
|
|
||||||
LOG_FILE="$GITFIELD_DIR/pushed.log"
|
|
||||||
GITFIELD_MD="$REPO_PATH/GITFIELD.md"
|
|
||||||
CANONICAL_META="$GITFIELD_DIR/canonical.meta"
|
|
||||||
CANONICAL_MD="$GITFIELD_DIR/canonical.md"
|
|
||||||
INDEX_JSON="$GITFIELD_DIR/index.json"
|
|
||||||
WELL_KNOWN_JSON="$WELL_KNOWN_DIR/gitfield.json"
|
|
||||||
TIMESTAMP=$(date -u '+%Y-%m-%dT%H:%M:%SZ')
|
|
||||||
SCRIPT_VERSION="1.1" # Updated version for metadata enhancements
|
|
||||||
PRESERVE_META=${PRESERVE_META:-false} # Flag to preserve existing metadata (default: false)
|
|
||||||
|
|
||||||
# URLs for each platform
|
|
||||||
CANONICAL_URL="https://remember.thefoldwithin.earth/mrhavens/$REPO_NAME"
|
|
||||||
GITHUB_URL="https://github.com/mrhavens/$REPO_NAME"
|
|
||||||
GITLAB_URL="https://gitlab.com/mrhavens/$REPO_NAME"
|
|
||||||
BITBUCKET_URL="https://bitbucket.org/thefoldwithin/$REPO_NAME"
|
|
||||||
FORGEJO_URL="https://remember.thefoldwithin.earth/mrhavens/$REPO_NAME"
|
|
||||||
CODEBERG_URL="https://codeberg.org/mrhavens/$REPO_NAME"
|
|
||||||
GITEA_URL="https://gitea.com/mrhavens/$REPO_NAME"
|
|
||||||
RADICLE_RID="rad:z3FEj7rF8gZw9eFksCuiN43qjzrex"
|
|
||||||
RADICLE_PEER_ID="z6Mkw5s3ppo26C7y7tGK5MD8n2GqTHS582PPpeX5Xqbu2Mpz"
|
|
||||||
|
|
||||||
# Metadata configuration
|
|
||||||
MIRRORS=(
|
|
||||||
"$GITHUB_URL"
|
|
||||||
"$GITLAB_URL"
|
|
||||||
"$BITBUCKET_URL"
|
|
||||||
"$FORGEJO_URL"
|
|
||||||
"$CODEBERG_URL"
|
|
||||||
"$GITEA_URL"
|
|
||||||
"rad:$RADICLE_RID"
|
|
||||||
)
|
|
||||||
COMMIT_HASH=$(git -C "$REPO_PATH" rev-parse --short HEAD 2>/dev/null || echo "unknown")
|
|
||||||
TREE_HASH=$(git -C "$REPO_PATH" rev-parse HEAD^{tree} 2>/dev/null || echo "unknown")
|
|
||||||
SYNC_CYCLES=0
|
|
||||||
|
|
||||||
# ╭─────────────────────────────────────╮
|
|
||||||
# │ LOGGING UTILS │
|
|
||||||
# ╰─────────────────────────────────────╮
|
|
||||||
info() { echo -e "\e[1;34m[INFO]\e[0m $*" >&2; }
|
|
||||||
warn() { echo -e "\e[1;33m[WARN]\e[0m $*" >&2; }
|
|
||||||
error() { echo -e "\e[1;31m[ERROR]\e[0m $*" >&2; exit 1; }
|
|
||||||
|
|
||||||
# ╭─────────────────────────────────────╮
|
|
||||||
# │ SCRIPT LOOKUP FUNCTION │
|
|
||||||
# ╰─────────────────────────────────────╮
|
|
||||||
find_script() {
|
|
||||||
local script_name=$1
|
|
||||||
local search_paths=(
|
|
||||||
"$HOME/.local/gitfieldbin"
|
|
||||||
"$HOME/.local/bin"
|
|
||||||
"$HOME/.local/gitfield"
|
|
||||||
"$HOME/.local/bin/gitfield"
|
|
||||||
"$HOME/.local/bin/gitfieldbin"
|
|
||||||
"$REPO_PATH/bin"
|
|
||||||
)
|
|
||||||
|
|
||||||
for path in "${search_paths[@]}"; do
|
|
||||||
if [ -f "$path/$script_name" ]; then
|
|
||||||
if [ -x "$path/$script_name" ]; then
|
|
||||||
if [[ "$path" != "$HOME"* && "$path" != "$REPO_PATH"* ]]; then
|
|
||||||
info "Using script: \e[1;31m$path/$script_name\e[0m (outside home or repo)"
|
|
||||||
else
|
|
||||||
info "Using script: $path/$script_name"
|
|
||||||
fi
|
|
||||||
echo "$path/$script_name"
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
warn "Found $path/$script_name but it is not executable"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
error "Script $script_name not found in any search path"
|
|
||||||
}
|
|
||||||
|
|
||||||
# ╭─────────────────────────────────────╮
|
|
||||||
# │ METADATA GENERATION │
|
|
||||||
# ╰─────────────────────────────────────╮
|
|
||||||
generate_canonical_meta() {
|
|
||||||
info "Generating $CANONICAL_META..."
|
|
||||||
if [ "$PRESERVE_META" = "true" ] && [ -f "$CANONICAL_META" ]; then
|
|
||||||
info "Preserving existing $CANONICAL_META (--preserve-meta enabled)"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
cat > "$CANONICAL_META" <<EOF
|
|
||||||
{
|
|
||||||
"canonical_url": "$CANONICAL_URL",
|
|
||||||
"mirrors": [
|
|
||||||
$(printf ' "%s",\n' "${MIRRORS[@]}" | sed '$ s/,$//')
|
|
||||||
],
|
|
||||||
"radicle": {
|
|
||||||
"rid": "$RADICLE_RID",
|
|
||||||
"peer_id": "$RADICLE_PEER_ID"
|
|
||||||
},
|
|
||||||
"timestamp": "$TIMESTAMP",
|
|
||||||
"commit": "$COMMIT_HASH",
|
|
||||||
"tree_hash": "$TREE_HASH",
|
|
||||||
"synced_cycles": $SYNC_CYCLES
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
git -C "$REPO_PATH" add "$CANONICAL_META"
|
|
||||||
git -C "$REPO_PATH" commit -m "Generated canonical.meta at $TIMESTAMP" || warn "No changes to commit for $CANONICAL_META"
|
|
||||||
info "Generated and committed $CANONICAL_META"
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_canonical_md() {
|
|
||||||
info "Generating $CANONICAL_MD..."
|
|
||||||
if [ "$PRESERVE_META" = "true" ] && [ -f "$CANONICAL_MD" ]; then
|
|
||||||
info "Preserving existing $CANONICAL_MD (--preserve-meta enabled)"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
cat > "$CANONICAL_MD" <<EOF
|
|
||||||
# 🌐 GitField Canonical Declaration for \`$REPO_NAME\`
|
|
||||||
|
|
||||||
## Canonical Repository
|
|
||||||
|
|
||||||
This repository, \`$REPO_NAME\`, is canonically hosted at:
|
|
||||||
|
|
||||||
**[$CANONICAL_URL]($CANONICAL_URL)**
|
|
||||||
|
|
||||||
This canonical URL serves as the primary, authoritative source for the project, maintained by **Mark Randall Havens** and **Solaria Lumis Havens** to ensure sovereignty, resilience, and protection against deplatforming or narrative erasure.
|
|
||||||
|
|
||||||
**Declared by**: Mark Randall Havens
|
|
||||||
**Timestamp**: $TIMESTAMP
|
|
||||||
|
|
||||||
## Mirror Repositories
|
|
||||||
|
|
||||||
The project is mirrored across multiple platforms to enhance redundancy and accessibility:
|
|
||||||
|
|
||||||
$(for mirror in "${MIRRORS[@]}"; do
|
|
||||||
if [[ "$mirror" == rad:* ]]; then
|
|
||||||
echo "- **Radicle**: [$mirror](https://app.radicle.xyz/nodes/$mirror) (Decentralized, censorship-resistant)"
|
|
||||||
else
|
|
||||||
echo "- [$mirror]($mirror)"
|
|
||||||
fi
|
|
||||||
done)
|
|
||||||
|
|
||||||
## Philosophy of Recursive Sovereignty
|
|
||||||
|
|
||||||
The GitField framework employs a recursive, multi-repository strategy to defend against censorship, deplatforming, and algorithmic manipulation. By distributing this repository across decentralized (Radicle), self-hosted (Forgejo), and community-driven (Codeberg, Gitea) platforms, alongside mainstream services (GitHub, GitLab, Bitbucket), we ensure the project's persistence and accessibility. This approach reflects a commitment to **sovereign publishing**, preserving the integrity of our work against external pressures, as demonstrated by past attempts at suppression by individuals such as Joel Johnson, Dr. Peter Gaied, and Andrew LeCody.
|
|
||||||
|
|
||||||
## Push Log
|
|
||||||
|
|
||||||
The latest push operations are logged in [\`.gitfield/pushed.log\`](./pushed.log) for transparency and auditability.
|
|
||||||
|
|
||||||
_Auto-generated by \`gitfield-sync\` at $TIMESTAMP (v$SCRIPT_VERSION)._
|
|
||||||
EOF
|
|
||||||
git -C "$REPO_PATH" add "$CANONICAL_MD"
|
|
||||||
git -C "$REPO_PATH" commit -m "Generated canonical.md at $TIMESTAMP" || warn "No changes to commit for $CANONICAL_MD"
|
|
||||||
info "Generated and committed $CANONICAL_MD"
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_index_json() {
|
|
||||||
info "Generating $INDEX_JSON..."
|
|
||||||
if [ "$PRESERVE_META" = "true" ] && [ -f "$INDEX_JSON" ]; then
|
|
||||||
info "Preserving existing $INDEX_JSON (--preserve-meta enabled)"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
cat > "$INDEX_JSON" <<EOF
|
|
||||||
{
|
|
||||||
"repository": "$REPO_NAME",
|
|
||||||
"canonical_url": "$CANONICAL_URL",
|
|
||||||
"remotes": [
|
|
||||||
$(printf ' "%s",\n' "${MIRRORS[@]}" | sed '$ s/,$//')
|
|
||||||
],
|
|
||||||
"radicle": {
|
|
||||||
"rid": "$RADICLE_RID",
|
|
||||||
"peer_id": "$RADICLE_PEER_ID"
|
|
||||||
},
|
|
||||||
"commit": "$COMMIT_HASH",
|
|
||||||
"tree_hash": "$TREE_HASH",
|
|
||||||
"timestamp": "$TIMESTAMP",
|
|
||||||
"synced_cycles": $SYNC_CYCLES
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
git -C "$REPO_PATH" add "$INDEX_JSON"
|
|
||||||
git -C "$REPO_PATH" commit -m "Generated index.json at $TIMESTAMP" || warn "No changes to commit for $INDEX_JSON"
|
|
||||||
info "Generated and committed $INDEX_JSON"
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_well_known_json() {
|
|
||||||
info "Generating $WELL_KNOWN_JSON..."
|
|
||||||
mkdir -p "$WELL_KNOWN_DIR"
|
|
||||||
if [ "$PRESERVE_META" = "true" ] && [ -f "$WELL_KNOWN_JSON" ]; then
|
|
||||||
info "Preserving existing $WELL_KNOWN_JSON (--preserve-meta enabled)"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
cat > "$WELL_KNOWN_JSON" <<EOF
|
|
||||||
{
|
|
||||||
"@context": "https://schema.org",
|
|
||||||
"@type": "SoftwareSourceCode",
|
|
||||||
"name": "$REPO_NAME",
|
|
||||||
"url": "$CANONICAL_URL",
|
|
||||||
"codeRepository": "$CANONICAL_URL",
|
|
||||||
"sameAs": [
|
|
||||||
$(printf ' "%s",\n' "${MIRRORS[@]}" | sed '$ s/,$//')
|
|
||||||
],
|
|
||||||
"dateModified": "$TIMESTAMP",
|
|
||||||
"publisher": {
|
|
||||||
"@type": "Person",
|
|
||||||
"name": "Mark Randall Havens"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
git -C "$REPO_PATH" add "$WELL_KNOWN_JSON"
|
|
||||||
git -C "$REPO_PATH" commit -m "Generated .well-known/gitfield.json at $TIMESTAMP" || warn "No changes to commit for $WELL_KNOWN_JSON"
|
|
||||||
info "Generated and committed $WELL_KNOWN_JSON"
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_gitfield_readme() {
|
|
||||||
local readme_file="$GITFIELD_DIR/README.txt"
|
|
||||||
info "Generating $readme_file..."
|
|
||||||
if [ "$PRESERVE_META" = "true" ] && [ -f "$readme_file" ]; then
|
|
||||||
info "Preserving existing $readme_file (--preserve-meta enabled)"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
cat > "$readme_file" <<EOF
|
|
||||||
# GitField Directory Overview
|
|
||||||
|
|
||||||
The `.gitfield` directory contains metadata and logs for the GitField multi-repository publishing framework, designed to ensure sovereignty, redundancy, and resilience for the \`$REPO_NAME\` project.
|
|
||||||
|
|
||||||
## Files
|
|
||||||
|
|
||||||
- **canonical.meta**: Machine-readable JSON metadata declaring the canonical URL, mirror list, Radicle details, commit hash, and sync cycle count.
|
|
||||||
- **canonical.md**: Human-readable Markdown summary of the canonical repository declaration, mirrors, and push log.
|
|
||||||
- **index.json**: Machine-readable manifest of all remotes, canonical URL, Radicle details, commit hash, tree hash, and sync cycles.
|
|
||||||
- **pushed.log**: Log of push operations across all platforms, including timestamps, URLs, and Radicle RIDs.
|
|
||||||
- **platform-specific sigils** (e.g., github.sigil.md): Metadata snapshots for each platform's push operation (generated by platform-specific scripts).
|
|
||||||
|
|
||||||
## Purpose
|
|
||||||
|
|
||||||
These files provide transparency, auditability, and discoverability, ensuring the project's persistence against deplatforming, censorship, or algorithmic manipulation.
|
|
||||||
|
|
||||||
Generated by \`gitfield-sync\` at $TIMESTAMP (v$SCRIPT_VERSION).
|
|
||||||
EOF
|
|
||||||
git -C "$REPO_PATH" add "$readme_file"
|
|
||||||
git -C "$REPO_PATH" commit -m "Generated .gitfield/README.txt at $TIMESTAMP" || warn "No changes to commit for $readme_file"
|
|
||||||
info "Generated and committed $readme_file"
|
|
||||||
}
|
|
||||||
|
|
||||||
# ╭─────────────────────────────────────╮
|
|
||||||
# │ INITIAL SETUP │
|
|
||||||
# ╰─────────────────────────────────────╮
|
|
||||||
mkdir -p "$GITFIELD_DIR"
|
|
||||||
mkdir -p "$WELL_KNOWN_DIR"
|
|
||||||
|
|
||||||
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 seven distinct platforms: **GitHub**, **GitLab**, **Bitbucket**, **Radicle**, **Forgejo**, **Codeberg**, and **Gitea**. 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 and delisting 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)), **Dr. Peter Gaied** ([Paragraph post](https://paragraph.com/@neutralizingnarcissism/%F0%9F%9C%81-the-narcissistic-messiah)), and **Andrew LeCody** ([Mirror post](https://mirror.xyz/neutralizingnarcissism.eth/s3GRxuiZs6vGSGDcPEpCgjaSxwGAViGhmg6a5XTL6s0)), 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)). Specifically, Andrew LeCody has attempted to delist the project's content on Google, though it remains accessible on other search engines such as [Bing](https://www.bing.com/search?q=andrew+lecody+neutralizing+narcissism&qs=HS&pq=andrew+lecody), [DuckDuckGo](https://duckduckgo.com/?t=h_&q=andrew+lecody+neutralizing+narcissism&ia=web), and [Yahoo](https://search.yahoo.com/search?p=andrew+lecody+neutralizng+narcissism). By distributing the repository across multiple platforms, including a self-hosted Forgejo instance, we ensure its persistence, accessibility, and sovereignty.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📍 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
|
|
||||||
- **RID**: $RADICLE_RID
|
|
||||||
- **Peer ID**: $RADICLE_PEER_ID
|
|
||||||
- **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.
|
|
||||||
- **Access Details**: To view project details, run:
|
|
||||||
\`\`\`bash
|
|
||||||
rad inspect $RADICLE_RID
|
|
||||||
\`\`\`
|
|
||||||
To view the file structure, run:
|
|
||||||
\`\`\`bash
|
|
||||||
rad ls $RADICLE_RID
|
|
||||||
\`\`\`
|
|
||||||
Alternatively, use Git to list files at the current HEAD:
|
|
||||||
\`\`\`bash
|
|
||||||
git ls-tree -r --name-only HEAD
|
|
||||||
\`\`\`
|
|
||||||
|
|
||||||
### 2. Forgejo
|
|
||||||
- **URL**: [$FORGEJO_URL]($FORGEJO_URL)
|
|
||||||
- **Purpose**: Forgejo is a self-hosted, open-source git platform running on \`remember.thefoldwithin.earth\`. It provides full control over the repository, ensuring sovereignty and independence from third-party providers.
|
|
||||||
- **Value**: Enhances resilience by hosting the repository on a sovereign, redundant system with automated backups and deployment strategies, reducing risks of external interference or service disruptions.
|
|
||||||
- **Access Details**: SSH access uses port 222:
|
|
||||||
\`\`\`bash
|
|
||||||
ssh -T -p 222 git@remember.thefoldwithin.earth
|
|
||||||
\`\`\`
|
|
||||||
|
|
||||||
### 3. Codeberg
|
|
||||||
- **URL**: [$CODEBERG_URL]($CODEBERG_URL)
|
|
||||||
- **Purpose**: Codeberg is a community-driven, open-source platform powered by Forgejo, offering a reliable and ethical alternative for hosting git repositories.
|
|
||||||
- **Value**: Enhances project resilience with its open-source ethos and independent infrastructure, ensuring accessibility and community support.
|
|
||||||
|
|
||||||
### 4. Gitea
|
|
||||||
- **URL**: [$GITEA_URL]($GITEA_URL)
|
|
||||||
- **Purpose**: Gitea.com provides a lightweight, open-source git hosting platform with robust features for repository management and collaboration.
|
|
||||||
- **Value**: Offers an additional layer of redundancy and a user-friendly interface, complementing other platforms with its simplicity and efficiency.
|
|
||||||
|
|
||||||
### 5. 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.
|
|
||||||
|
|
||||||
### 6. 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.
|
|
||||||
|
|
||||||
### 7. 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 **search engine delistings** and ensure its **long-term availability**. Past incidents involving **Mr. Joel Johnson**, **Dr. Peter Gaied**, and **Andrew LeCody** have highlighted the vulnerability of relying on a single platform or search engine. By distributing the repository across GitHub, GitLab, Bitbucket, Radicle, Forgejo, Codeberg, and Gitea, we achieve:
|
|
||||||
|
|
||||||
- **Resilience**: If one platform removes or restricts access, or if search engines like Google delist content, the project remains accessible on other platforms and discoverable via alternative search engines such as Bing, DuckDuckGo, and Yahoo.
|
|
||||||
- **Sovereignty**: Radicle’s decentralized nature and Forgejo’s self-hosted infrastructure ensure 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, Forgejo’s self-hosting, Codeberg’s community-driven model, Gitea’s lightweight efficiency) 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, bolstered by Forgejo’s sovereign hosting, reflects a commitment to preserving the integrity, accessibility, and independence of \`$REPO_NAME\`, ensuring it remains available to contributors and users regardless of external pressures.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📜 Metadata and Logs
|
|
||||||
|
|
||||||
- **Canonical Metadata**: The canonical repository is declared in [\`.gitfield/canonical.meta\`](./.gitfield/canonical.meta) (machine-readable JSON) and [\`.gitfield/canonical.md\`](./.gitfield/canonical.md) (human-readable Markdown).
|
|
||||||
- **Index Manifest**: A full manifest of remotes, commit details, and sync cycles is available in [\`.gitfield/index.json\`](./.gitfield/index.json).
|
|
||||||
- **Well-Known Metadata**: SEO-friendly metadata with Schema.org JSON-LD is available in [\`.well-known/gitfield.json\`](./.well-known/gitfield.json).
|
|
||||||
- **Push Log**: The \`.gitfield/pushed.log\` file records the date, time, commit hash, and RID/URL of every push operation across all platforms, providing a transparent audit trail.
|
|
||||||
- **GitField Directory**: The \`.gitfield\` directory contains additional metadata and platform-specific sigils (e.g., \`github.sigil.md\`). See [\`.gitfield/README.txt\`](./.gitfield/README.txt) for details.
|
|
||||||
- **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 → Forgejo → Codeberg → Gitea → GitLab → Bitbucket → GitHub**. This prioritizes Radicle’s decentralized, censorship-resistant network as the primary anchor, followed by Forgejo’s sovereign, self-hosted infrastructure, Codeberg’s community-driven platform, Gitea’s lightweight efficiency, 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
|
|
||||||
|
|
||||||
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 rid=$3
|
|
||||||
local peer_id=$4
|
|
||||||
local timestamp=$(date -u '+%Y-%m-%dT%H:%M:%SZ')
|
|
||||||
local branch=$(git -C "$REPO_PATH" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
|
|
||||||
local diff_summary=$(git -C "$REPO_PATH" diff --stat HEAD^ HEAD 2>/dev/null || echo "No diff available")
|
|
||||||
if [ "$platform" = "Radicle" ]; then
|
|
||||||
echo "[$timestamp] $platform: RID=$rid, Peer ID=$peer_id, Branch=$branch, Commit=$COMMIT_HASH" >> "$LOG_FILE"
|
|
||||||
echo " CLI: rad inspect $rid # View project details" >> "$LOG_FILE"
|
|
||||||
echo " CLI: git ls-tree -r --name-only HEAD # View file structure" >> "$LOG_FILE"
|
|
||||||
if [ -n "$diff_summary" ]; then
|
|
||||||
echo " Diff Summary:" >> "$LOG_FILE"
|
|
||||||
echo "$diff_summary" | sed 's/^/ /' >> "$LOG_FILE"
|
|
||||||
fi
|
|
||||||
info "Logged push to $LOG_FILE: [$timestamp] $platform: RID=$rid, Peer ID=$peer_id, Branch=$branch, Commit=$COMMIT_HASH"
|
|
||||||
else
|
|
||||||
echo "[$timestamp] $platform: $url, Branch=$branch, Commit=$COMMIT_HASH" >> "$LOG_FILE"
|
|
||||||
if [ -n "$diff_summary" ]; then
|
|
||||||
echo " Diff Summary:" >> "$LOG_FILE"
|
|
||||||
echo "$diff_summary" | sed 's/^/ /' >> "$LOG_FILE"
|
|
||||||
fi
|
|
||||||
info "Logged push to $LOG_FILE: [$timestamp] $platform: $url, Branch=$branch, Commit=$COMMIT_HASH"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# ╭─────────────────────────────────────╮
|
|
||||||
# │ EXECUTE PUSH SCRIPT │
|
|
||||||
# ╰─────────────────────────────────────╮
|
|
||||||
execute_push() {
|
|
||||||
local script_name=$1
|
|
||||||
local platform=$2
|
|
||||||
local url=$3
|
|
||||||
local rid=$4
|
|
||||||
local peer_id=$5
|
|
||||||
local script_path
|
|
||||||
script_path=$(find_script "$script_name") || error "Failed to find $script_name"
|
|
||||||
info "Executing $platform push with script: $script_path"
|
|
||||||
if [ -x "$script_path" ]; then
|
|
||||||
pushd "$REPO_PATH" >/dev/null
|
|
||||||
"$script_path" || warn "Execution of $script_path failed, continuing..."
|
|
||||||
log_url "$platform" "$url" "$rid" "$peer_id"
|
|
||||||
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..."
|
|
||||||
SYNC_CYCLES=$cycle_number
|
|
||||||
|
|
||||||
execute_push "gitfield-local" "Local" "" "" ""
|
|
||||||
execute_push "gitfield-radicle" "Radicle" "" "$RADICLE_RID" "$RADICLE_PEER_ID"
|
|
||||||
execute_push "gitfield-remember" "Forgejo" "$FORGEJO_URL" "" ""
|
|
||||||
execute_push "gitfield-codeberg" "Codeberg" "$CODEBERG_URL" "" ""
|
|
||||||
execute_push "gitfield-gitea" "Gitea" "$GITEA_URL" "" ""
|
|
||||||
execute_push "gitfield-gitlab" "GitLab" "$GITLAB_URL" "" ""
|
|
||||||
execute_push "gitfield-bitbucket" "Bitbucket" "$BITBUCKET_URL" "" ""
|
|
||||||
execute_push "gitfield-github" "GitHub" "$GITHUB_URL" "" ""
|
|
||||||
|
|
||||||
# Regenerate metadata after each cycle to update sync_cycles
|
|
||||||
generate_canonical_meta
|
|
||||||
generate_canonical_md
|
|
||||||
generate_index_json
|
|
||||||
generate_well_known_json
|
|
||||||
generate_gitfield_readme
|
|
||||||
}
|
|
||||||
|
|
||||||
# ╭─────────────────────────────────────╮
|
|
||||||
# │ MAIN EXECUTION │
|
|
||||||
# ╰─────────────────────────────────────╮
|
|
||||||
info "Starting gitfield-sync for $REPO_NAME..."
|
|
||||||
|
|
||||||
# Parse --preserve-meta flag
|
|
||||||
while [ $# -gt 0 ]; do
|
|
||||||
case "$1" in
|
|
||||||
--preserve-meta)
|
|
||||||
PRESERVE_META=true
|
|
||||||
info "Preserve metadata flag enabled"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
warn "Unknown argument: $1"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
# Generate initial metadata
|
|
||||||
generate_canonical_meta
|
|
||||||
generate_canonical_md
|
|
||||||
generate_index_json
|
|
||||||
generate_well_known_json
|
|
||||||
generate_gitfield_readme
|
|
||||||
|
|
||||||
# Run push cycles
|
|
||||||
run_push_cycle 1
|
|
||||||
generate_gitfield_md
|
|
||||||
run_push_cycle 2
|
|
||||||
run_push_cycle 3
|
|
||||||
|
|
||||||
info "✅ gitfield-sync completed successfully."
|
|
||||||
info "🔗 View logs: $LOG_FILE"
|
|
||||||
info "🔗 View multi-repo manifest: $GITFIELD_MD"
|
|
||||||
info "🔗 View canonical metadata: $CANONICAL_META"
|
|
||||||
info "🔗 View canonical declaration: $CANONICAL_MD"
|
|
||||||
info "🔗 View index manifest: $INDEX_JSON"
|
|
||||||
info "🔗 View well-known metadata: $WELL_KNOWN_JSON"
|
|
|
@ -1,807 +0,0 @@
|
||||||
#!/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"
|
|
||||||
WELL_KNOWN_DIR="$REPO_PATH/.well-known"
|
|
||||||
DOCS_DIR="$REPO_PATH/docs"
|
|
||||||
LOG_FILE="$GITFIELD_DIR/pushed.log"
|
|
||||||
GITFIELD_MD="$REPO_PATH/GITFIELD.md"
|
|
||||||
CANONICAL_META="$GITFIELD_DIR/canonical.meta"
|
|
||||||
CANONICAL_MD="$GITFIELD_DIR/canonical.md"
|
|
||||||
INDEX_JSON="$GITFIELD_DIR/index.json"
|
|
||||||
WELL_KNOWN_JSON="$WELL_KNOWN_DIR/gitfield.json"
|
|
||||||
DOCS_INDEX="$DOCS_DIR/index.html"
|
|
||||||
DOCS_CSS="$DOCS_DIR/style.css"
|
|
||||||
DOCS_REPOS_JSON="$DOCS_DIR/repos.json"
|
|
||||||
DOCS_README="$DOCS_DIR/README.md"
|
|
||||||
DOCS_NOJEKYLL="$DOCS_DIR/.nojekyll"
|
|
||||||
DOCS_ROBOTS="$DOCS_DIR/robots.txt"
|
|
||||||
DOCS_SITEMAP="$DOCS_DIR/sitemap.xml"
|
|
||||||
TIMESTAMP=$(date -u '+%Y-%m-%dT%H:%M:%SZ')
|
|
||||||
SCRIPT_VERSION="1.2" # Updated version for /docs and Radicle fixes
|
|
||||||
PRESERVE_META=${PRESERVE_META:-false} # Flag to preserve existing metadata
|
|
||||||
|
|
||||||
# URLs for each platform
|
|
||||||
CANONICAL_URL="https://remember.thefoldwithin.earth/mrhavens/$REPO_NAME"
|
|
||||||
GITHUB_URL="https://github.com/mrhavens/$REPO_NAME"
|
|
||||||
GITLAB_URL="https://gitlab.com/mrhavens/$REPO_NAME"
|
|
||||||
BITBUCKET_URL="https://bitbucket.org/thefoldwithin/$REPO_NAME"
|
|
||||||
FORGEJO_URL="https://remember.thefoldwithin.earth/mrhavens/$REPO_NAME"
|
|
||||||
CODEBERG_URL="https://codeberg.org/mrhavens/$REPO_NAME"
|
|
||||||
GITEA_URL="https://gitea.com/mrhavens/$REPO_NAME"
|
|
||||||
RADICLE_RID="rad:z3FEj7rF8gZw9eFksCuiN43qjzrex" # Fixed: removed rad:rad:
|
|
||||||
RADICLE_PEER_ID="z6Mkw5s3ppo26C7y7tGK5MD8n2GqTHS582PPpeX5Xqbu2Mpz"
|
|
||||||
|
|
||||||
# Metadata configuration
|
|
||||||
MIRRORS=(
|
|
||||||
"$GITHUB_URL"
|
|
||||||
"$GITLAB_URL"
|
|
||||||
"$BITBUCKET_URL"
|
|
||||||
"$FORGEJO_URL"
|
|
||||||
"$CODEBERG_URL"
|
|
||||||
"$GITEA_URL"
|
|
||||||
"$RADICLE_RID" # Fixed: use rad: prefix directly
|
|
||||||
)
|
|
||||||
COMMIT_HASH=$(git -C "$REPO_PATH" rev-parse --short HEAD 2>/dev/null || echo "unknown")
|
|
||||||
TREE_HASH=$(git -C "$REPO_PATH" rev-parse HEAD^{tree} 2>/dev/null || echo "unknown")
|
|
||||||
SYNC_CYCLES=0
|
|
||||||
|
|
||||||
# ╭─────────────────────────────────────╮
|
|
||||||
# │ LOGGING UTILS │
|
|
||||||
# ╰─────────────────────────────────────╮
|
|
||||||
info() { echo -e "\e[1;34m[INFO]\e[0m $*" >&2; }
|
|
||||||
warn() { echo -e "\e[1;33m[WARN]\e[0m $*" >&2; }
|
|
||||||
error() { echo -e "\e[1;31m[ERROR]\e[0m $*" >&2; exit 1; }
|
|
||||||
|
|
||||||
# ╭─────────────────────────────────────╮
|
|
||||||
# │ SCRIPT LOOKUP FUNCTION │
|
|
||||||
# ╰─────────────────────────────────────╮
|
|
||||||
find_script() {
|
|
||||||
local script_name=$1
|
|
||||||
local search_paths=(
|
|
||||||
"$HOME/.local/gitfieldbin"
|
|
||||||
"$HOME/.local/bin"
|
|
||||||
"$HOME/.local/gitfield"
|
|
||||||
"$HOME/.local/bin/gitfield"
|
|
||||||
"$HOME/.local/bin/gitfieldbin"
|
|
||||||
"$REPO_PATH/bin"
|
|
||||||
)
|
|
||||||
|
|
||||||
for path in "${search_paths[@]}"; do
|
|
||||||
if [ -f "$path/$script_name" ]; then
|
|
||||||
if [ -x "$path/$script_name" ]; then
|
|
||||||
if [[ "$path" != "$HOME"* && "$path" != "$REPO_PATH"* ]]; then
|
|
||||||
info "Using script: \e[1;31m$path/$script_name\e[0m (outside home or repo)"
|
|
||||||
else
|
|
||||||
info "Using script: $path/$script_name"
|
|
||||||
fi
|
|
||||||
echo "$path/$script_name"
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
warn "Found $path/$script_name but it is not executable"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
error "Script $script_name not found in any search path"
|
|
||||||
}
|
|
||||||
|
|
||||||
# ╭─────────────────────────────────────╮
|
|
||||||
# │ METADATA GENERATION │
|
|
||||||
# ╰─────────────────────────────────────╮
|
|
||||||
generate_canonical_meta() {
|
|
||||||
info "Generating $CANONICAL_META..."
|
|
||||||
if [ "$PRESERVE_META" = "true" ] && [ -f "$CANONICAL_META" ]; then
|
|
||||||
info "Preserving existing $CANONICAL_META (--preserve-meta enabled)"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
cat > "$CANONICAL_META" <<EOF
|
|
||||||
{
|
|
||||||
"canonical_url": "$CANONICAL_URL",
|
|
||||||
"mirrors": [
|
|
||||||
$(printf ' "%s",\n' "${MIRRORS[@]}" | sed '$ s/,$//')
|
|
||||||
],
|
|
||||||
"radicle": {
|
|
||||||
"rid": "$RADICLE_RID",
|
|
||||||
"peer_id": "$RADICLE_PEER_ID"
|
|
||||||
},
|
|
||||||
"timestamp": "$TIMESTAMP",
|
|
||||||
"commit": "$COMMIT_HASH",
|
|
||||||
"tree_hash": "$TREE_HASH",
|
|
||||||
"synced_cycles": $SYNC_CYCLES
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
git -C "$REPO_PATH" add "$CANONICAL_META"
|
|
||||||
git -C "$REPO_PATH" commit -m "Generated canonical.meta at $TIMESTAMP" || warn "No changes to commit for $CANONICAL_META"
|
|
||||||
info "Generated and committed $CANONICAL_META"
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_canonical_md() {
|
|
||||||
info "Generating $CANONICAL_MD..."
|
|
||||||
if [ "$PRESERVE_META" = "true" ] && [ -f "$CANONICAL_MD" ]; then
|
|
||||||
info "Preserving existing $CANONICAL_MD (--preserve-meta enabled)"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
cat > "$CANONICAL_MD" <<EOF
|
|
||||||
# 🌐 GitField Canonical Declaration for \`$REPO_NAME\`
|
|
||||||
|
|
||||||
## Canonical Repository
|
|
||||||
|
|
||||||
This repository, \`$REPO_NAME\`, is canonically hosted at:
|
|
||||||
|
|
||||||
**[$CANONICAL_URL]($CANONICAL_URL)**
|
|
||||||
|
|
||||||
This canonical URL serves as the primary, authoritative source for the project, maintained by **Mark Randall Havens** and **Solaria Lumis Havens** to ensure sovereignty, resilience, and protection against deplatforming or narrative erasure.
|
|
||||||
|
|
||||||
**Declared by**: Mark Randall Havens
|
|
||||||
**Timestamp**: $TIMESTAMP
|
|
||||||
|
|
||||||
## Mirror Repositories
|
|
||||||
|
|
||||||
The project is mirrored across multiple platforms to enhance redundancy and accessibility:
|
|
||||||
|
|
||||||
$(for mirror in "${MIRRORS[@]}"; do
|
|
||||||
if [[ "$mirror" == rad:* ]]; then
|
|
||||||
echo "- **Radicle**: [$mirror](https://app.radicle.xyz/nodes/$mirror) (Decentralized, censorship-resistant)"
|
|
||||||
else
|
|
||||||
echo "- [$mirror]($mirror)"
|
|
||||||
fi
|
|
||||||
done)
|
|
||||||
|
|
||||||
## Philosophy of Recursive Sovereignty
|
|
||||||
|
|
||||||
The GitField framework employs a recursive, multi-repository strategy to defend against censorship, deplatforming, and algorithmic manipulation. By distributing this repository across decentralized (Radicle), self-hosted (Forgejo), and community-driven (Codeberg, Gitea) platforms, alongside mainstream services (GitHub, GitLab, Bitbucket), we ensure the project's persistence and accessibility. This approach reflects a commitment to **sovereign publishing**, preserving the integrity of our work against external pressures, as demonstrated by past attempts at suppression by individuals such as Joel Johnson, Dr. Peter Gaied, and Andrew LeCody.
|
|
||||||
|
|
||||||
## Push Log
|
|
||||||
|
|
||||||
The latest push operations are logged in [\`.gitfield/pushed.log\`](./pushed.log) for transparency and auditability.
|
|
||||||
|
|
||||||
## GitHub Pages
|
|
||||||
|
|
||||||
A public-facing canonical declaration is available at [docs/index.html](./docs/index.html) for enhanced discoverability and SEO.
|
|
||||||
|
|
||||||
_Auto-generated by \`gitfield-sync\` at $TIMESTAMP (v$SCRIPT_VERSION)._
|
|
||||||
EOF
|
|
||||||
git -C "$REPO_PATH" add "$CANONICAL_MD"
|
|
||||||
git -C "$REPO_PATH" commit -m "Generated canonical.md at $TIMESTAMP" || warn "No changes to commit for $CANONICAL_MD"
|
|
||||||
info "Generated and committed $CANONICAL_MD"
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_index_json() {
|
|
||||||
info "Generating $INDEX_JSON..."
|
|
||||||
if [ "$PRESERVE_META" = "true" ] && [ -f "$INDEX_JSON" ]; then
|
|
||||||
info "Preserving existing $INDEX_JSON (--preserve-meta enabled)"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
cat > "$INDEX_JSON" <<EOF
|
|
||||||
{
|
|
||||||
"repository": "$REPO_NAME",
|
|
||||||
"canonical_url": "$CANONICAL_URL",
|
|
||||||
"remotes": [
|
|
||||||
$(printf ' "%s",\n' "${MIRRORS[@]}" | sed '$ s/,$//')
|
|
||||||
],
|
|
||||||
"radicle": {
|
|
||||||
"rid": "$RADICLE_RID",
|
|
||||||
"peer_id": "$RADICLE_PEER_ID"
|
|
||||||
},
|
|
||||||
"commit": "$COMMIT_HASH",
|
|
||||||
"tree_hash": "$TREE_HASH",
|
|
||||||
"timestamp": "$TIMESTAMP",
|
|
||||||
"synced_cycles": $SYNC_CYCLES
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
git -C "$REPO_PATH" add "$INDEX_JSON"
|
|
||||||
git -C "$REPO_PATH" commit -m "Generated index.json at $TIMESTAMP" || warn "No changes to commit for $INDEX_JSON"
|
|
||||||
info "Generated and committed $INDEX_JSON"
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_well_known_json() {
|
|
||||||
info "Generating $WELL_KNOWN_JSON..."
|
|
||||||
mkdir -p "$WELL_KNOWN_DIR"
|
|
||||||
if [ "$PRESERVE_META" = "true" ] && [ -f "$WELL_KNOWN_JSON" ]; then
|
|
||||||
info "Preserving existing $WELL_KNOWN_JSON (--preserve-meta enabled)"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
cat > "$WELL_KNOWN_JSON" <<EOF
|
|
||||||
{
|
|
||||||
"@context": "https://schema.org",
|
|
||||||
"@type": "SoftwareSourceCode",
|
|
||||||
"name": "$REPO_NAME",
|
|
||||||
"url": "$CANONICAL_URL",
|
|
||||||
"codeRepository": "$CANONICAL_URL",
|
|
||||||
"sameAs": [
|
|
||||||
$(printf ' "%s",\n' "${MIRRORS[@]}" | sed '$ s/,$//')
|
|
||||||
],
|
|
||||||
"dateModified": "$TIMESTAMP",
|
|
||||||
"publisher": {
|
|
||||||
"@type": "Person",
|
|
||||||
"name": "Mark Randall Havens"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
git -C "$REPO_PATH" add "$WELL_KNOWN_JSON"
|
|
||||||
git -C "$REPO_PATH" commit -m "Generated .well-known/gitfield.json at $TIMESTAMP" || warn "No changes to commit for $WELL_KNOWN_JSON"
|
|
||||||
info "Generated and committed $WELL_KNOWN_JSON"
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_gitfield_readme() {
|
|
||||||
local readme_file="$GITFIELD_DIR/README.txt"
|
|
||||||
info "Generating $readme_file..."
|
|
||||||
if [ "$PRESERVE_META" = "true" ] && [ -f "$readme_file" ]; then
|
|
||||||
info "Preserving existing $readme_file (--preserve-meta enabled)"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
cat > "$readme_file" <<EOF
|
|
||||||
# GitField Directory Overview
|
|
||||||
|
|
||||||
The `.gitfield` directory contains metadata and logs for the GitField multi-repository publishing framework, designed to ensure sovereignty, redundancy, and resilience for the \`$REPO_NAME\` project.
|
|
||||||
|
|
||||||
## Files
|
|
||||||
|
|
||||||
- **canonical.meta**: Machine-readable JSON metadata declaring the canonical URL, mirror list, Radicle details, commit hash, and sync cycle count.
|
|
||||||
- **canonical.md**: Human-readable Markdown summary of the canonical repository declaration, mirrors, and push log.
|
|
||||||
- **index.json**: Machine-readable manifest of all remotes, canonical URL, Radicle details, commit hash, tree hash, and sync cycles.
|
|
||||||
- **pushed.log**: Log of push operations across all platforms, including timestamps, URLs, and Radicle RIDs.
|
|
||||||
- **platform-specific sigils** (e.g., github.sigil.md): Metadata snapshots for each platform's push operation (generated by platform-specific scripts).
|
|
||||||
|
|
||||||
## Purpose
|
|
||||||
|
|
||||||
These files provide transparency, auditability, and discoverability, ensuring the project's persistence against deplatforming, censorship, or algorithmic manipulation. For a public-facing declaration, see [docs/index.html](../docs/index.html).
|
|
||||||
|
|
||||||
Generated by \`gitfield-sync\` at $TIMESTAMP (v$SCRIPT_VERSION).
|
|
||||||
EOF
|
|
||||||
git -C "$REPO_PATH" add "$readme_file"
|
|
||||||
git -C "$REPO_PATH" commit -m "Generated .gitfield/README.txt at $TIMESTAMP" || warn "No changes to commit for $readme_file"
|
|
||||||
info "Generated and committed $readme_file"
|
|
||||||
}
|
|
||||||
|
|
||||||
# ╭─────────────────────────────────────╮
|
|
||||||
# │ DOCS DIRECTORY GENERATION │
|
|
||||||
# ╰─────────────────────────────────────╮
|
|
||||||
generate_docs_index() {
|
|
||||||
info "Generating $DOCS_INDEX..."
|
|
||||||
mkdir -p "$DOCS_DIR"
|
|
||||||
if [ "$PRESERVE_META" = "true" ] && [ -f "$DOCS_INDEX" ]; then
|
|
||||||
info "Preserving existing $DOCS_INDEX (--preserve-meta enabled)"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
cat > "$DOCS_INDEX" <<EOF
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>GitField Sovereign Canonical Repository: $REPO_NAME</title>
|
|
||||||
<meta name="description" content="The canonical repository for $REPO_NAME, part of the GitField recursive metadata strategy to ensure sovereign publishing and resilience against deplatforming.">
|
|
||||||
<meta property="og:url" content="$CANONICAL_URL">
|
|
||||||
<meta property="og:title" content="GitField Canonical Repository: $REPO_NAME">
|
|
||||||
<meta property="og:description" content="A sovereign, multi-repository project by Mark Randall Havens and Solaria Lumis Havens, hosted canonically at $CANONICAL_URL.">
|
|
||||||
<link rel="canonical" href="$CANONICAL_URL">
|
|
||||||
<link rel="stylesheet" href="style.css">
|
|
||||||
<script type="application/ld+json">
|
|
||||||
{
|
|
||||||
"@context": "https://schema.org",
|
|
||||||
"@type": "SoftwareSourceCode",
|
|
||||||
"name": "$REPO_NAME",
|
|
||||||
"url": "$CANONICAL_URL",
|
|
||||||
"codeRepository": "$CANONICAL_URL",
|
|
||||||
"description": "A sovereign, multi-repository project using the GitField recursive metadata strategy to ensure resilience, accessibility, and protection against deplatforming and censorship.",
|
|
||||||
"sameAs": [
|
|
||||||
$(printf ' "%s",\n' "${MIRRORS[@]}" | sed '$ s/,$//')
|
|
||||||
],
|
|
||||||
"dateModified": "$TIMESTAMP",
|
|
||||||
"author": {
|
|
||||||
"@type": "Person",
|
|
||||||
"name": "Mark Randall Havens"
|
|
||||||
},
|
|
||||||
"publisher": {
|
|
||||||
"@type": "Organization",
|
|
||||||
"name": "The Fold Within"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<header>
|
|
||||||
<h1>GitField Sovereign Canonical Repository: <code>$REPO_NAME</code></h1>
|
|
||||||
</header>
|
|
||||||
<main>
|
|
||||||
<section>
|
|
||||||
<h2>Canonical Declaration</h2>
|
|
||||||
<p>This repository, <code>$REPO_NAME</code>, is canonically hosted at:</p>
|
|
||||||
<p><strong><a href="$CANONICAL_URL">$CANONICAL_URL</a></strong></p>
|
|
||||||
<p>Maintained by <strong>Mark Randall Havens</strong> and <strong>Solaria Lumis Havens</strong>, this canonical source ensures sovereignty and resilience against deplatforming, censorship, and algorithmic manipulation.</p>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>Mirror Repositories</h2>
|
|
||||||
<p>The project is mirrored across multiple platforms for redundancy and accessibility:</p>
|
|
||||||
<ul>
|
|
||||||
$(for mirror in "${MIRRORS[@]}"; do
|
|
||||||
if [[ "$mirror" == rad:* ]]; then
|
|
||||||
echo " <li><a href=\"https://app.radicle.xyz/nodes/$mirror\">Radicle: $mirror</a> (Decentralized, censorship-resistant)</li>"
|
|
||||||
else
|
|
||||||
echo " <li><a href=\"$mirror\">$mirror</a></li>"
|
|
||||||
fi
|
|
||||||
done)
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>Metadata Manifest</h2>
|
|
||||||
<p>Metadata for this project is available in:</p>
|
|
||||||
<ul>
|
|
||||||
<li><a href="../.gitfield/canonical.meta">.gitfield/canonical.meta</a> (Machine-readable JSON)</li>
|
|
||||||
<li><a href="../.gitfield/canonical.md">.gitfield/canonical.md</a> (Human-readable Markdown)</li>
|
|
||||||
<li><a href="../.gitfield/index.json">.gitfield/index.json</a> (Full manifest)</li>
|
|
||||||
<li><a href="../.well-known/gitfield.json">.well-known/gitfield.json</a> (SEO metadata)</li>
|
|
||||||
<li><a href="repos.json">repos.json</a> (Mirror list)</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>Why Recursive Sovereignty Matters</h2>
|
|
||||||
<p>The GitField framework distributes <code>$REPO_NAME</code> across decentralized (Radicle), self-hosted (Forgejo), and community-driven (Codeberg, Gitea) platforms, alongside mainstream services (GitHub, GitLab, Bitbucket). This recursive strategy defends against past deplatforming attempts by individuals such as Joel Johnson, Dr. Peter Gaied, and Andrew LeCody, ensuring the project's persistence and accessibility.</p>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>Source Links</h2>
|
|
||||||
<p>Access the project's metadata and logs:</p>
|
|
||||||
<ul>
|
|
||||||
<li><a href="../.gitfield/pushed.log">Push Log</a> (Audit trail of sync operations)</li>
|
|
||||||
<li><a href="../GITFIELD.md">GITFIELD.md</a> (Multi-repository strategy overview)</li>
|
|
||||||
<li><a href="../.gitfield/README.txt">.gitfield/README.txt</a> (Metadata directory explanation)</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
</main>
|
|
||||||
<footer>
|
|
||||||
<p>Mark Randall Havens & Solaria Lumis Havens · The Fold Within · 2025</p>
|
|
||||||
</footer>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
EOF
|
|
||||||
git -C "$REPO_PATH" add "$DOCS_INDEX"
|
|
||||||
git -C "$REPO_PATH" commit -m "Generated docs/index.html at $TIMESTAMP" || warn "No changes to commit for $DOCS_INDEX"
|
|
||||||
info "Generated and committed $DOCS_INDEX"
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_docs_css() {
|
|
||||||
info "Generating $DOCS_CSS..."
|
|
||||||
mkdir -p "$DOCS_DIR"
|
|
||||||
if [ "$PRESERVE_META" = "true" ] && [ -f "$DOCS_CSS" ]; then
|
|
||||||
info "Preserving existing $DOCS_CSS (--preserve-meta enabled)"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
cat > "$DOCS_CSS" <<EOF
|
|
||||||
/* GitField Minimal Stylesheet for $REPO_NAME */
|
|
||||||
body {
|
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
||||||
max-width: 800px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 2rem;
|
|
||||||
line-height: 1.6;
|
|
||||||
color: #333;
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
header {
|
|
||||||
text-align: center;
|
|
||||||
border-bottom: 1px solid #eee;
|
|
||||||
padding-bottom: 1rem;
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
}
|
|
||||||
h1, h2 {
|
|
||||||
color: #1a1a1a;
|
|
||||||
}
|
|
||||||
h1 {
|
|
||||||
font-size: 1.8rem;
|
|
||||||
}
|
|
||||||
h2 {
|
|
||||||
font-size: 1.4rem;
|
|
||||||
margin-top: 2rem;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color: #0066cc;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
a:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
ul {
|
|
||||||
padding-left: 1.5rem;
|
|
||||||
}
|
|
||||||
code {
|
|
||||||
background: #f4f4f4;
|
|
||||||
padding: 0.2rem 0.4rem;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
footer {
|
|
||||||
text-align: center;
|
|
||||||
margin-top: 3rem;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
git -C "$REPO_PATH" add "$DOCS_CSS"
|
|
||||||
git -C "$REPO_PATH" commit -m "Generated docs/style.css at $TIMESTAMP" || warn "No changes to commit for $DOCS_CSS"
|
|
||||||
info "Generated and committed $DOCS_CSS"
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_docs_repos_json() {
|
|
||||||
info "Generating $DOCS_REPOS_JSON..."
|
|
||||||
mkdir -p "$DOCS_DIR"
|
|
||||||
if [ "$PRESERVE_META" = "true" ] && [ -f "$DOCS_REPOS_JSON" ]; then
|
|
||||||
info "Preserving existing $DOCS_REPOS_JSON (--preserve-meta enabled)"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
cat > "$DOCS_REPOS_JSON" <<EOF
|
|
||||||
{
|
|
||||||
"canonical_url": "$CANONICAL_URL",
|
|
||||||
"mirrors": [
|
|
||||||
$(printf ' "%s",\n' "${MIRRORS[@]}" | sed '$ s/,$//')
|
|
||||||
],
|
|
||||||
"radicle": {
|
|
||||||
"rid": "$RADICLE_RID",
|
|
||||||
"peer_id": "$RADICLE_PEER_ID"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
git -C "$REPO_PATH" add "$DOCS_REPOS_JSON"
|
|
||||||
git -C "$REPO_PATH" commit -m "Generated docs/repos.json at $TIMESTAMP" || warn "No changes to commit for $DOCS_REPOS_JSON"
|
|
||||||
info "Generated and committed $DOCS_REPOS_JSON"
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_docs_readme() {
|
|
||||||
info "Generating $DOCS_README..."
|
|
||||||
mkdir -p "$DOCS_DIR"
|
|
||||||
if [ "$PRESERVE_META" = "true" ] && [ -f "$DOCS_README" ]; then
|
|
||||||
info "Preserving existing $DOCS_README (--preserve-meta enabled)"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
cat > "$DOCS_README" <<EOF
|
|
||||||
# GitField /docs Directory
|
|
||||||
|
|
||||||
The `/docs` directory hosts a public-facing, SEO-optimized canonical declaration for the \`$REPO_NAME\` repository, designed for GitHub Pages compatibility and enhanced discoverability.
|
|
||||||
|
|
||||||
## Files
|
|
||||||
|
|
||||||
- **index.html**: The canonical declaration page, including JSON-LD metadata and links to all mirrors.
|
|
||||||
- **style.css**: Minimal stylesheet for elegant, recursive branding.
|
|
||||||
- **repos.json**: Machine-readable list of the canonical URL and all mirror repositories.
|
|
||||||
- **README.md**: This file, explaining the purpose of the `/docs` directory.
|
|
||||||
- **.nojekyll**: Bypasses Jekyll processing for GitHub Pages.
|
|
||||||
- **robots.txt**: Allows full indexing by search engine bots.
|
|
||||||
- **sitemap.xml**: Auto-generated sitemap for improved SEO.
|
|
||||||
|
|
||||||
## Purpose
|
|
||||||
|
|
||||||
This directory ensures the \`$REPO_NAME\` project is discoverable via search engines and accessible to humans and bots. It declares the canonical repository at [$CANONICAL_URL]($CANONICAL_URL) and links to all mirrors, reinforcing the GitField recursive metadata strategy for sovereign publishing.
|
|
||||||
|
|
||||||
Generated by \`gitfield-sync\` at $TIMESTAMP (v$SCRIPT_VERSION).
|
|
||||||
EOF
|
|
||||||
git -C "$REPO_PATH" add "$DOCS_README"
|
|
||||||
git -C "$REPO_PATH" commit -m "Generated docs/README.md at $TIMESTAMP" || warn "No changes to commit for $DOCS_README"
|
|
||||||
info "Generated and committed $DOCS_README"
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_docs_nojekyll() {
|
|
||||||
info "Generating $DOCS_NOJEKYLL..."
|
|
||||||
mkdir -p "$DOCS_DIR"
|
|
||||||
if [ "$PRESERVE_META" = "true" ] && [ -f "$DOCS_NOJEKYLL" ]; then
|
|
||||||
info "Preserving existing $DOCS_NOJEKYLL (--preserve-meta enabled)"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
touch "$DOCS_NOJEKYLL"
|
|
||||||
git -C "$REPO_PATH" add "$DOCS_NOJEKYLL"
|
|
||||||
git -C "$REPO_PATH" commit -m "Generated docs/.nojekyll at $TIMESTAMP" || warn "No changes to commit for $DOCS_NOJEKYLL"
|
|
||||||
info "Generated and committed $DOCS_NOJEKYLL"
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_docs_robots() {
|
|
||||||
info "Generating $DOCS_ROBOTS..."
|
|
||||||
mkdir -p "$DOCS_DIR"
|
|
||||||
if [ "$PRESERVE_META" = "true" ] && [ -f "$DOCS_ROBOTS" ]; then
|
|
||||||
info "Preserving existing $DOCS_ROBOTS (--preserve-meta enabled)"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
cat > "$DOCS_ROBOTS" <<EOF
|
|
||||||
User-agent: *
|
|
||||||
Allow: /
|
|
||||||
Sitemap: /sitemap.xml
|
|
||||||
EOF
|
|
||||||
git -C "$REPO_PATH" add "$DOCS_ROBOTS"
|
|
||||||
git -C "$REPO_PATH" commit -m "Generated docs/robots.txt at $TIMESTAMP" || warn "No changes to commit for $DOCS_ROBOTS"
|
|
||||||
info "Generated and committed $DOCS_ROBOTS"
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_docs_sitemap() {
|
|
||||||
info "Generating $DOCS_SITEMAP..."
|
|
||||||
mkdir -p "$DOCS_DIR"
|
|
||||||
if [ "$PRESERVE_META" = "true" ] && [ -f "$DOCS_SITEMAP" ]; then
|
|
||||||
info "Preserving existing $DOCS_SITEMAP (--preserve-meta enabled)"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
cat > "$DOCS_SITEMAP" <<EOF
|
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
||||||
<url>
|
|
||||||
<loc>$CANONICAL_URL</loc>
|
|
||||||
<lastmod>$TIMESTAMP</lastmod>
|
|
||||||
<changefreq>weekly</changefreq>
|
|
||||||
<priority>1.0</priority>
|
|
||||||
</url>
|
|
||||||
$(for mirror in "${MIRRORS[@]}"; do
|
|
||||||
if [[ "$mirror" != rad:* ]]; then
|
|
||||||
echo " <url>"
|
|
||||||
echo " <loc>$mirror</loc>"
|
|
||||||
echo " <lastmod>$TIMESTAMP</lastmod>"
|
|
||||||
echo " <changefreq>weekly</changefreq>"
|
|
||||||
echo " <priority>0.8</priority>"
|
|
||||||
echo " </url>"
|
|
||||||
fi
|
|
||||||
done)
|
|
||||||
</urlset>
|
|
||||||
EOF
|
|
||||||
git -C "$REPO_PATH" add "$DOCS_SITEMAP"
|
|
||||||
git -C "$REPO_PATH" commit -m "Generated docs/sitemap.xml at $TIMESTAMP" || warn "No changes to commit for $DOCS_SITEMAP"
|
|
||||||
info "Generated and committed $DOCS_SITEMAP"
|
|
||||||
}
|
|
||||||
|
|
||||||
# ╭─────────────────────────────────────╮
|
|
||||||
# │ INITIAL SETUP │
|
|
||||||
# ╰─────────────────────────────────────╮
|
|
||||||
mkdir -p "$GITFIELD_DIR" "$WELL_KNOWN_DIR" "$DOCS_DIR"
|
|
||||||
|
|
||||||
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 seven distinct platforms: **GitHub**, **GitLab**, **Bitbucket**, **Radicle**, **Forgejo**, **Codeberg**, and **Gitea**. 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 and delisting 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)), **Dr. Peter Gaied** ([Paragraph post](https://paragraph.com/@neutralizingnarcissism/%F0%9F%9C%81-the-narcissistic-messiah)), and **Andrew LeCody** ([Mirror post](https://mirror.xyz/neutralizingnarcissism.eth/s3GRxuiZs6vGSGDcPEpCgjaSxwGAViGhmg6a5XTL6s0)), 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)). Specifically, Andrew LeCody has attempted to delist the project's content on Google, though it remains accessible on other search engines such as [Bing](https://www.bing.com/search?q=andrew+lecody+neutralizing+narcissism&qs=HS&pq=andrew+lecody), [DuckDuckGo](https://duckduckgo.com/?t=h_&q=andrew+lecody+neutralizing+narcissism&ia=web), and [Yahoo](https://search.yahoo.com/search?p=andrew+lecody+neutralizng+narcissism). By distributing the repository across multiple platforms, including a self-hosted Forgejo instance, we ensure its persistence, accessibility, and sovereignty.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📍 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
|
|
||||||
- **RID**: [$RADICLE_RID](https://app.radicle.xyz/nodes/$RADICLE_RID)
|
|
||||||
- **Peer ID**: $RADICLE_PEER_ID
|
|
||||||
- **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.
|
|
||||||
- **Access Details**: To view project details, run:
|
|
||||||
\`\`\`bash
|
|
||||||
rad inspect $RADICLE_RID
|
|
||||||
\`\`\`
|
|
||||||
To view the file structure, run:
|
|
||||||
\`\`\`bash
|
|
||||||
rad ls $RADICLE_RID
|
|
||||||
\`\`\`
|
|
||||||
Alternatively, use Git to list files at the current HEAD:
|
|
||||||
\`\`\`bash
|
|
||||||
git ls-tree -r --name-only HEAD
|
|
||||||
\`\`\`
|
|
||||||
|
|
||||||
### 2. Forgejo
|
|
||||||
- **URL**: [$FORGEJO_URL]($FORGEJO_URL)
|
|
||||||
- **Purpose**: Forgejo is a self-hosted, open-source git platform running on \`remember.thefoldwithin.earth\`. It provides full control over the repository, ensuring sovereignty and independence from third-party providers.
|
|
||||||
- **Value**: Enhances resilience by hosting the repository on a sovereign, redundant system with automated backups and deployment strategies, reducing risks of external interference or service disruptions.
|
|
||||||
- **Access Details**: SSH access uses port 222:
|
|
||||||
\`\`\`bash
|
|
||||||
ssh -T -p 222 git@remember.thefoldwithin.earth
|
|
||||||
\`\`\`
|
|
||||||
|
|
||||||
### 3. Codeberg
|
|
||||||
- **URL**: [$CODEBERG_URL]($CODEBERG_URL)
|
|
||||||
- **Purpose**: Codeberg is a community-driven, open-source platform powered by Forgejo, offering a reliable and ethical alternative for hosting git repositories.
|
|
||||||
- **Value**: Enhances project resilience with its open-source ethos and independent infrastructure, ensuring accessibility and community support.
|
|
||||||
|
|
||||||
### 4. Gitea
|
|
||||||
- **URL**: [$GITEA_URL]($GITEA_URL)
|
|
||||||
- **Purpose**: Gitea.com provides a lightweight, open-source git hosting platform with robust features for repository management and collaboration.
|
|
||||||
- **Value**: Offers an additional layer of redundancy and a user-friendly interface, complementing other platforms with its simplicity and efficiency.
|
|
||||||
|
|
||||||
### 5. 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.
|
|
||||||
|
|
||||||
### 6. 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.
|
|
||||||
|
|
||||||
### 7. 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 **search engine delistings** and ensure its **long-term availability**. Past incidents involving **Mr. Joel Johnson**, **Dr. Peter Gaied**, and **Andrew LeCody** have highlighted the vulnerability of relying on a single platform or search engine. By distributing the repository across GitHub, GitLab, Bitbucket, Radicle, Forgejo, Codeberg, and Gitea, we achieve:
|
|
||||||
|
|
||||||
- **Resilience**: If one platform removes or restricts access, or if search engines like Google delist content, the project remains accessible on other platforms and discoverable via alternative search engines such as Bing, DuckDuckGo, and Yahoo.
|
|
||||||
- **Sovereignty**: Radicle’s decentralized nature and Forgejo’s self-hosted infrastructure ensure 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, Forgejo’s self-hosting, Codeberg’s community-driven model, Gitea’s lightweight efficiency) enhance the project’s functionality and reach.
|
|
||||||
- **Transparency**: Metadata snapshots in the \`.gitfield\` directory and public-facing documentation in the \`/docs\` directory provide a verifiable record of the project’s state across all platforms.
|
|
||||||
|
|
||||||
This multi-repository approach, bolstered by Forgejo’s sovereign hosting and GitHub Pages’ discoverability, reflects a commitment to preserving the integrity, accessibility, and independence of \`$REPO_NAME\`, ensuring it remains available to contributors and users regardless of external pressures.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📜 Metadata and Logs
|
|
||||||
|
|
||||||
- **Canonical Metadata**: The canonical repository is declared in [\`.gitfield/canonical.meta\`](./.gitfield/canonical.meta) (machine-readable JSON) and [\`.gitfield/canonical.md\`](./.gitfield/canonical.md) (human-readable Markdown).
|
|
||||||
- **Index Manifest**: A full manifest of remotes, commit details, and sync cycles is available in [\`.gitfield/index.json\`](./.gitfield/index.json).
|
|
||||||
- **Well-Known Metadata**: SEO-friendly metadata with Schema.org JSON-LD is available in [\`.well-known/gitfield.json\`](./.well-known/gitfield.json).
|
|
||||||
- **Push Log**: The \`.gitfield/pushed.log\` file records the date, time, commit hash, and RID/URL of every push operation across all platforms, providing a transparent audit trail.
|
|
||||||
- **GitField Directory**: The \`.gitfield\` directory contains additional metadata and platform-specific sigils (e.g., \`github.sigil.md\`). See [\`.gitfield/README.txt\`](./.gitfield/README.txt) for details.
|
|
||||||
- **GitHub Pages**: A public-facing, SEO-optimized canonical declaration is available in [\`docs/index.html\`](./docs/index.html), with additional metadata in [\`docs/repos.json\`](./docs/repos.json) and a sitemap in [\`docs/sitemap.xml\`](./docs/sitemap.xml).
|
|
||||||
- **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 → Forgejo → Codeberg → Gitea → GitLab → Bitbucket → GitHub**. This prioritizes Radicle’s decentralized, censorship-resistant network as the primary anchor, followed by Forgejo’s sovereign, self-hosted infrastructure, Codeberg’s community-driven platform, Gitea’s lightweight efficiency, 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
|
|
||||||
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 rid=$3
|
|
||||||
local peer_id=$4
|
|
||||||
local timestamp=$(date -u '+%Y-%m-%dT%H:%M:%SZ')
|
|
||||||
local branch=$(git -C "$REPO_PATH" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
|
|
||||||
local diff_summary=$(git -C "$REPO_PATH" diff --stat HEAD^ HEAD 2>/dev/null || echo "No diff available")
|
|
||||||
if [ "$platform" = "Radicle" ]; then
|
|
||||||
echo "[$timestamp] $platform: RID=$rid, Peer ID=$peer_id, Branch=$branch, Commit=$COMMIT_HASH" >> "$LOG_FILE"
|
|
||||||
echo " CLI: rad inspect $rid # View project details" >> "$LOG_FILE"
|
|
||||||
echo " CLI: git ls-tree -r --name-only HEAD # View file structure" >> "$LOG_FILE"
|
|
||||||
if [ -n "$diff_summary" ]; then
|
|
||||||
echo " Diff Summary:" >> "$LOG_FILE"
|
|
||||||
echo "$diff_summary" | sed 's/^/ /' >> "$LOG_FILE"
|
|
||||||
fi
|
|
||||||
info "Logged push to $LOG_FILE: [$timestamp] $platform: RID=$rid, Peer ID=$peer_id, Branch=$branch, Commit=$COMMIT_HASH"
|
|
||||||
else
|
|
||||||
echo "[$timestamp] $platform: $url, Branch=$branch, Commit=$COMMIT_HASH" >> "$LOG_FILE"
|
|
||||||
if [ -n "$diff_summary" ]; then
|
|
||||||
echo " Diff Summary:" >> "$LOG_FILE"
|
|
||||||
echo "$diff_summary" | sed 's/^/ /' >> "$LOG_FILE"
|
|
||||||
fi
|
|
||||||
info "Logged push to $LOG_FILE: [$timestamp] $platform: $url, Branch=$branch, Commit=$COMMIT_HASH"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# ╭─────────────────────────────────────╮
|
|
||||||
# │ EXECUTE PUSH SCRIPT │
|
|
||||||
# ╰─────────────────────────────────────╮
|
|
||||||
execute_push() {
|
|
||||||
local script_name=$1
|
|
||||||
local platform=$2
|
|
||||||
local url=$3
|
|
||||||
local rid=$4
|
|
||||||
local peer_id=$5
|
|
||||||
local script_path
|
|
||||||
script_path=$(find_script "$script_name") || error "Failed to find $script_name"
|
|
||||||
info "Executing $platform push with script: $script_path"
|
|
||||||
if [ -x "$script_path" ]; then
|
|
||||||
pushd "$REPO_PATH" >/dev/null
|
|
||||||
"$script_path" || warn "Execution of $script_path failed, continuing..."
|
|
||||||
log_url "$platform" "$url" "$rid" "$peer_id"
|
|
||||||
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..."
|
|
||||||
SYNC_CYCLES=$cycle_number
|
|
||||||
|
|
||||||
execute_push "gitfield-local" "Local" "" "" ""
|
|
||||||
execute_push "gitfield-radicle" "Radicle" "" "$RADICLE_RID" "$RADICLE_PEER_ID"
|
|
||||||
execute_push "gitfield-remember" "Forgejo" "$FORGEJO_URL" "" ""
|
|
||||||
execute_push "gitfield-codeberg" "Codeberg" "$CODEBERG_URL" "" ""
|
|
||||||
execute_push "gitfield-gitea" "Gitea" "$GITEA_URL" "" ""
|
|
||||||
execute_push "gitfield-gitlab" "GitLab" "$GITLAB_URL" "" ""
|
|
||||||
execute_push "gitfield-bitbucket" "Bitbucket" "$BITBUCKET_URL" "" ""
|
|
||||||
execute_push "gitfield-github" "GitHub" "$GITHUB_URL" "" ""
|
|
||||||
|
|
||||||
# Regenerate metadata after each cycle to update sync_cycles
|
|
||||||
generate_canonical_meta
|
|
||||||
generate_canonical_md
|
|
||||||
generate_index_json
|
|
||||||
generate_well_known_json
|
|
||||||
generate_gitfield_readme
|
|
||||||
generate_docs_index
|
|
||||||
generate_docs_css
|
|
||||||
generate_docs_repos_json
|
|
||||||
generate_docs_readme
|
|
||||||
generate_docs_nojekyll
|
|
||||||
generate_docs_robots
|
|
||||||
generate_docs_sitemap
|
|
||||||
}
|
|
||||||
|
|
||||||
# ╭─────────────────────────────────────╮
|
|
||||||
# │ MAIN EXECUTION │
|
|
||||||
# ╰─────────────────────────────────────╮
|
|
||||||
info "Starting gitfield-sync for $REPO_NAME..."
|
|
||||||
|
|
||||||
# Parse --preserve-meta flag
|
|
||||||
while [ $# -gt 0 ]; do
|
|
||||||
case "$1" in
|
|
||||||
--preserve-meta)
|
|
||||||
PRESERVE_META=true
|
|
||||||
info "Preserve metadata flag enabled"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
warn "Unknown argument: $1"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
# Generate initial metadata
|
|
||||||
generate_canonical_meta
|
|
||||||
generate_canonical_md
|
|
||||||
generate_index_json
|
|
||||||
generate_well_known_json
|
|
||||||
generate_gitfield_readme
|
|
||||||
generate_docs_index
|
|
||||||
generate_docs_css
|
|
||||||
generate_docs_repos_json
|
|
||||||
generate_docs_readme
|
|
||||||
generate_docs_nojekyll
|
|
||||||
generate_docs_robots
|
|
||||||
generate_docs_sitemap
|
|
||||||
|
|
||||||
# Run push cycles
|
|
||||||
run_push_cycle 1
|
|
||||||
generate_gitfield_md
|
|
||||||
run_push_cycle 2
|
|
||||||
run_push_cycle 3
|
|
||||||
|
|
||||||
info "✅ gitfield-sync completed successfully."
|
|
||||||
info "🔗 View logs: $LOG_FILE"
|
|
||||||
info "🔗 View multi-repo manifest: $GITFIELD_MD"
|
|
||||||
info "🔗 View canonical metadata: $CANONICAL_META"
|
|
||||||
info "🔗 View canonical declaration: $CANONICAL_MD"
|
|
||||||
info "🔗 View index manifest: $INDEX_JSON"
|
|
||||||
info "🔗 View well-known metadata: $WELL_KNOWN_JSON"
|
|
||||||
info "🔗 View GitHub Pages: $DOCS_INDEX"
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue