├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── action.yml └── entrypoint.py /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | .pytest_cache 3 | .hypothesis -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.7-alpine 2 | 3 | LABEL version="1.0.0" 4 | LABEL repository="https://github.com/github-actions-x/commit" 5 | LABEL homepage="https://github.com/github-actions-x/commit" 6 | LABEL maintainer="Ruslan Nasonov " 7 | 8 | LABEL com.github.actions.name="Git Commit and Push" 9 | LABEL com.github.actions.description="Commits any changed files and pushes the result back to origin." 10 | LABEL com.github.actions.icon="git-commit" 11 | LABEL com.github.actions.color="green" 12 | COPY LICENSE README.md / 13 | 14 | RUN apk --update --no-cache add git git-lfs && pip install plumbum 15 | 16 | COPY "entrypoint.py" "/entrypoint.py" 17 | 18 | ENTRYPOINT ["/entrypoint.py"] 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019 Ruslan Nasonov 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 13 | in all 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 NON-INFRINGEMENT. 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## commit 2 | 3 | Git commit and push 4 | 5 | ### Example 6 | 7 | ```yaml 8 | name: publish 9 | 10 | on: 11 | push: 12 | branches: 13 | - master 14 | 15 | jobs: 16 | build: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: checkout 20 | uses: actions/checkout@master 21 | with: 22 | ref: master 23 | - name: build 24 | uses: github-actions-x/hugo@master 25 | - name: push 26 | uses: github-actions-x/commit@v2.9 27 | with: 28 | github-token: ${{ secrets.GITHUB_TOKEN }} 29 | push-branch: 'master' 30 | commit-message: 'publish' 31 | force-add: 'true' 32 | files: a.txt b.txt c.txt dirA/ dirB/ dirC/a.txt 33 | name: commiter name 34 | email: my.github@email.com 35 | 36 | ``` 37 | 38 | If you use `commit` inside [matrix](https://help.github.com/en/articles/workflow-syntax-for-github-actions#jobsjob_idstrategymatrix), set variable `rebase='true'` for pulling and rebasing changes. 39 | 40 | ```yaml 41 | name: Node CI 42 | 43 | on: 44 | push: 45 | branches: 46 | - master 47 | 48 | jobs: 49 | build: 50 | runs-on: ubuntu-latest 51 | strategy: 52 | matrix: 53 | node-version: 54 | - 10.x 55 | - 12.x 56 | steps: 57 | - uses: actions/checkout@v1 58 | - name: Use Node.js ${{ matrix.node-version }} 59 | uses: actions/setup-node@v1 60 | with: 61 | node-version: ${{ matrix.node-version }} 62 | - name: generate benchmarks 63 | run: | 64 | npm run generate-some-files-for-specific-node-version 65 | - name: push 66 | uses: github-actions-x/commit@v2.9 67 | with: 68 | github-token: ${{ secrets.GITHUB_TOKEN }} 69 | push-branch: master 70 | commit-message: '${{ matrix.node-version }} adds auto-generated benchmarks and bar graph' 71 | rebase: 'true' # pull and rebase before commit 72 | ``` 73 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: 'Git Commit and Push' 2 | description: 'Commits any changed files and pushes the result back to origin branch.' 3 | author: 'rusnasonov' 4 | branding: 5 | icon: 'git-commit' 6 | color: 'green' 7 | inputs: 8 | github-token: 9 | description: 'Github Token with commit access' 10 | required: true 11 | push-branch: 12 | description: 'Override branch to push to' 13 | required: false 14 | commit-message: 15 | description: 'Specify commit message' 16 | required: false 17 | default: 'autocommit' 18 | force-add: 19 | description: 'Force add files, useful for adding ignored files.' 20 | required: false 21 | default: 'false' 22 | force-push: 23 | description: 'Force push.' 24 | required: false 25 | default: 'false' 26 | rebase: 27 | description: 'Pull and rebase before commiting. Useful when using commit inside matrix.' 28 | required: false 29 | default: 'false' 30 | files: 31 | description: 'Specific files to add.' 32 | required: false 33 | default: '' 34 | email: 35 | description: 'Committer email. Default is ${name}@users.noreply.github.com' 36 | required: false 37 | default: '' 38 | name: 39 | description: 'Committer name. Default is name of the person or app that initiated the workflow.' 40 | required: false 41 | default: '' 42 | runs: 43 | using: 'docker' 44 | image: 'Dockerfile' 45 | -------------------------------------------------------------------------------- /entrypoint.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from plumbum import local 4 | import os 5 | 6 | def debug(message: str): 7 | print(f'##[debug]{message}') 8 | 9 | 10 | def run(): 11 | netrc_path = os.path.join(local.env.get('HOME', ''), '.netrc') 12 | github_actor = local.env.get('GITHUB_ACTOR') 13 | github_token = local.env.get('INPUT_GITHUB-TOKEN') 14 | commit_message = local.env.get('INPUT_COMMIT-MESSAGE') 15 | force_add = local.env.get('INPUT_FORCE-ADD') 16 | force_push = local.env.get('INPUT_FORCE-PUSH') 17 | branch = local.env.get('INPUT_PUSH-BRANCH') or "/".join(local.env.get('GITHUB_REF').split('/')[2:]) 18 | rebase = local.env.get('INPUT_REBASE', 'false') 19 | files = local.env.get('INPUT_FILES', '') 20 | email = local.env.get('INPUT_EMAIL', f'{github_actor}@users.noreply.github.com') 21 | name = local.env.get('INPUT_NAME', github_actor) 22 | with open(netrc_path, 'w') as f: 23 | f.write( 24 | f'machine github.com\n' 25 | f'login {github_actor}\n' 26 | f'password {github_token}\n' 27 | f'machine api.github.com\n' 28 | f'login {github_actor}\n' 29 | f'password {github_token}\n' 30 | ) 31 | chmod = local['chmod'] 32 | git = local['git'] 33 | debug(chmod(['600', netrc_path])) 34 | debug(git(['config', '--global', 'user.email', email])) 35 | debug(git(['config', '--global', 'user.name', name])) 36 | debug(git(['config', '--global', '--add', 'safe.directory', '/github/workspace'])) 37 | debug(f'username:{github_actor}, branch:{branch}, commit message:{commit_message}') 38 | with open(netrc_path) as f: 39 | debug(f.read()) 40 | add_args = ['add'] 41 | if force_add == 'true': 42 | add_args.append('-f') 43 | add_args.append('-A') 44 | if files: 45 | debug(f"Files: {files}") 46 | add_args.extend(files.strip("'").split()) 47 | if rebase == 'true': 48 | debug(git(['pull', '--rebase', '--autostash', 'origin', branch])) 49 | push_args = ['push', '--follow-tags', '--set-upstream', 'origin', branch] 50 | if force_push == 'true': 51 | push_args.append('--force') 52 | debug(git(['checkout', '-B', branch])) 53 | debug(git(add_args)) 54 | debug(git(['commit', '-m', commit_message], retcode=None)) 55 | debug(git(push_args)) 56 | 57 | if __name__ == '__main__': 58 | run() 59 | --------------------------------------------------------------------------------