This GitHub Action will help to push files from one GitHub repository to another. For example, on a git push in a `source` repository, files can be pushed into a `destination` repository.
* Specifying a directory in a `source` repository to be pushed to a `destination` repository
* Generating some files using another GitHub Action and pushing them into another `destination` repository (e.g. generate PDFs from MarkDown and push the PDFs across to the `destination` repository)
* Using SSH deploy keys (recommended, a bit harder to set up): [push-to-another-repository-deploy-keys-example](https://github.com/cpina/push-to-another-repository-deploy-keys-example). The configuration is in the file [.github/workflows/ci.yml](https://github.com/cpina/push-to-another-repository-deploy-keys-example/blob/main/.github/workflows/ci.yml#L21)
* Using a Personal Access Token (first iteration, not recommended but easier to set up: [push-to-another-repository-example](https://github.com/cpina/push-to-another-repository-example). The configuration is in the file [.github/workflows/ci.yml](https://github.com/cpina/push-to-another-repository-example/blob/main/.github/workflows/ci.yml#L21)
Once the setup using one of the methods above has been done, the file [build.sh](https://github.com/cpina/push-to-another-repository-deploy-keys-example/blob/main/build.sh) is executed, creating a new directory `output/`, and this directory is copied across to the [destination repository](https://github.com/cpina/push-to-another-repository-output).
:warning: Please bear in mind that the files in the specified directory of the target repository are deleted unless the option `target-directory` is used (in this case, only the files for this directory are deleted).
Username/Organization of the GitHub repository that will be used for the `destination` repository. To output to a repository such as `https://github.com/cpina/push-to-another-repository-output` this variable would be `cpina`.
Name of the `destination` repository. To output to a repository such as `https://github.com/cpina/push-to-another-repository-output` this variable would be `push-to-another-repository-output`
:warning:: the GitHub Action currently deletes all the files and directories in the destination repository. The idea is to copy from an `output` directory into the `destination-repository-name`, removing all pre-existing files.
The name that will be used for the commit to the destination-repository-name. If not specified, the `destination-github-username` will be used instead.
The Username/Organization for the destination repository, if different from `destination-github-username`. For the repository `https://github.com/cpina/push-to-another-repository-output` this variable would be `cpina`.
Someone with write access to your repository or this Action, could technically add code to leak the Token. Thus, *it is recommended to use the SSH deploy key method to minimise the impact* if this were to happen.
* In your computer terminal, generate an SSH key using: `ssh-keygen -t ed25519 -C "your_email@example.com"` (the type ed25519 is recommended by [GitHub documentation](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent#generating-a-new-ssh-key)).
*`ssh-keygen` will ask for a file path: `Enter file in which to save the key`: write a new file name. I suggest the default directory and as a filename: `id_github_{name_of_your_destination_repository}` to avoid overwriting a previous file. If you will be using this Action for multiple repositories, you might want to generate different keys for each one. For the repository `https://github.com/cpina/push-to-another-repository-example/`, `id_github_push-to-another-repository-example` could be used.
* Title: "GitHub Action push to another repository"
* Key: paste the contents of the file with the public key. This was generated in the "Generate the key files" step and the name is "id_github_name_of_your_repository.pub"
* Value: paste the contents of the file with the private key. This was generated in the "Generate the key files" step and the name is "id_github_name_of_your_repository"
This does not need to be done if you chose to set up the deploy keys using the steps above. This method is here for compatibility with the initial approach of this GitHub Action. The Personal Access Token would have access to all your repositories, so if it were to be leaked, the damage would be greater: it would allow pushes to the same repositories to which the Personal Access Token owner has access, and other possible associated permissions. On the other hand, the setup is a bit easier because it does not involve creating the deploy key.
* Generate a new token entering a name and expiration date, and choose "Repo". Click the bottom button "Generate token". If you choose an expiration date you will need to create a new token after this date. In this example, I have used "No expiration"; this should be used carefully.
This example shows both set up methods. Only one of the lines, `SSH_DEPLOY_KEY` or `API_TOKEN_GITHUB`, is needed according to the set up method that is being used. Do not include the other line.
This is the most common problem. Carefully read the logs on the GitHub Action pages of the source repositories. The action tries to write the errors and gives possible solutions / hints. To solve this problem, the first suggestion is to follow the steps above to redo the setup following the steps above. If this still does not work, the following problems have occurred in the past, so they may be useful points to start solving the problem:
* User was logged in to GitHub with an account that did not have permission to push into the destination repository. The action could not push (permission denied).
Instead of `.ssh/id_push-to-another-repository-output_ed25519`, use the file as you created it. This is the **private** key (it does not end with `.pub`). If you used the correct private key for the correctly uploaded public key, it will print something along the lines of:
This should match what you see in the deploy key of the destination repository. If it does not match, the deploy key is not properly set (perhaps different public/private keys were used, for example).
If the Personal Access Token method was used for the setup, check it has the correct permissions to push to the destination repository and has not expired.
It seems that GitHub created a Personal Access Token with a space character. This would happen if the Personal Token had a `#` or some other characters.
The problem, for those that are curious, is that the Personal Access Token is used in the git URLs and the URLs don't support `#`. The error "URL using bad/illegal format" comes from the curl library used by git.
More information: [issue 70](https://github.com/cpina/github-action-push-to-another-repository/issues/70)
Use `source_directory: .` to copy all the source GitHub repository to the destination.
:warning: this will also copy `.github/workflows/`! The destination repository will try to execute the Action. It will probably fail because the SSH keys / Personal Acccess Token will not be available for the destination repository.
A suggestion if you are using `source_directory: .` is to disable the GitHub Actions in the destination repository. To disable Actions in the destination repository:
* Go to the destination repository (e.g. https://github.com/cpina/push-to-another-repository-output/settings)
* Click on "Settings"
* On the left side bar click on "Actions" and then "General"
* Click on "Disable actions"
* Click on "Save"
### How can I copy only some files / only some directories / exclude some files / etc.?
If you need to filter files or directories (exclude files, include only some, etc.) use a step before the Action to filter these into a temporary directory that will be pushed. This can be done with "rsync" or any tool that you feel comfortable with (could be "rclone" or "find + exec + rm", "find + exec + mv", etc. depending on your needs).
For example, see the step: https://github.com/cpina/push-to-another-repository-deploy-keys-example/blob/main/.github/workflows/ci.yml#L21
In the step above, rsync is installed (depending on your environment it will already be installed) and everything is copied from "output_temp" to "output" excluding "main.epub". Be careful with the usage of "/" and the exclude parameter in rsync directories. Refer to the rsync documentation for other options such as filter using an extension to include only some files / directories, etc.