mirror-radicle.yml
1 name: Mirror to Radicle 2 # Mirrors every push to main → Radicle seed.radicle.garden 3 4 on: 5 push: 6 branches: [main] 7 8 jobs: 9 mirror: 10 runs-on: ubuntu-latest 11 env: 12 RAD_PASSPHRASE: "" 13 14 steps: 15 - uses: actions/checkout@v4 16 with: 17 fetch-depth: 0 18 19 - name: Install rad CLI 20 # To upgrade: update RAD_VERSION + RAD_SHA256 from https://files.radicle.xyz/releases/ 21 env: 22 RAD_VERSION: 1.7.1 23 RAD_SHA256: 37980a3b7660704007c3fa100bb6aa452ffb3cd13426fbf0f4f824f8f49bca95 24 run: | 25 curl -fsSL "https://files.radicle.xyz/releases/${RAD_VERSION}/radicle-${RAD_VERSION}-x86_64-unknown-linux-musl.tar.xz" \ 26 -o radicle.tar.xz 27 echo "${RAD_SHA256} radicle.tar.xz" | sha256sum -c 28 tar -xJf radicle.tar.xz 29 sudo mv radicle-*/bin/rad /usr/local/bin/rad 30 sudo mv radicle-*/bin/radicle-node /usr/local/bin/radicle-node 31 sudo mv radicle-*/bin/git-remote-rad /usr/local/bin/git-remote-rad 32 rad --version 33 34 - name: Set up Radicle identity 35 env: 36 RAD_KEYGEN_SEED: ${{ secrets.RAD_KEYGEN_SEED }} 37 run: | 38 rad auth --alias github-ci 39 40 - name: Push to Radicle seed 41 env: 42 RAD_RID: ${{ secrets.RAD_RID }} 43 RAD_COB_BUNDLE: ${{ secrets.RAD_COB_BUNDLE }} 44 run: | 45 trap 'kill $NODE_PID 2>/dev/null || true' EXIT 46 47 # RAD_RID may include "rad:" prefix; storage dirs use just the hash 48 RID="${RAD_RID#rad:}" 49 50 # Restore COB bundle into local storage. 51 # git bundle unbundle drops refs/namespaces/* silently; use git fetch instead. 52 mkdir -p "${HOME}/.radicle/storage/${RID}" 53 git -C "${HOME}/.radicle/storage/${RID}" init --bare --quiet 54 55 # Seed storage with git objects first — the COB bundle uses the current HEAD 56 # as a prerequisite for refs/heads/main (so no history objects in the bundle), 57 # but git fetch will reject the bundle unless those objects already exist here. 58 git -C "${HOME}/.radicle/storage/${RID}" fetch "${GITHUB_WORKSPACE}" \ 59 "+refs/heads/main:refs/tmp/bootstrap" 60 git -C "${HOME}/.radicle/storage/${RID}" update-ref -d refs/tmp/bootstrap 2>/dev/null || true 61 62 # Restore COB bundle — includes k7's refs/namespaces/.../refs/heads/main 63 # (with prerequisite satisfied by the checkout objects above) 64 echo "${RAD_COB_BUNDLE}" | base64 -d > /tmp/cob.bundle 65 git -C "${HOME}/.radicle/storage/${RID}" fetch /tmp/cob.bundle \ 66 "+refs/namespaces/*:refs/namespaces/*" \ 67 "+refs/rad/*:refs/rad/*" || exit 1 68 rm /tmp/cob.bundle 69 70 echo "=== Profile check ===" 71 CI_NID=$(rad self --nid 2>/dev/null) 72 echo "CI NID: ${CI_NID}" 73 74 echo "=== Radicle home ===" 75 ls -la "${HOME}/.radicle/" 2>&1 || true 76 ls -la "${HOME}/.radicle/keys/" 2>&1 || true 77 78 echo "=== git-remote-rad ===" 79 which git-remote-rad 2>&1 || true 80 ls -la "$(which git-remote-rad 2>/dev/null)" 2>&1 || true 81 82 git config --global user.name "github-ci" 83 git config --global user.email "ci@harvest316.github.com" 84 85 git remote add rad "rad://${RID}" 2>/dev/null || \ 86 git remote set-url rad "rad://${RID}" 87 git remote set-url --push rad "rad://${RID}/${CI_NID}" 88 89 # seed.radicle.garden = iris.radicle.xyz (NID from https://seed.radicle.garden/api/v1/node) 90 SEED_NID="z6MkrLMMsiPWUcNPHcRajuMi9mDfYckSoJyPwwnknocNYPm7" 91 git config rad.seed seed.radicle.garden 92 93 radicle-node --listen 0.0.0.0:8776 & 94 NODE_PID=$! 95 96 # Wait for node to bind its port (up to 10s) 97 for i in $(seq 1 20); do 98 nc -z 0.0.0.0 8776 2>/dev/null && break 99 sleep 0.5 100 done 101 nc -z 0.0.0.0 8776 2>/dev/null || { echo "radicle-node failed to start"; exit 1; } 102 103 # Give bootstrap peers time to connect (iris must be in routing table for announce) 104 sleep 5 105 106 echo "=== Node state ===" 107 rad node status 2>&1 || true 108 rad ls 2>&1 || true 109 110 # Seed the repo to register it with the node (allows git-remote-rad to push) 111 rad seed "rad:${RID}" 2>&1 || true 112 113 echo "=== Node socket ===" 114 ls -la "${HOME}/.radicle/node/" 2>&1 || true 115 116 echo "=== Attempting git push ===" 117 RAD_HOME="${HOME}/.radicle" GIT_TRACE2_EVENT=/tmp/git-trace.json \ 118 git push rad main --force 2>&1 || { 119 echo "=== git push failed, trace tail ===" 120 tail -20 /tmp/git-trace.json 2>/dev/null || true 121 exit 1 122 } 123 124 # Announce to iris — CI runner has a public IP so iris can inbound-fetch 125 rad sync --announce --seed "${SEED_NID}"