Add FF-only Gitea to GitHub sync job #1
@ -117,6 +117,34 @@ services:
|
||||
networks:
|
||||
- n8n_default
|
||||
|
||||
git-bridge:
|
||||
container_name: git-bridge
|
||||
profiles: ["git-bridge"]
|
||||
image: ${GITEA_IMAGE:-gitea/gitea:1.23}
|
||||
restart: "no"
|
||||
user: "0:0"
|
||||
environment:
|
||||
HOME: /state/home
|
||||
HTTP_PROXY: http://192.168.0.4:7890
|
||||
HTTPS_PROXY: http://192.168.0.4:7890
|
||||
ALL_PROXY: http://192.168.0.4:7890
|
||||
NO_PROXY: localhost,127.0.0.1,::1,gitea,postgres,litellm
|
||||
entrypoint: ["/bin/sh", "/app/bin/sync-main-forward.sh"]
|
||||
volumes:
|
||||
- ./git-bridge/bin:/app/bin:ro
|
||||
- ./git-bridge/config:/app/config:ro
|
||||
- ./git-bridge/state:/state
|
||||
- ./git-bridge/secrets/gitea_token:/run/secrets/gitea_token:ro
|
||||
- ./git-bridge/secrets/github_token:/run/secrets/github_token:ro
|
||||
read_only: true
|
||||
tmpfs:
|
||||
- /tmp
|
||||
cap_drop: ["ALL"]
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
networks:
|
||||
- git_forge
|
||||
|
||||
networks:
|
||||
git_forge:
|
||||
name: git_forge
|
||||
|
||||
13
git-bridge/README.md
Normal file
13
git-bridge/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
# Git Bridge
|
||||
|
||||
Phase 1 provides a deterministic, one-shot forward sync from Gitea Main to
|
||||
GitHub Main. The job refuses divergence and never force-pushes.
|
||||
|
||||
Run after this change is merged and deployed:
|
||||
|
||||
```bash
|
||||
docker compose --profile git-bridge run --rm --no-deps git-bridge
|
||||
```
|
||||
|
||||
GitHub remains a development workspace. Production deployment continues to
|
||||
use only Gitea Main.
|
||||
8
git-bridge/bin/git-askpass.sh
Executable file
8
git-bridge/bin/git-askpass.sh
Executable file
@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
case "$1" in
|
||||
*Username*github.com*|*github.com*Username*) printf '%s\n' 'RX-Penguin' ;;
|
||||
*github.com*) cat /run/secrets/github_token ;;
|
||||
*Username*gitea*|*gitea*Username*) printf '%s\n' 'git-bridge' ;;
|
||||
*gitea*) cat /run/secrets/gitea_token ;;
|
||||
*) exit 1 ;;
|
||||
esac
|
||||
68
git-bridge/bin/sync-main-forward.sh
Executable file
68
git-bridge/bin/sync-main-forward.sh
Executable file
@ -0,0 +1,68 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
. /app/config/repositories.conf
|
||||
|
||||
state_repo=/state/infra.git
|
||||
lock_dir=/state/forward-sync.lock
|
||||
|
||||
mkdir -p /state
|
||||
mkdir -p "$HOME"
|
||||
if ! mkdir "$lock_dir" 2>/dev/null; then
|
||||
echo "forward sync is already running" >&2
|
||||
exit 75
|
||||
fi
|
||||
trap 'rmdir "$lock_dir" 2>/dev/null || true' EXIT INT TERM
|
||||
|
||||
export GIT_TERMINAL_PROMPT=0
|
||||
export GIT_ASKPASS=/app/bin/git-askpass.sh
|
||||
|
||||
if [ ! -d "$state_repo" ]; then
|
||||
git init --bare "$state_repo" >/dev/null
|
||||
fi
|
||||
|
||||
if git -C "$state_repo" remote get-url gitea >/dev/null 2>&1; then
|
||||
[ "$(git -C "$state_repo" remote get-url gitea)" = "$GITEA_REMOTE" ] || {
|
||||
echo "gitea remote mismatch" >&2
|
||||
exit 2
|
||||
}
|
||||
else
|
||||
git -C "$state_repo" remote add gitea "$GITEA_REMOTE"
|
||||
fi
|
||||
if git -C "$state_repo" remote get-url github >/dev/null 2>&1; then
|
||||
[ "$(git -C "$state_repo" remote get-url github)" = "$GITHUB_REMOTE" ] || {
|
||||
echo "github remote mismatch" >&2
|
||||
exit 2
|
||||
}
|
||||
else
|
||||
git -C "$state_repo" remote add github "$GITHUB_REMOTE"
|
||||
fi
|
||||
|
||||
git -C "$state_repo" fetch --no-tags gitea \
|
||||
"+refs/heads/$MAIN_BRANCH:refs/remotes/gitea/$MAIN_BRANCH"
|
||||
gitea_sha=$(git -C "$state_repo" rev-parse "refs/remotes/gitea/$MAIN_BRANCH")
|
||||
|
||||
if git -C "$state_repo" ls-remote --exit-code --heads github \
|
||||
"refs/heads/$MAIN_BRANCH" >/dev/null 2>&1; then
|
||||
git -C "$state_repo" fetch --no-tags github \
|
||||
"+refs/heads/$MAIN_BRANCH:refs/remotes/github/$MAIN_BRANCH"
|
||||
github_sha=$(git -C "$state_repo" rev-parse "refs/remotes/github/$MAIN_BRANCH")
|
||||
if ! git -C "$state_repo" merge-base --is-ancestor "$github_sha" "$gitea_sha"; then
|
||||
echo "sync refused: GitHub Main is not an ancestor of Gitea Main" >&2
|
||||
exit 42
|
||||
fi
|
||||
fi
|
||||
|
||||
git -C "$state_repo" push github \
|
||||
"refs/remotes/gitea/$MAIN_BRANCH:refs/heads/$MAIN_BRANCH"
|
||||
verified_sha=$(git -C "$state_repo" ls-remote github \
|
||||
"refs/heads/$MAIN_BRANCH" | awk 'NR == 1 { print $1 }')
|
||||
[ "$verified_sha" = "$gitea_sha" ] || {
|
||||
echo "sync verification failed" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
echo "forward sync completed"
|
||||
echo "branch=$MAIN_BRANCH"
|
||||
echo "commit=$gitea_sha"
|
||||
echo "force_push=false"
|
||||
3
git-bridge/config/repositories.conf
Normal file
3
git-bridge/config/repositories.conf
Normal file
@ -0,0 +1,3 @@
|
||||
GITEA_REMOTE=http://gitea:3000/slh/infra.git
|
||||
GITHUB_REMOTE=https://github.com/RX-Penguin/infra.git
|
||||
MAIN_BRANCH=main
|
||||
Loading…
x
Reference in New Issue
Block a user