├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── windows_mac_nodocker.md ├── Dockerfile ├── LICENSE ├── README.md ├── action.yml └── entrypoint.sh /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Bug report with a problem 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | > [!WARNING] 11 | > TL;DR: this repository is not maintained for any new development. I plan to 12 | > fix issues if they arise due to changes on GitHub, to minimise disruption of 13 | > existing usage. 14 | > 15 | > My circumstances changed since I started the GitHub Action in 2020. I am not 16 | > able to add functionality to it or fix issues. 17 | > 18 | > The action is 175 lines of shell script. Feel free to fork it and modify it 19 | > for your own use case. 20 | > 21 | > If you create a fork that might replace this one, I will add a note in the 22 | > documentation and the README.md. Please, open an issue and I will do it. 23 | 24 | 25 | Suggestion: read carefully the GitHub Action output. It might contain information that might help fixing the problem. If not please keep opening the bug report. 26 | 27 | The [documentation](https://github.com/cpina/push-to-another-repository-docs) 28 | might have information on what you could do to fix the problem. See the [FAQ](https://cpina.github.io/push-to-another-repository-docs/faq.html) 29 | 30 | 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/windows_mac_nodocker.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Windows/Mac/No Docker 3 | about: Questions about Windows/Mac/No Docker runners 4 | title: '' 5 | labels: Windows-Mac-NoDocker 6 | assignees: '' 7 | 8 | --- 9 | 10 | Suggestion: see the relevant FAQ entry: https://cpina.github.io/push-to-another-repository-docs/faq.html#could-it-work-on-mac-os-windows-or-no-docker-environments 11 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:latest 2 | 3 | RUN apk add --no-cache git git-lfs openssh-client 4 | 5 | COPY entrypoint.sh /entrypoint.sh 6 | 7 | ENTRYPOINT ["/entrypoint.sh"] 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Carles Pina Estany 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 | # github-action-push-to-another-repository 2 | 3 | > [!WARNING] 4 | > TL;DR: this repository is not maintained for any new development. I plan to 5 | > fix issues if they arise due to changes on GitHub, to minimise disruption of 6 | > existing usage. 7 | > 8 | > My circumstances changed since I started the GitHub Action in 2020. I am not 9 | > able to add functionality to it or fix issues. 10 | > 11 | > The action is 175 lines of shell script. Feel free to fork it and modify it 12 | > for your own use case. 13 | > 14 | > If you create a fork that might replace this one, I will add a note in the 15 | > documentation and the README.md. Please, open an issue and I will do it. 16 | 17 | See the extensive documentation in https://cpina.github.io/push-to-another-repository-docs/ (includes examples, FAQ, troubleshooting, etc.). 18 | 19 | GitHub repository of the documentation: https://github.com/cpina/push-to-another-repository-docs 20 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: Push directory to another repository 2 | description: >- 3 | Useful to push files to another repository to be used, for example, via github 4 | pages 5 | inputs: 6 | source-before-directory: 7 | description: Source before directory from the origin directory 8 | required: false 9 | source-directory: 10 | description: Source directory from the origin directory 11 | required: true 12 | destination-github-username: 13 | description: Name of the destination username/organization 14 | required: true 15 | destination-repository-name: 16 | description: Destination repository 17 | required: true 18 | user-email: 19 | description: Email for the git commit 20 | required: true 21 | github-server: 22 | description: 'Github server' 23 | default: 'github.com' 24 | required: false 25 | user-name: 26 | description: >- 27 | [Optional] Name for the git commit. Defaults to the destination 28 | username/organization name 29 | required: false 30 | default: '' 31 | destination-repository-username: 32 | description: '[Optional] Username/organization for the destination repository' 33 | required: false 34 | default: '' 35 | target-branch: 36 | description: >- 37 | [Optional] set target branch name for the destination repository. Defaults 38 | to "main" 39 | default: main 40 | required: false 41 | commit-message: 42 | description: >- 43 | [Optional] commit message for the output repository. ORIGIN_COMMIT is 44 | replaced by the URL@commit in the origin repo 45 | default: Update from ORIGIN_COMMIT 46 | required: false 47 | target-directory: 48 | description: '[Optional] The directory to wipe and replace in the target repository' 49 | default: '' 50 | required: false 51 | create-target-branch-if-needed: 52 | type: boolean 53 | description: >- 54 | [Optional] create target branch if not exist. Defaults to `false` 55 | default: false 56 | required: false 57 | 58 | runs: 59 | using: docker 60 | image: Dockerfile 61 | args: 62 | - '${{ inputs.source-before-directory }}' 63 | - '${{ inputs.source-directory }}' 64 | - '${{ inputs.destination-github-username }}' 65 | - '${{ inputs.destination-repository-name }}' 66 | - '${{ inputs.github-server }}' 67 | - '${{ inputs.user-email }}' 68 | - '${{ inputs.user-name }}' 69 | - '${{ inputs.destination-repository-username }}' 70 | - '${{ inputs.target-branch }}' 71 | - '${{ inputs.commit-message }}' 72 | - '${{ inputs.target-directory }}' 73 | - '${{ inputs.create-target-branch-if-needed }}' 74 | branding: 75 | icon: git-commit 76 | color: green 77 | -------------------------------------------------------------------------------- /entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -l 2 | 3 | set -e # if a command fails it stops the execution 4 | set -u # script fails if trying to access to an undefined variable 5 | 6 | echo "[+] Action start" 7 | SOURCE_BEFORE_DIRECTORY="${1}" 8 | SOURCE_DIRECTORY="${2}" 9 | DESTINATION_GITHUB_USERNAME="${3}" 10 | DESTINATION_REPOSITORY_NAME="${4}" 11 | GITHUB_SERVER="${5}" 12 | USER_EMAIL="${6}" 13 | USER_NAME="${7}" 14 | DESTINATION_REPOSITORY_USERNAME="${8}" 15 | TARGET_BRANCH="${9}" 16 | COMMIT_MESSAGE="${10}" 17 | TARGET_DIRECTORY="${11}" 18 | CREATE_TARGET_BRANCH_IF_NEEDED="${12}" 19 | 20 | if [ -z "$DESTINATION_REPOSITORY_USERNAME" ] 21 | then 22 | DESTINATION_REPOSITORY_USERNAME="$DESTINATION_GITHUB_USERNAME" 23 | fi 24 | 25 | if [ -z "$USER_NAME" ] 26 | then 27 | USER_NAME="$DESTINATION_GITHUB_USERNAME" 28 | fi 29 | 30 | # Verify that there (potentially) some access to the destination repository 31 | # and set up git (with GIT_CMD variable) and GIT_CMD_REPOSITORY 32 | if [ -n "${SSH_DEPLOY_KEY:=}" ] 33 | then 34 | echo "[+] Using SSH_DEPLOY_KEY" 35 | 36 | # Inspired by https://github.com/leigholiver/commit-with-deploy-key/blob/main/entrypoint.sh , thanks! 37 | mkdir --parents "$HOME/.ssh" 38 | DEPLOY_KEY_FILE="$HOME/.ssh/deploy_key" 39 | echo "${SSH_DEPLOY_KEY}" > "$DEPLOY_KEY_FILE" 40 | chmod 600 "$DEPLOY_KEY_FILE" 41 | 42 | SSH_KNOWN_HOSTS_FILE="$HOME/.ssh/known_hosts" 43 | ssh-keyscan -H "$GITHUB_SERVER" > "$SSH_KNOWN_HOSTS_FILE" 44 | 45 | export GIT_SSH_COMMAND="ssh -i "$DEPLOY_KEY_FILE" -o UserKnownHostsFile=$SSH_KNOWN_HOSTS_FILE" 46 | 47 | GIT_CMD_REPOSITORY="git@$GITHUB_SERVER:$DESTINATION_REPOSITORY_USERNAME/$DESTINATION_REPOSITORY_NAME.git" 48 | 49 | elif [ -n "${API_TOKEN_GITHUB:=}" ] 50 | then 51 | echo "[+] Using API_TOKEN_GITHUB" 52 | GIT_CMD_REPOSITORY="https://$DESTINATION_REPOSITORY_USERNAME:$API_TOKEN_GITHUB@$GITHUB_SERVER/$DESTINATION_REPOSITORY_USERNAME/$DESTINATION_REPOSITORY_NAME.git" 53 | else 54 | echo "::error::API_TOKEN_GITHUB and SSH_DEPLOY_KEY are empty. Please fill one (recommended the SSH_DEPLOY_KEY)" 55 | exit 1 56 | fi 57 | 58 | 59 | CLONE_DIR=$(mktemp -d) 60 | 61 | echo "[+] Git version" 62 | git --version 63 | 64 | echo "[+] Enable git lfs" 65 | git lfs install 66 | 67 | echo "[+] Cloning destination git repository $DESTINATION_REPOSITORY_NAME" 68 | 69 | # Setup git 70 | git config --global user.email "$USER_EMAIL" 71 | git config --global user.name "$USER_NAME" 72 | 73 | # workaround for https://github.com/cpina/github-action-push-to-another-repository/issues/103 74 | git config --global http.version HTTP/1.1 75 | 76 | { 77 | git clone --single-branch --depth 1 --branch "$TARGET_BRANCH" "$GIT_CMD_REPOSITORY" "$CLONE_DIR" 78 | } || { 79 | if [ "$CREATE_TARGET_BRANCH_IF_NEEDED" = "true" ] 80 | then 81 | # Default branch of the repository is cloned. Later on the required branch 82 | # will be created 83 | git clone --single-branch --depth 1 "$GIT_CMD_REPOSITORY" "$CLONE_DIR" 84 | else 85 | false 86 | fi 87 | } || { 88 | echo "::error::Could not clone the destination repository. Command:" 89 | echo "::error::git clone --single-branch --branch $TARGET_BRANCH $GIT_CMD_REPOSITORY $CLONE_DIR" 90 | echo "::error::(Note that if they exist USER_NAME and API_TOKEN is redacted by GitHub)" 91 | echo "::error::Please verify that the target repository exist AND that it contains the destination branch name, and is accesible by the API_TOKEN_GITHUB OR SSH_DEPLOY_KEY" 92 | exit 1 93 | 94 | } 95 | ls -la "$CLONE_DIR" 96 | 97 | TEMP_DIR=$(mktemp -d) 98 | # This mv has been the easier way to be able to remove files that were there 99 | # but not anymore. Otherwise we had to remove the files from "$CLONE_DIR", 100 | # including "." and with the exception of ".git/" 101 | mv "$CLONE_DIR/.git" "$TEMP_DIR/.git" 102 | 103 | # $TARGET_DIRECTORY is '' by default 104 | ABSOLUTE_TARGET_DIRECTORY="$CLONE_DIR/$TARGET_DIRECTORY/" 105 | 106 | echo "[+] Deleting $ABSOLUTE_TARGET_DIRECTORY" 107 | rm -rf "$ABSOLUTE_TARGET_DIRECTORY" 108 | 109 | echo "[+] Creating (now empty) $ABSOLUTE_TARGET_DIRECTORY" 110 | mkdir -p "$ABSOLUTE_TARGET_DIRECTORY" 111 | 112 | echo "[+] Listing Current Directory Location" 113 | ls -al 114 | 115 | echo "[+] Listing root Location" 116 | ls -al / 117 | 118 | mv "$TEMP_DIR/.git" "$CLONE_DIR/.git" 119 | 120 | echo "[+] List contents of $SOURCE_DIRECTORY" 121 | ls "$SOURCE_DIRECTORY" 122 | 123 | echo "[+] Checking if local $SOURCE_DIRECTORY exist" 124 | if [ ! -d "$SOURCE_DIRECTORY" ] 125 | then 126 | echo "ERROR: $SOURCE_DIRECTORY does not exist" 127 | echo "This directory needs to exist when push-to-another-repository is executed" 128 | echo 129 | echo "In the example it is created by ./build.sh: https://github.com/cpina/push-to-another-repository-example/blob/main/.github/workflows/ci.yml#L19" 130 | echo 131 | echo "If you want to copy a directory that exist in the source repository" 132 | echo "to the target repository: you need to clone the source repository" 133 | echo "in a previous step in the same build section. For example using" 134 | echo "actions/checkout@v2. See: https://github.com/cpina/push-to-another-repository-example/blob/main/.github/workflows/ci.yml#L16" 135 | exit 1 136 | fi 137 | 138 | echo "[+] Copying contents of source repository folder $SOURCE_DIRECTORY to folder $TARGET_DIRECTORY in git repo $DESTINATION_REPOSITORY_NAME" 139 | cp -ra "$SOURCE_DIRECTORY"/. "$CLONE_DIR/$TARGET_DIRECTORY" 140 | cd "$CLONE_DIR" 141 | 142 | echo "[+] Files that will be pushed" 143 | ls -la 144 | 145 | ORIGIN_COMMIT="https://$GITHUB_SERVER/$GITHUB_REPOSITORY/commit/$GITHUB_SHA" 146 | COMMIT_MESSAGE="${COMMIT_MESSAGE/ORIGIN_COMMIT/$ORIGIN_COMMIT}" 147 | COMMIT_MESSAGE="${COMMIT_MESSAGE/\$GITHUB_REF/$GITHUB_REF}" 148 | 149 | echo "[+] Set directory is safe ($CLONE_DIR)" 150 | # Related to https://github.com/cpina/github-action-push-to-another-repository/issues/64 151 | git config --global --add safe.directory "$CLONE_DIR" 152 | 153 | if [ "$CREATE_TARGET_BRANCH_IF_NEEDED" = "true" ] 154 | then 155 | echo "[+] Switch to the TARGET_BRANCH" 156 | # || true: if the $TARGET_BRANCH already existed in the destination repo: 157 | # it is already the current branch and it cannot be switched to 158 | # (it's not needed) 159 | # If the branch did not exist: it switches (creating) the branch 160 | git switch -c "$TARGET_BRANCH" || true 161 | fi 162 | 163 | echo "[+] Adding git commit" 164 | git add . 165 | 166 | echo "[+] git status:" 167 | git status 168 | 169 | echo "[+] git diff-index:" 170 | # git diff-index : to avoid doing the git commit failing if there are no changes to be commit 171 | git diff-index --quiet HEAD || git commit --message "$COMMIT_MESSAGE" 172 | 173 | echo "[+] Pushing git commit" 174 | # --set-upstream: sets de branch when pushing to a branch that does not exist 175 | git push "$GIT_CMD_REPOSITORY" --set-upstream "$TARGET_BRANCH" 176 | --------------------------------------------------------------------------------