├── .gitignore ├── Dockerfile ├── .github └── workflows │ └── main.yml ├── action.yml ├── conflictFinder ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.12.0 2 | 3 | RUN apk add bash 4 | RUN apk add grep 5 | 6 | COPY conflictFinder /conflictFinder 7 | 8 | ENTRYPOINT ["/conflictFinder"] 9 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | on: [push] 2 | 3 | jobs: 4 | merge_conflict_job: 5 | runs-on: ubuntu-latest 6 | name: Find merge conflicts 7 | steps: 8 | - uses: actions/checkout@v1 9 | - name: Merge Conflict finder 10 | uses: olivernybroe/action-conflict-finder@master 11 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: 'Merge Conflict Finder' 2 | description: 'Check if there are any unresolved merge conflicts' 3 | branding: 4 | icon: 'git-merge' 5 | color: 'gray-dark' 6 | inputs: 7 | exclude_dir: 8 | description: "Glob of directories to exclude from check" 9 | required: false 10 | default: 'node_modules,vendor' 11 | excludes: 12 | description: "Glob of files to exclude from check, supports wildcards" 13 | required: false 14 | default: '' 15 | runs: 16 | using: 'docker' 17 | image: 'Dockerfile' 18 | -------------------------------------------------------------------------------- /conflictFinder: -------------------------------------------------------------------------------- 1 | #!/bin/bash -l 2 | set -eu 3 | 4 | grepExit () { 5 | # Grep Returns 1 if pattern not found, > 1 is an error 6 | if [ $1 -eq 1 ]; then 7 | printf "\033[0;32mNo merge conflicts found.\033[0m\n" 8 | exit 0; 9 | fi 10 | printf "\033[1;31mGrep Error.\033[0m\n" 11 | exit 1; 12 | } 13 | 14 | EXCLUDE=(${INPUT_EXCLUDES/,/ }) 15 | EXCLUDE_DIR=(${INPUT_EXCLUDE_DIR/,/ }) 16 | 17 | CONFLICTS="$(grep -lr -r --exclude-dir=.git "${EXCLUDE_DIR[@]/#/--exclude-dir=}" "${EXCLUDE[@]/#/--exclude=}" -E -- '^<<<<<<<|^>>>>>>>' .)" || grepExit $? 18 | 19 | printf "\033[1;31mFound merge conflicts.\033[0m\n" 20 | for file in "$CONFLICTS" 21 | do 22 | echo "::error file="$file"::Merge conflict found in $file" 23 | done 24 | 25 | exit 1; 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Oliver Nybroe 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 | # Merge Conflict Finder 2 | 3 | This action finds any merge conflicts in your repository. 4 | 5 | Sometimes we accidentally resolve merge conflicts without actually resolving it, 6 | this action simply finds if we have any instances of files with merge conflicts we 7 | didn't resolve and reports them. 8 | 9 | 10 | ## How to use it? 11 | This is a Github action, so it has to be added to a github workflow. 12 | A simple example of running this action on all pushes to the repository would be 13 | add a `main.yml` file under `.github/workflows` with the following content 14 | ```yaml 15 | on: [push] 16 | 17 | jobs: 18 | merge_conflict_job: 19 | runs-on: ubuntu-latest 20 | name: Find merge conflicts 21 | steps: 22 | # Checkout the source code so we have some files to look at. 23 | - uses: actions/checkout@v2 24 | # Run the actual merge conflict finder 25 | - name: Merge Conflict finder 26 | uses: olivernybroe/action-conflict-finder@v2.0 27 | ``` 28 | 29 | On each push, it will now run the merge conflict finder 30 | 31 | ### Excludes 32 | You can add custom excludes to the search through the following inputs: 33 | 34 | #### `exclude_dir` 35 | A comma separate list of directories to ignore. The .git folder is always ignored 36 | 37 | #### `excludes` 38 | A comma separated list of files to ignore. Supports wildcard matching. 39 | 40 | A workflow with the inputs could look like: 41 | 42 | ```yaml 43 | on: [push] 44 | 45 | jobs: 46 | merge_conflict_job: 47 | runs-on: ubuntu-latest 48 | name: Find merge conflicts 49 | steps: 50 | # Checkout the source code so we have some files to look at. 51 | - uses: actions/checkout@v2 52 | # Run the actual merge conflict finder 53 | - name: Merge Conflict finder 54 | uses: olivernybroe/action-conflict-finder@v2.0 55 | with: 56 | exclude_dir: "path/to/ignore,path/to/ignore2" 57 | excludes: "ignore.me,*.zip" 58 | ``` 59 | --------------------------------------------------------------------------------