├── VERSION ├── Dockerfile ├── entrypoint.sh ├── action.yml ├── README.md └── .github └── workflows └── test-tag.yml /VERSION: -------------------------------------------------------------------------------- 1 | v1.0.4 2 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Container image that runs your code 2 | FROM alpine:3.10 3 | 4 | RUN apk update && apk add git openssh-client 5 | 6 | # Copies your code file from your action repository to the filesystem path `/` of the container 7 | COPY entrypoint.sh /entrypoint.sh 8 | 9 | # Code file to execute when the docker container starts up (`entrypoint.sh`) 10 | ENTRYPOINT ["/entrypoint.sh"] 11 | -------------------------------------------------------------------------------- /entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -l 2 | set -e 3 | 4 | if [ ! -f "${INPUT_SOURCE}" ] && [ ! -d "${INPUT_SOURCE}" ]; then 5 | echo "No source specified" 6 | exit 1 7 | fi 8 | 9 | # set up some directories 10 | CALLING_DIR=$(pwd) 11 | WORKING_DIR=$(mktemp -d) 12 | 13 | # set up the github deploy key 14 | mkdir -p ~/.ssh 15 | echo "${INPUT_DEPLOY_KEY}" > ~/.ssh/id_rsa 16 | chmod 600 ~/.ssh/id_rsa 17 | 18 | # set up git 19 | git config --global user.name "${INPUT_GIT_USERNAME}" 20 | git config --global user.email "${INPUT_GIT_EMAIL}" 21 | ssh-keyscan -H github.com > ~/.ssh/known_hosts 22 | GIT_SSH='ssh -i /github/home/.ssh/id_rsa -o UserKnownHostsFile=/github/home/.ssh/known_hosts' 23 | 24 | # clone the repo into our working directory and cd to it 25 | GIT_SSH_COMMAND=$GIT_SSH git clone git@github.com:$INPUT_DESTINATION_REPO.git $WORKING_DIR 26 | cd $WORKING_DIR 27 | 28 | # checkout the destination branch, creating it if it doesn't exist 29 | git checkout $INPUT_DESTINATION_BRANCH || git checkout -b $INPUT_DESTINATION_BRANCH 30 | 31 | # ensure destination directory exists, and is emptied if appropriate 32 | mkdir -p $INPUT_DESTINATION_FOLDER 33 | cd $INPUT_DESTINATION_FOLDER 34 | if [ "${INPUT_DELETE_DESTINATION}" = "true" ]; then 35 | git rm -rf . 36 | fi 37 | 38 | # do the copy 39 | if [ -f $CALLING_DIR/$INPUT_SOURCE ]; then 40 | cp -a $CALLING_DIR/$INPUT_SOURCE . 41 | elif [ -d $CALLING_DIR/$INPUT_SOURCE ]; then 42 | cp -a $CALLING_DIR/$INPUT_SOURCE/* . 43 | fi 44 | 45 | # create the commit 46 | git add . 47 | git commit -m "${INPUT_COMMIT_MESSAGE}" || echo 48 | GIT_SSH_COMMAND=$GIT_SSH git push -u origin $INPUT_DESTINATION_BRANCH 49 | 50 | # output the commit hash 51 | echo "commit_hash=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT 52 | exit 0 53 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: 'Commit with deploy key' 2 | description: 'Commit to another repository using a deploy key' 3 | branding: 4 | icon: git-commit 5 | color: green 6 | inputs: 7 | source: 8 | description: 'The file/directory to commit' 9 | required: true 10 | deploy_key: 11 | description: 'Private SSH key. Public key must be added to the destination repostitory as a deploy key with push access' 12 | required: true 13 | destination_repo: 14 | description: 'Git repository to push changes to' 15 | required: true 16 | destination_folder: 17 | description: 'Directory in destination repo to push changes to' 18 | required: false 19 | default: '.' 20 | destination_branch: 21 | description: 'Branch in destination repo to push changes to (default `main`)' 22 | required: false 23 | default: 'main' 24 | delete_destination: 25 | description: 'Delete destination directory contents before copy? (default `false`)' 26 | required: false 27 | default: false 28 | git_username: 29 | description: 'Git username' 30 | required: false 31 | default: ${{ github.actor }} 32 | git_email: 33 | description: 'Git email address' 34 | required: false 35 | default: ${{ github.actor }} 36 | commit_message: 37 | description: 'Commit message' 38 | required: false 39 | default: "${{ github.job }} from https://github.com/${{ github.repository }}/commit/${{ github.sha }}" 40 | outputs: 41 | commit_hash: 42 | description: 'The SHA hash of the generated commit' 43 | runs: 44 | using: 'docker' 45 | image: 'Dockerfile' 46 | args: 47 | - ${{ inputs.source }} 48 | - ${{ inputs.destination_repo }} 49 | - ${{ inputs.destination_folder }} 50 | - ${{ inputs.delete_destination }} 51 | - ${{ inputs.deploy_key }} 52 | - ${{ inputs.git_username }} 53 | - ${{ inputs.git_email }} 54 | - ${{ inputs.commit_message }} 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Commit with deploy key 2 | Action to commit a file or directory to another repo using a deploy key. 3 | 4 | ## Usage 5 | * Create an SSH key pair to use for the commits 6 | * Add the public key to your destination repo as a deploy key with write access 7 | * Add the private key to your source repo as a secret 8 | * Add this action to your workflow: 9 | ```yaml 10 | uses: leigholiver/commit-with-deploy-key@v1.0.4 11 | with: 12 | source: build_output 13 | destination_folder: dist 14 | destination_repo: leigholiver/commit-with-deploy-key 15 | deploy_key: ${{ secrets.DEPLOY_KEY }} 16 | ``` 17 | 18 | ## Inputs 19 | | Name | Required | Default | Description | 20 | |--------------------- |--------- |----------------------------------- |---------------------------------------------------------| 21 | | `source` | `true` | | The file/directory to commit | 22 | | `deploy_key` | `true` | | Private SSH key to use for the commit. The public key must be added to the destination repostitory as a deploy key, with push access | 23 | | `destination_repo` | `true` | | Git repository to push changes to | 24 | | `destination_folder` | `false` | `.` | Directory in the destination repo to push changes to | 25 | | `destination_branch` | `false` | `main` | Branch in destination repo to push changes to | 26 | | `delete_destination` | `false` | `false` | Delete destination directory contents before copy? | 27 | | `git_username` | `false` | `${{ github.actor }}` | Github user to use for the commit | 28 | | `git_email` | `false` | `${{ github.actor }}` | Github user to use for the commit | 29 | | `commit_message` | `false` | ` from ` | Commit message | 30 | 31 | ## Outputs 32 | | Name | Description | 33 | |---------------|----------------------------------| 34 | | `commit_hash` | SHA hash of the generated commit | 35 | -------------------------------------------------------------------------------- /.github/workflows/test-tag.yml: -------------------------------------------------------------------------------- 1 | name: Run tests, Tag release 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - fix/* 8 | 9 | jobs: 10 | 11 | run_tests: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Checkout 15 | uses: actions/checkout@v2 16 | 17 | - name: create test file 18 | run: echo $(date) > tmp.txt 19 | 20 | - name: create test directory 21 | run: mkdir -p tmp && cp tmp.txt tmp && echo "second cool file" > tmp/tmp2.txt 22 | 23 | - name: test with file 24 | uses: ./ 25 | id: filetest 26 | with: 27 | source: tmp.txt 28 | destination_repo: leigholiver/commit-with-deploy-key 29 | destination_branch: file_test 30 | deploy_key: ${{ secrets.DEPLOY_KEY }} 31 | 32 | - name: test commit hash output 33 | run: echo "the commit hash for the file test is ${{ steps.filetest.outputs.commit_hash }}" 34 | 35 | - name: test with directory 36 | uses: ./ 37 | with: 38 | source: tmp 39 | destination_repo: leigholiver/commit-with-deploy-key 40 | destination_branch: directory_test 41 | deploy_key: ${{ secrets.DEPLOY_KEY }} 42 | 43 | - name: test destination directory 44 | uses: ./ 45 | with: 46 | source: tmp 47 | destination_repo: leigholiver/commit-with-deploy-key 48 | destination_branch: destination_directory_test 49 | destination_folder: destination 50 | deploy_key: ${{ secrets.DEPLOY_KEY }} 51 | 52 | - name: test destination subdirectory 53 | uses: ./ 54 | with: 55 | source: tmp 56 | destination_repo: leigholiver/commit-with-deploy-key 57 | destination_branch: destination_subdirectory_test 58 | destination_folder: destination/destination_sub 59 | deploy_key: ${{ secrets.DEPLOY_KEY }} 60 | 61 | - name: test destination directory with removal 62 | uses: ./ 63 | with: 64 | source: tmp 65 | destination_repo: leigholiver/commit-with-deploy-key 66 | destination_branch: destination_directory_test_with_delete 67 | delete_destination: true 68 | deploy_key: ${{ secrets.DEPLOY_KEY }} 69 | 70 | - name: test with different username 71 | uses: ./ 72 | with: 73 | source: tmp.txt 74 | destination_repo: leigholiver/commit-with-deploy-key 75 | destination_branch: username_test 76 | deploy_key: ${{ secrets.DEPLOY_KEY }} 77 | git_username: some different user 78 | 79 | - name: test with different commit message 80 | uses: ./ 81 | with: 82 | source: tmp.txt 83 | destination_repo: leigholiver/commit-with-deploy-key 84 | destination_branch: commit_message_test 85 | deploy_key: ${{ secrets.DEPLOY_KEY }} 86 | commit_message: testing a custom commit message (${{ github.sha }}) 87 | 88 | - name: test workflow doesnt fail when there is nothing to commit 89 | uses: ./ 90 | with: 91 | source: tmp.txt 92 | destination_repo: leigholiver/commit-with-deploy-key 93 | destination_branch: commit_message_test 94 | deploy_key: ${{ secrets.DEPLOY_KEY }} 95 | commit_message: testing a custom commit message (${{ github.sha }}) 96 | 97 | 98 | # If the tests are successful, and we've merged to main, create a tag 99 | create_tag: 100 | runs-on: ubuntu-latest 101 | if: github.ref == 'refs/heads/main' 102 | needs: run_tests 103 | steps: 104 | - name: Checkout 105 | uses: actions/checkout@v2 106 | 107 | - name: check if tag already exists 108 | run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* && git rev-parse "$(cat VERSION)" >/dev/null 2>&1 && exit 1 || exit 0 109 | 110 | - name: create tag 111 | run: git config --global user.email "${{ github.actor }}" && git config --global user.name "${{ github.actor }}" && git tag -a -m "$(cat VERSION)" $(cat VERSION) && git push --follow-tags 112 | --------------------------------------------------------------------------------