~ knotless Search/
↑↓ move↵ open⇧↵ all results

grain.social/grain

photography-focused photo sharing platform

grain.social
1 collaborator
0
2
63 lines · 2.7 KB Raw History
# Mirrors main to GitHub and Tangled on every push. Knotless is the source
# of truth: nothing pushes the other way, and a mirror only ever
# fast-forwards, so a commit made on GitHub or Tangled directly makes the
# run fail rather than be overwritten.
#
# A run pushes main as knotless has it when the run starts, so a run that a
# newer push overtakes still leaves the mirrors at the newest commit. Each
# mirror is tried even when the other fails, and the run fails if either
# did.
#
# It runs on ci.knotless.dev alone, like deploy, so the keys never reach
# the hosted runner that checks pulls. Both are sealed to pushes to main
# (`knotless secret knotless://grain.social/grain set <name> --runner
# ci.knotless.dev --ref refs/heads/main`):
#
#   GITHUB_DEPLOY_KEY  a write deploy key on github.com/grainsocial/grain
#   TANGLED_SSH_KEY    a key on the grain.social account on tangled.org
#
# `knotless rerun knotless://grain.social/grain --ref refs/heads/main
# --workflow mirror` mirrors main again, which is how to repair a mirror
# after a failed run.
on:
  push: { refs: [refs/heads/main] }
  asked: { refs: [refs/heads/main] }
image: alpine:3.22
runners: [ci.knotless.dev]
secrets: [GITHUB_DEPLOY_KEY, TANGLED_SSH_KEY]
env:
  SOURCE: https://knotless.dev/grain.social/grain.git
steps:
  - name: tools
    run: apk add --no-cache git openssh-client
  - name: keys
    run: |
      mkdir -p ~/.ssh && chmod 700 ~/.ssh
      printf '%s\n' "$GITHUB_DEPLOY_KEY" > ~/.ssh/github && chmod 600 ~/.ssh/github
      printf '%s\n' "$TANGLED_SSH_KEY" > ~/.ssh/tangled && chmod 600 ~/.ssh/tangled
      printf 'Host github.com\n  IdentityFile ~/.ssh/github\n  IdentitiesOnly yes\nHost tangled.org\n  IdentityFile ~/.ssh/tangled\n  IdentitiesOnly yes\n' > ~/.ssh/config
      # Both hosts' ed25519 keys, pinned. GitHub publishes its own at
      # api.github.com/meta.
      cat > ~/.ssh/known_hosts <<'EOF'
      github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl
      tangled.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII2UShEm/FFPmYZUizaPnIqOJuynoCQpcLhl5PPHd02n
      EOF
  - name: mirror
    timeout: 10
    run: |
      # A full fetch, not the checkout: a mirror is sent the history between
      # its head and this commit, and a shallow repository cannot send it.
      git init -q --bare /mirror && cd /mirror
      git fetch -q "$SOURCE" "+refs/heads/main:refs/heads/main"
      echo "main is at $(git rev-parse refs/heads/main)"

      failed=""
      for mirror in git@github.com:grainsocial/grain.git git@tangled.org:grain.social/grain; do
        echo "==> $mirror"
        git push "$mirror" refs/heads/main:refs/heads/main || failed="$failed $mirror"
      done

      if [ -n "$failed" ]; then
        echo "not mirrored to:$failed"
        exit 1
      fi