Post-Local sync at 2025-06-09T20:30:45Z
This commit is contained in:
parent
45c3fa9c4d
commit
f8a6d28311
4 changed files with 513 additions and 9 deletions
|
@ -8,12 +8,19 @@ IFS=$'\n\t'
|
|||
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"
|
||||
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
SCRIPT_VERSION="1.0"
|
||||
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"
|
||||
|
@ -23,6 +30,20 @@ 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 │
|
||||
# ╰─────────────────────────────────────╮
|
||||
|
@ -62,10 +83,176 @@ find_script() {
|
|||
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"
|
||||
|
@ -160,8 +347,11 @@ This multi-repository approach, bolstered by Forgejo’s sovereign hosting, refl
|
|||
|
||||
## 📜 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.
|
||||
- **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.
|
||||
|
||||
|
@ -183,15 +373,25 @@ log_url() {
|
|||
local url=$2
|
||||
local rid=$3
|
||||
local peer_id=$4
|
||||
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
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" >> "$LOG_FILE"
|
||||
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"
|
||||
info "Logged push to $LOG_FILE: [$timestamp] $platform: RID=$rid, Peer ID=$peer_id"
|
||||
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" >> "$LOG_FILE"
|
||||
info "Logged push to $LOG_FILE: [$timestamp] $platform: $url"
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -225,6 +425,7 @@ execute_push() {
|
|||
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"
|
||||
|
@ -234,6 +435,13 @@ run_push_cycle() {
|
|||
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
|
||||
}
|
||||
|
||||
# ╭─────────────────────────────────────╮
|
||||
|
@ -241,6 +449,21 @@ run_push_cycle() {
|
|||
# ╰─────────────────────────────────────╮
|
||||
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
|
||||
|
@ -249,6 +472,14 @@ if [ ! -d "$REPO_PATH/.git" ]; then
|
|||
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
|
||||
|
@ -257,3 +488,7 @@ 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"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue