├── .github └── workflows │ └── test.yml ├── Dockerfile ├── LICENSE ├── README.md ├── action.yml ├── cleanup.sh ├── mirror.sh └── setup-ssh.sh /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | on: 3 | delete: 4 | pull_request: 5 | push: 6 | branches: 7 | - main 8 | 9 | jobs: 10 | check_preconditions: 11 | runs-on: ubuntu-latest 12 | outputs: 13 | results: ${{ join(steps.*.outcome) }} 14 | steps: 15 | - id: secrets 16 | continue-on-error: true 17 | env: 18 | SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} 19 | TARGET_REPO_URL: ${{ secrets.TARGET_REPO_URL }} 20 | run: '[ -n "$SSH_PRIVATE_KEY" ] && [ -n "$TARGET_REPO_URL" ]' 21 | mirroring: 22 | needs: check_preconditions 23 | if: "!contains(needs.check_preconditions.outputs.results, 'failure')" 24 | runs-on: ubuntu-latest 25 | steps: 26 | - uses: actions/checkout@v3 27 | with: 28 | fetch-depth: 0 29 | - uses: ./ 30 | with: 31 | ssh_private_key: ${{ secrets.SSH_PRIVATE_KEY }} 32 | target_repo_url: ${{ secrets.TARGET_REPO_URL }} 33 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.10 2 | 3 | RUN apk update && apk upgrade && \ 4 | apk add --no-cache git openssh git-lfs 5 | 6 | RUN git lfs install 7 | 8 | COPY setup-ssh.sh /setup-ssh.sh 9 | COPY mirror.sh /mirror.sh 10 | COPY cleanup.sh /cleanup.sh 11 | 12 | ENTRYPOINT ["/mirror.sh"] 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 PIXTA Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # repository-mirroring-action 2 | 3 | [![Test](https://github.com/pixta-dev/repository-mirroring-action/actions/workflows/test.yml/badge.svg)](https://github.com/pixta-dev/repository-mirroring-action/actions/workflows/test.yml) 4 | 5 | A GitHub Action for mirroring a repository to another repository on GitHub, GitLab, BitBucket, AWS CodeCommit, etc. 6 | 7 | This will copy all commits, branches and tags. 8 | 9 | >⚠️ Note that the other settings will not be copied. Please check which branch is 'default branch' after the first mirroring. 10 | 11 | ## Usage 12 | 13 | Customize following example workflow (namely replace `/` with the right information) and save as `.github/workflows/main.yml` on your source repository. 14 | 15 | To find out how to create and add the `GITLAB_SSH_PRIVATE_KEY`, follow the steps below: 16 | 1. [How to generate an SSH key pair](https://docs.gitlab.com/ee/ssh/#generate-an-ssh-key-pair). Recommended encryption would be _at least_ `2048-bit RSA`. 17 | 2. Add the _public_ key to [your gitlab account](https://gitlab.com/-/profile/keys) 18 | 3. Add the _private_ key as a secret to your workflow. More information on [creating and using secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets). 19 | 20 | 21 | ```yaml 22 | name: Mirroring 23 | 24 | on: [push, delete] 25 | 26 | jobs: 27 | to_gitlab: 28 | runs-on: ubuntu-latest 29 | steps: # <-- must use actions/checkout before mirroring! 30 | - uses: actions/checkout@v3 31 | with: 32 | fetch-depth: 0 33 | - uses: pixta-dev/repository-mirroring-action@v1 34 | with: 35 | target_repo_url: 36 | git@gitlab.com:/.git 37 | ssh_private_key: # <-- use 'secrets' to pass credential information. 38 | ${{ secrets.GITLAB_SSH_PRIVATE_KEY }} 39 | 40 | to_codecommit: # <-- different jobs are executed in parallel. 41 | runs-on: ubuntu-latest 42 | steps: 43 | - uses: actions/checkout@v3 44 | with: 45 | fetch-depth: 0 46 | - uses: pixta-dev/repository-mirroring-action@v1 47 | with: 48 | target_repo_url: 49 | ssh://git-codecommit..amazonaws.com/v1/repos/ 50 | ssh_private_key: 51 | ${{ secrets.CODECOMMIT_SSH_PRIVATE_KEY }} 52 | ssh_username: # <-- (for codecommit) you need to specify ssh-key-id as ssh username. 53 | ${{ secrets.CODECOMMIT_SSH_PRIVATE_KEY_ID }} 54 | ``` 55 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: "Mirroring Repository" 2 | description: "Mirror a repository to another repository on GitHub, GitLab, BitBucket, AWS CodeCommit, etc." 3 | branding: 4 | icon: "archive" 5 | color: "blue" 6 | inputs: 7 | ssh_private_key: 8 | description: "SSH private key for ssh connection to the target repository" 9 | required: false 10 | target_repo_url: 11 | description: "Target url" 12 | required: true 13 | ssh_username: 14 | description: "Username for ssh connection" 15 | required: false 16 | default: "git" 17 | runs: 18 | using: 'docker' 19 | image: 'Dockerfile' 20 | -------------------------------------------------------------------------------- /cleanup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | set -eu 3 | 4 | git remote remove "$1" 5 | -------------------------------------------------------------------------------- /mirror.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | set -eu 3 | 4 | /setup-ssh.sh 5 | 6 | export GIT_SSH_COMMAND="ssh -v -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no -l $INPUT_SSH_USERNAME" 7 | git remote add mirror "$INPUT_TARGET_REPO_URL" 8 | git push --tags --force --prune mirror "refs/remotes/origin/*:refs/heads/*" 9 | 10 | # NOTE: Since `post` execution is not supported for local action from './' for now, we need to 11 | # run the command by hand. 12 | /cleanup.sh mirror 13 | -------------------------------------------------------------------------------- /setup-ssh.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | set -eu 3 | 4 | mkdir -p ~/.ssh 5 | echo "$INPUT_SSH_PRIVATE_KEY" > ~/.ssh/id_rsa 6 | chmod 600 ~/.ssh/id_rsa 7 | --------------------------------------------------------------------------------