Skip to content

Commit

Permalink
git-sync allowing sha1
Browse files Browse the repository at this point in the history
  • Loading branch information
bei-re committed Feb 17, 2022
0 parents commit 55110aa
Show file tree
Hide file tree
Showing 5 changed files with 244 additions and 0 deletions.
12 changes: 12 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM alpine

LABEL "repository"="http://github.com/wei/git-sync"
LABEL "homepage"="http://github.com/wei/git-sync"
LABEL "maintainer"="Wei He <github@weispot.com>"

RUN apk add --no-cache git openssh-client && \
echo "StrictHostKeyChecking no" >> /etc/ssh/ssh_config

ADD *.sh /

ENTRYPOINT ["/entrypoint.sh"]
113 changes: 113 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# Git Sync

A GitHub Action for syncing between two independent repositories using **force push**.

## Features

- Sync branches between two GitHub repositories
- Sync branches to/from a remote repository
- GitHub action can be triggered on a timer or on push
- To sync with current repository, please checkout [Github Repo Sync](https://github.com/marketplace/actions/github-repo-sync)

## Usage

> Always make a full backup of your repo (`git clone --mirror`) before using this action.
### GitHub Actions

```yml
# .github/workflows/git-sync.yml

on: push
jobs:
git-sync:
runs-on: ubuntu-latest
steps:
- name: git-sync
uses: wei/git-sync@v3
with:
source_repo: "source_org/repository"
source_branch: "main"
destination_repo: "destination_org/repository"
destination_branch: "main"
ssh_private_key: ${{ secrets.SSH_PRIVATE_KEY }} # optional
source_ssh_private_key: ${{ secrets.SOURCE_SSH_PRIVATE_KEY }} # optional, will override `SSH_PRIVATE_KEY`
destination_ssh_private_key: ${{ secrets.DESTINATION_SSH_PRIVATE_KEY }} # optional, will override `SSH_PRIVATE_KEY`
```
##### Using shorthand
You can use GitHub repo shorthand like `username/repository`.

##### Using ssh

> The `ssh_private_key`, or `source_ssh_private_key` and `destination_ssh_private_key` must be supplied if using ssh clone urls.

```yml
source_repo: "git@github.com:username/repository.git"
```
or
```yml
source_repo: "git@gitlab.com:username/repository.git"
```

##### Using https

> The `ssh_private_key`, `source_ssh_private_key` and `destination_ssh_private_key` can be omitted if using authenticated https urls.

```yml
source_repo: "https://username:personal_access_token@github.com/username/repository.git"
```

#### Set up deploy keys

> You only need to set up deploy keys if repository is private and ssh clone url is used.

- Either generate different ssh keys for both source and destination repositories or use the same one for both, leave passphrase empty (note that GitHub deploy keys must be unique for each repository)

```sh
$ ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
```

- In GitHub, either:

- add the unique public keys (`key_name.pub`) to _Repo Settings > Deploy keys_ for each repository respectively and allow write access for the destination repository

or

- add the single public key (`key_name.pub`) to _Personal Settings > SSH keys_

- Add the private key(s) to _Repo > Settings > Secrets_ for the repository containing the action (`SSH_PRIVATE_KEY`, or `SOURCE_SSH_PRIVATE_KEY` and `DESTINATION_SSH_PRIVATE_KEY`)

#### Advanced: Sync all branches

To Sync all branches from source to destination, use `source_branch: "refs/remotes/source/*"` and `destination_branch: "refs/heads/*"`. But be careful, branches with the same name including `master` will be overwritten.

```yml
source_branch: "refs/remotes/source/*"
destination_branch: "refs/heads/*"
```

#### Advanced: Sync all tags

To Sync all tags from source to destination, use `source_branch: "refs/tags/*"` and `destination_branch: "refs/tags/*"`. But be careful, tags with the same name will be overwritten.

```yml
source_branch: "refs/tags/*"
destination_branch: "refs/tags/*"
```

### Docker

```sh
$ docker run --rm -e "SSH_PRIVATE_KEY=$(cat ~/.ssh/id_rsa)" $(docker build -q .) \
$SOURCE_REPO $SOURCE_BRANCH $DESTINATION_REPO $DESTINATION_BRANCH
```

## Author

[Wei He](https://github.com/wei) _github@weispot.com_

## License

[MIT](https://wei.mit-license.org)
40 changes: 40 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Git Sync Action (allow sha1)
author: BEI.RE
description: 🔃 Sync between two independent repositories
branding:
icon: 'git-branch'
color: 'gray-dark'
inputs:
source_repo:
description: GitHub repo slug or full url
required: true
source_branch:
description: Branch name to sync from
required: true
destination_repo:
description: GitHub repo slug or full url
required: true
destination_branch:
description: Branch name to sync to
required: true
ssh_private_key:
description: SSH key used to authenticate with source and destination ssh urls provided (optional if public or https url with authentication)
required: false
source_ssh_private_key:
description: SSH key used to authenticate with source ssh url provided (optional if public or https url with authentication)
required: false
destination_ssh_private_key:
description: SSH key used to authenticate with destination ssh url provided (optional if public or https url with authentication)
required: false
runs:
using: 'docker'
image: 'Dockerfile'
env:
SSH_PRIVATE_KEY: ${{ inputs.ssh_private_key }}
SOURCE_SSH_PRIVATE_KEY: ${{ inputs.source_ssh_private_key }}
DESTINATION_SSH_PRIVATE_KEY: ${{ inputs.destination_ssh_private_key }}
args:
- ${{ inputs.source_repo }}
- ${{ inputs.source_branch }}
- ${{ inputs.destination_repo }}
- ${{ inputs.destination_branch }}
26 changes: 26 additions & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/sh

set -e

if [[ -n "$SSH_PRIVATE_KEY" ]]; then
mkdir -p /root/.ssh
echo "$SSH_PRIVATE_KEY" | sed 's/\\n/\n/g' >/root/.ssh/id_rsa
chmod 600 /root/.ssh/id_rsa
fi

if [[ -n "$SOURCE_SSH_PRIVATE_KEY" ]]; then
mkdir -p /root/.ssh
echo "$SOURCE_SSH_PRIVATE_KEY" | sed 's/\\n/\n/g' >/root/.ssh/src_rsa
chmod 600 /root/.ssh/src_rsa
fi

if [[ -n "$DESTINATION_SSH_PRIVATE_KEY" ]]; then
mkdir -p /root/.ssh
echo "$DESTINATION_SSH_PRIVATE_KEY" | sed 's/\\n/\n/g' >/root/.ssh/dst_rsa
chmod 600 /root/.ssh/dst_rsa
fi

mkdir -p ~/.ssh
cp /root/.ssh/* ~/.ssh/ 2>/dev/null || true

sh -c "/git-sync.sh $*"
53 changes: 53 additions & 0 deletions git-sync.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/bin/sh

set -e

SOURCE_REPO=$1
SOURCE_BRANCH=$2
DESTINATION_REPO=$3
DESTINATION_BRANCH=$4

if ! echo $SOURCE_REPO | grep -Eq ':|@|\.git\/?$'; then
if [[ -n "$SSH_PRIVATE_KEY" || -n "$SOURCE_SSH_PRIVATE_KEY" ]]; then
SOURCE_REPO="git@github.com:${SOURCE_REPO}.git"
GIT_SSH_COMMAND="ssh -v"
else
SOURCE_REPO="https://github.com/${SOURCE_REPO}.git"
fi
fi

if ! echo $DESTINATION_REPO | grep -Eq ':|@|\.git\/?$'; then
if [[ -n "$SSH_PRIVATE_KEY" || -n "$DESTINATION_SSH_PRIVATE_KEY" ]]; then
DESTINATION_REPO="git@github.com:${DESTINATION_REPO}.git"
GIT_SSH_COMMAND="ssh -v"
else
DESTINATION_REPO="https://github.com/${DESTINATION_REPO}.git"
fi
fi

echo "SOURCE=$SOURCE_REPO:$SOURCE_BRANCH"
echo "DESTINATION=$DESTINATION_REPO:$DESTINATION_BRANCH"

if [[ -n "$SOURCE_SSH_PRIVATE_KEY" ]]; then
# Clone using source ssh key if provided
git clone -c core.sshCommand="/usr/bin/ssh -i ~/.ssh/src_rsa" "$SOURCE_REPO" /root/source --origin source && cd /root/source
else
git clone "$SOURCE_REPO" /root/source --origin source && cd /root/source
fi

git remote add destination "$DESTINATION_REPO"

# Pull all branches references down locally so subsequent commands can see them
git fetch source '+refs/heads/*:refs/heads/*' --update-head-ok

# Print out all branches
git --no-pager branch -a -vv

if [[ -n "$DESTINATION_SSH_PRIVATE_KEY" ]]; then
# Push using destination ssh key if provided
git config --local core.sshCommand "/usr/bin/ssh -o HostkeyAlgorithms=+ssh-rsa -o PubkeyAcceptedAlgorithms=+ssh-rsa -i ~/.ssh/dst_rsa"
else
git config --local core.sshCommand "/usr/bin/ssh -o HostkeyAlgorithms=+ssh-rsa -o PubkeyAcceptedAlgorithms=+ssh-rsa"
fi

git push destination "${SOURCE_BRANCH}:${DESTINATION_BRANCH}" -f

0 comments on commit 55110aa

Please sign in to comment.