Skip to content

Commit 55c6b63

Browse files
homerjamwei
andauthored
feat: add support for source/destination ssh keys (wei#22)
* add support for source/destination ssh keys * update readme * revert to SSH_PRIVATE_KEY by default * release: bump to v3 Co-authored-by: Wei He <[email protected]>
1 parent c81b9ea commit 55c6b63

File tree

4 files changed

+102
-38
lines changed

4 files changed

+102
-38
lines changed

README.md

+58-21
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,93 @@
11
# Git Sync
22

3-
A GitHub Action for syncing between two independent repositories using **force push**.
4-
3+
A GitHub Action for syncing between two independent repositories using **force push**.
54

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

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

1312
## Usage
1413

15-
Always make a full backup of your repo (`git clone --mirror`) before using this action.
14+
> Always make a full backup of your repo (`git clone --mirror`) before using this action.
1615
17-
### GitHub Actions
16+
- 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)
17+
18+
```sh
19+
$ ssh-keygen -t rsa -b 4096 -C "[email protected]"
1820
```
19-
# File: .github/workflows/repo-sync.yml
21+
22+
- In GitHub, either:
23+
24+
- 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
25+
26+
or
27+
28+
- add the single public key (`key_name.pub`) to _Personal Settings > SSH keys_
29+
30+
- 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`)
31+
32+
### GitHub Actions
33+
34+
```yml
35+
# .github/workflows/repo-sync.yml
2036

2137
on: push
2238
jobs:
2339
repo-sync:
2440
runs-on: ubuntu-latest
2541
steps:
26-
- name: repo-sync
27-
uses: wei/git-sync@v2
28-
with:
29-
source_repo: ""
30-
source_branch: ""
31-
destination_repo: ""
32-
destination_branch: ""
33-
ssh_private_key: ${{ secrets.SSH_PRIVATE_KEY }}
42+
- name: repo-sync
43+
uses: wei/git-sync@v3
44+
with:
45+
source_repo: "username/repository"
46+
source_branch: "main"
47+
destination_repo: "[email protected]:org/repository.git"
48+
destination_branch: "main"
49+
ssh_private_key: ${{ secrets.SSH_PRIVATE_KEY }} # optional
50+
source_ssh_private_key: ${{ secrets.SOURCE_SSH_PRIVATE_KEY }} # optional, will override `SSH_PRIVATE_KEY`
51+
destination_ssh_private_key: ${{ secrets.DESTINATION_SSH_PRIVATE_KEY }} # optional, will override `SSH_PRIVATE_KEY`
52+
```
53+
54+
##### Alternative using https
55+
56+
The `ssh_private_key`, `source_ssh_private_key` and `destination_ssh_private_key` can be omitted if using authenticated https urls.
57+
58+
```yml
59+
source_repo: "https://username:[email protected]/username/repository.git"
3460
```
35-
`ssh_private_key` can be omitted if using authenticated HTTPS repo clone urls like `https://username:[email protected]/username/repository.git`.
3661

3762
#### Advanced: Sync all branches
3863

3964
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.
4065

66+
```yml
67+
source_branch: "refs/remotes/source/*"
68+
destination_branch: "refs/heads/*"
69+
```
70+
4171
#### Advanced: Sync all tags
4272

4373
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.
4474

45-
### Docker
75+
```yml
76+
source_branch: "refs/tags/*"
77+
destination_branch: "refs/tags/*"
4678
```
47-
docker run --rm -e "SSH_PRIVATE_KEY=$(cat ~/.ssh/id_rsa)" $(docker build -q .) \
79+
80+
### Docker
81+
82+
```sh
83+
$ docker run --rm -e "SSH_PRIVATE_KEY=$(cat ~/.ssh/id_rsa)" $(docker build -q .) \
4884
$SOURCE_REPO $SOURCE_BRANCH $DESTINATION_REPO $DESTINATION_BRANCH
4985
```
5086

5187
## Author
52-
[Wei He](https://github.com/wei) _[email protected]_
5388

89+
[Wei He](https://github.com/wei) [email protected]_
5490

5591
## License
92+
5693
[MIT](https://wei.mit-license.org)

action.yml

+12-4
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,38 @@
11
name: Git Sync Action
22
author: Wei He <[email protected]>
3-
description: 🔃 Sync between two independent repositories
3+
description: 🔃 Sync between two independent repositories
44
branding:
55
icon: 'git-branch'
66
color: 'gray-dark'
77
inputs:
88
source_repo:
9-
description: GitHub repo slug or full clone url
9+
description: GitHub repo slug or full url
1010
required: true
1111
source_branch:
1212
description: Branch name to sync from
1313
required: true
1414
destination_repo:
15-
description: GitHub repo slug or full clone url
15+
description: GitHub repo slug or full url
1616
required: true
1717
destination_branch:
1818
description: Branch name to sync to
1919
required: true
2020
ssh_private_key:
21-
description: SSH key used to authenticate with git clone urls provided (optional if public or https clone url with authentication)
21+
description: SSH key used to authenticate with source and destination ssh urls provided (optional if public or https url with authentication)
22+
required: false
23+
source_ssh_private_key:
24+
description: SSH key used to authenticate with source ssh url provided (optional if public or https url with authentication)
25+
required: false
26+
destination_ssh_private_key:
27+
description: SSH key used to authenticate with destination ssh url provided (optional if public or https url with authentication)
2228
required: false
2329
runs:
2430
using: 'docker'
2531
image: 'Dockerfile'
2632
env:
2733
SSH_PRIVATE_KEY: ${{ inputs.ssh_private_key }}
34+
SOURCE_SSH_PRIVATE_KEY: ${{ inputs.source_ssh_private_key }}
35+
DESTINATION_SSH_PRIVATE_KEY: ${{ inputs.destination_ssh_private_key }}
2836
args:
2937
- ${{ inputs.source_repo }}
3038
- ${{ inputs.source_branch }}

entrypoint.sh

+15-4
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,25 @@
22

33
set -e
44

5-
if [[ -n "$SSH_PRIVATE_KEY" ]]
6-
then
5+
if [[ -n "$SSH_PRIVATE_KEY" ]]; then
76
mkdir -p /root/.ssh
8-
echo "$SSH_PRIVATE_KEY" > /root/.ssh/id_rsa
7+
echo "$SSH_PRIVATE_KEY" | sed 's/\\n/\n/g' >/root/.ssh/id_rsa
98
chmod 600 /root/.ssh/id_rsa
109
fi
1110

11+
if [[ -n "$SOURCE_SSH_PRIVATE_KEY" ]]; then
12+
mkdir -p /root/.ssh
13+
echo "$SOURCE_SSH_PRIVATE_KEY" | sed 's/\\n/\n/g' >/root/.ssh/src_rsa
14+
chmod 600 /root/.ssh/src_rsa
15+
fi
16+
17+
if [[ -n "$DESTINATION_SSH_PRIVATE_KEY" ]]; then
18+
mkdir -p /root/.ssh
19+
echo "$DESTINATION_SSH_PRIVATE_KEY" | sed 's/\\n/\n/g' >/root/.ssh/dst_rsa
20+
chmod 600 /root/.ssh/dst_rsa
21+
fi
22+
1223
mkdir -p ~/.ssh
13-
cp /root/.ssh/* ~/.ssh/ 2> /dev/null || true
24+
cp /root/.ssh/* ~/.ssh/ 2>/dev/null || true
1425

1526
sh -c "/git-sync.sh $*"

git-sync.sh

+17-9
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,17 @@ SOURCE_BRANCH=$2
77
DESTINATION_REPO=$3
88
DESTINATION_BRANCH=$4
99

10-
if ! echo $SOURCE_REPO | grep -Eq ':|@|\.git\/?$'
11-
then
12-
if [[ -n "$SSH_PRIVATE_KEY" ]]
13-
then
10+
if ! echo $SOURCE_REPO | grep -Eq ':|@|\.git\/?$'; then
11+
if [[ -n "$SSH_PRIVATE_KEY" || -n "$SOURCE_SSH_PRIVATE_KEY" ]]; then
1412
SOURCE_REPO="[email protected]:${SOURCE_REPO}.git"
1513
GIT_SSH_COMMAND="ssh -v"
1614
else
1715
SOURCE_REPO="https://github.com/${SOURCE_REPO}.git"
1816
fi
1917
fi
20-
if ! echo $DESTINATION_REPO | grep -Eq ':|@|\.git\/?$'
21-
then
22-
if [[ -n "$SSH_PRIVATE_KEY" ]]
23-
then
18+
19+
if ! echo $DESTINATION_REPO | grep -Eq ':|@|\.git\/?$'; then
20+
if [[ -n "$SSH_PRIVATE_KEY" || -n "$DESTINATION_SSH_PRIVATE_KEY" ]]; then
2421
DESTINATION_REPO="[email protected]:${DESTINATION_REPO}.git"
2522
GIT_SSH_COMMAND="ssh -v"
2623
else
@@ -31,7 +28,13 @@ fi
3128
echo "SOURCE=$SOURCE_REPO:$SOURCE_BRANCH"
3229
echo "DESTINATION=$DESTINATION_REPO:$DESTINATION_BRANCH"
3330

34-
git clone "$SOURCE_REPO" /root/source --origin source && cd /root/source
31+
if [[ -n "$SOURCE_SSH_PRIVATE_KEY" ]]; then
32+
# Clone using source ssh key if provided
33+
git clone -c core.sshCommand="/usr/bin/ssh -i ~/.ssh/src_rsa" "$SOURCE_REPO" /root/source --origin source && cd /root/source
34+
else
35+
git clone "$SOURCE_REPO" /root/source --origin source && cd /root/source
36+
fi
37+
3538
git remote add destination "$DESTINATION_REPO"
3639

3740
# Pull all branches references down locally so subsequent commands can see them
@@ -40,4 +43,9 @@ git fetch source '+refs/heads/*:refs/heads/*' --update-head-ok
4043
# Print out all branches
4144
git --no-pager branch -a -vv
4245

46+
if [[ -n "$DESTINATION_SSH_PRIVATE_KEY" ]]; then
47+
# Push using destination ssh key if provided
48+
git config --local core.sshCommand "/usr/bin/ssh -i ~/.ssh/dst_rsa"
49+
fi
50+
4351
git push destination "${SOURCE_BRANCH}:${DESTINATION_BRANCH}" -f

0 commit comments

Comments
 (0)