├── .deepsource.toml ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ └── push.yml ├── Dockerfile ├── LICENSE ├── README.md ├── action.yml ├── entrypoint.sh ├── md ├── AdditionalFileTest1.md ├── AdditionalFileTest2.md ├── dir1 │ ├── dir1level2 │ │ ├── level-2a.md │ │ └── level-2b.md │ ├── level-1a.md │ └── level-1b.md ├── dir2 │ ├── dir2level2 │ │ ├── level-2a.md │ │ └── level-2b.md │ ├── level-1a.md │ └── level-1b.md ├── dir3 │ ├── dir3level2 │ │ ├── level-2a.md │ │ └── level-2b.md │ └── level-1b.md ├── dir4 │ └── ok4.md ├── dir5 │ └── ok5.md ├── file1.md ├── file2.md ├── file3.markdown └── file4.markdown └── mlc_config.json /.deepsource.toml: -------------------------------------------------------------------------------- 1 | version = 1 2 | 3 | [[analyzers]] 4 | name = "docker" 5 | enabled = true 6 | 7 | -------------------------------------------------------------------------------- /.github/FUNDING.yml : -------------------------------------------------------------------------------- 1 | ko_fi: gauravnelson -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '[Use Linkspector and action linkspector] ' 5 | assignees: '' 6 | --- 7 | 8 | 9 | 10 | 15 | 16 |
11 |

🚨 Update (March 2025)

12 |

I have developed a new tool called Linkspector, which offers improved functionality and reduced false positives. I recommend using Linkspector for your needs, which is now the preferred and supported option.

13 |

Try GitHub action Linkspector!

14 |
-------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '[Use Linkspector and action linkspector] ' 5 | assignees: '' 6 | --- 7 | 8 | 9 | 10 | 15 | 16 |
11 |

🚨 Update (March 2025)

12 |

I have developed a new tool called Linkspector, which offers improved functionality and reduced false positives. I recommend using Linkspector for your needs, which is now the preferred and supported option.

13 |

Try GitHub action Linkspector!

14 |
-------------------------------------------------------------------------------- /.github/workflows/push.yml: -------------------------------------------------------------------------------- 1 | on: [pull_request] 2 | name: PR Checks 3 | jobs: 4 | markdown-link-check: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@master 8 | - name: markdown-link-check 9 | uses: ./ 10 | with: 11 | check-modified-files-only: 'yes' 12 | id: markdown-link-check 13 | - name: display errors 14 | run: | 15 | echo "${{ steps.markdown-link-check.outputs.MLC_OUTPUT }}" 16 | 17 | markdown-link-check-folders: 18 | runs-on: ubuntu-latest 19 | steps: 20 | - uses: actions/checkout@master 21 | - name: markdown-link-check 22 | uses: ./ 23 | with: 24 | # Add a test to restrict the test to just dir4 and dir5. 25 | folder-path: './md/dir4, ./md/dir5' 26 | file-path: './md/AdditionalFileTest1.md, ./md/AdditionalFileTest2.md' 27 | shellcheck: 28 | runs-on: [ubuntu-latest] 29 | steps: 30 | - uses: 'bewuethr/shellcheck-action@v2' 31 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:21.7.3-alpine3.18 2 | RUN apk add --no-cache bash>5.0.16-r0 git>2.26.0-r0 3 | COPY entrypoint.sh /entrypoint.sh 4 | RUN chmod +x /entrypoint.sh 5 | ENTRYPOINT ["/entrypoint.sh"] 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Gaurav Nelson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | 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, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 24 | 25 |
4 |

⛔️ Deprecation notice (Apr 2025)

5 |

6 | This repository is now ⛔️ deprecated and is no longer actively maintained. 7 |

8 |

9 | For support and further development, please use the maintained fork available at 10 | Tcort GitHub Action Markdown Link Check. 11 |

12 |
13 |

14 | I have also developed a new tool called 15 | Linkspector, 16 | which offers improved functionality and reduced false positives. 17 | You can try this tool as an alternative if it fits your needs. 18 |

19 |

20 | Try GitHub Action Linkspector! 21 |

22 |
23 |
26 | 27 | ### GitHub Action - Markdown link check 🔗✔️ 28 | [![GitHub Marketplace](https://img.shields.io/badge/GitHub%20Marketplace-Markdown%20link%20check-brightgreen?style=for-the-badge)](https://github.com/marketplace/actions/markdown-link-check) 29 | Donate using Liberapay 30 | 31 | This GitHub action checks all Markdown files in your repository for broken links. (Uses [tcort/markdown-link-check](https://github.com/tcort/markdown-link-check)) 32 | 33 | ## How to use 34 | 1. Create a new file in your repository `.github/workflows/action.yml`. 35 | 1. Copy-paste the following workflow in your `action.yml` file: 36 | 37 | ```yml 38 | name: Check Markdown links 39 | 40 | on: push 41 | 42 | jobs: 43 | markdown-link-check: 44 | runs-on: ubuntu-latest 45 | steps: 46 | - uses: actions/checkout@master 47 | - uses: gaurav-nelson/github-action-markdown-link-check@v1 48 | ``` 49 | 50 | ### Real-life usage samples 51 | 52 | Following is a list of some of the repositories which are using GitHub Action - 53 | Markdown link check. 54 | 55 | 1. [netdata](https://github.com/netdata/netdata/blob/master/.github/workflows/docs.yml) ![](https://img.shields.io/github/stars/netdata/netdata?style=social) 56 | 1. [GoogleChrome/lighthouse (Weekly cron job)](https://github.com/GoogleChrome/lighthouse/blob/master/.github/workflows/cron-weekly.yml) 57 | ![](https://img.shields.io/github/stars/GoogleChrome/lighthouse?style=social) 58 | 1. [tendermint/tendermint](https://github.com/tendermint/tendermint/blob/master/.github/workflows/markdown-links.yml) 59 | ![](https://img.shields.io/github/stars/tendermint/tendermint?style=social) 60 | 1. [pyroscope-io/pyroscope](https://github.com/pyroscope-io/pyroscope/blob/main/.github/workflows/lint-markdown.yml) 61 | ![](https://img.shields.io/github/stars/pyroscope-io/pyroscope?style=social) 62 | 63 | If you are using this on production, consider [buying me a coffee](https://liberapay.com/gaurav-nelson/) ☕. 64 | 65 | ## Configuration 66 | 67 | - [Custom variables](#custom-variables) 68 | - [Scheduled runs](#scheduled-runs) 69 | - [Disable check for some links](#disable-check-for-some-links) 70 | - [Check only modified files in a pull request](#check-only-modified-files-in-a-pull-request) 71 | - [Check multiple directories and files](#check-multiple-directories-and-files) 72 | - [Status code 429: Too many requests](#too-many-requests) 73 | - [GitHub links failure fix](#github-links-failure-fix) 74 | 75 | ### Custom variables 76 | You customize the action by using the following variables: 77 | 78 | | Variable | Description | Default value | 79 | |:----------|:--------------|:-----------| 80 | |`use-quiet-mode`| Specify `yes` to only show errors in output.| `no`| 81 | |`use-verbose-mode`|Specify `yes` to show detailed HTTP status for checked links. |`no` | 82 | |`config-file`|Specify a [custom configuration file](https://github.com/tcort/markdown-link-check#config-file-format) for markdown-link-check. You can use it to remove false-positives by specifying replacement patterns and ignore patterns. The filename is interpreted relative to the repository root.|`mlc_config.json`| 83 | |`folder-path` |By default the `github-action-markdown-link-check` action checks for all markdown files in your repository. Use this option to limit checks to only specific folders. Use comma separated values for checking multiple folders. |`.` | 84 | |`max-depth` |Specify how many levels deep you want to check in the directory structure. The default value is `-1` which means check all levels.|`-1` | 85 | |`check-modified-files-only` |Use this variable to only check modified markdown files instead of checking all markdown files. The action uses `git` to find modified markdown files. Only use this variable when you run the action to check pull requests.|`no`| 86 | |`base-branch`|Use this variable to specify the branch to compare when finding modified markdown files. |`master`| 87 | |`file-extension`|By default the `github-action-markdown-link-check` action checks files in your repository with the `.md` extension. Use this option to specify a different file extension such as `.markdown` or `.mdx`.|`.md`| 88 | |`file-path` | Specify additional files (with complete path and extension) you want to check. Use comma separated values for checking multiple files. See [Check multiple directories and files](#check-multiple-directories-and-files) section for usage.| - | 89 | 90 | #### Sample workflow with variables 91 | 92 | ```yml 93 | name: Check Markdown links 94 | 95 | on: push 96 | 97 | jobs: 98 | markdown-link-check: 99 | runs-on: ubuntu-latest 100 | steps: 101 | - uses: actions/checkout@master 102 | - uses: gaurav-nelson/github-action-markdown-link-check@v1 103 | with: 104 | use-quiet-mode: 'yes' 105 | use-verbose-mode: 'yes' 106 | config-file: 'mlc_config.json' 107 | folder-path: 'docs/markdown_files' 108 | max-depth: 2 109 | ``` 110 | 111 | ### Scheduled runs 112 | In addition to checking links on every push, or pull requests, its also a good 113 | hygiene to check for broken links regularly as well. See 114 | [Workflow syntax for GitHub Actions - on.schedule](https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#onschedule) 115 | for more details. 116 | 117 | #### Sample workflow with scheduled job 118 | 119 | ```yml 120 | name: Check Markdown links 121 | 122 | on: 123 | push: 124 | branches: 125 | - master 126 | schedule: 127 | # Run everyday at 9:00 AM (See https://pubs.opengroup.org/onlinepubs/9699919799/utilities/crontab.html#tag_20_25_07) 128 | - cron: "0 9 * * *" 129 | 130 | jobs: 131 | markdown-link-check: 132 | runs-on: ubuntu-latest 133 | steps: 134 | - uses: actions/checkout@master 135 | - uses: gaurav-nelson/github-action-markdown-link-check@v1 136 | with: 137 | use-quiet-mode: 'yes' 138 | use-verbose-mode: 'yes' 139 | config-file: 'mlc_config.json' 140 | folder-path: 'docs/markdown_files' 141 | ``` 142 | 143 | ### Disable check for some links 144 | You can include the following HTML comments into your markdown files to disable 145 | checking for certain links in a markdown document. 146 | 147 | 1. `` and ``: Use these to disable links for all links appearing between these 148 | comments. 149 | - Example: 150 | ```md 151 | 152 | ## Section 153 | 154 | Disbale link checking in this section. Ignore this [Bad Link](https://exampleexample.cox) 155 | 156 | ``` 157 | 2. `` Use this comment to disable link checking for the next line. 158 | 3. `` Use this comment to disable link 159 | checking for the current line. 160 | 161 | ### Check only modified files in a pull request 162 | 163 | Use the following workflow to only check links in modified markdown files in a 164 | pull request. 165 | 166 | When 167 | you use this variable, the action finds modified files between two commits: 168 | - latest commit in you PR 169 | - latest commit in the `master` branch. If you are suing a different branch to 170 | merge PRs, specify the branch using `base-branch`. 171 | 172 | > **NOTE**: We can also use GitHub API to get all modified files in a PR, but that 173 | > would require tokens and stuff, create an issue or PR if you need that. 174 | 175 | ```yml 176 | on: [pull_request] 177 | name: Check links for modified files 178 | jobs: 179 | markdown-link-check: 180 | runs-on: ubuntu-latest 181 | steps: 182 | - uses: actions/checkout@master 183 | - uses: gaurav-nelson/github-action-markdown-link-check@v1 184 | with: 185 | use-quiet-mode: 'yes' 186 | use-verbose-mode: 'yes' 187 | check-modified-files-only: 'yes' 188 | 189 | ``` 190 | 191 | ### Check multiple directories and files 192 | 193 | ```yml 194 | on: [pull_request] 195 | name: Check links for modified files 196 | jobs: 197 | markdown-link-check: 198 | runs-on: ubuntu-latest 199 | steps: 200 | - uses: actions/checkout@master 201 | - uses: gaurav-nelson/github-action-markdown-link-check@v1 202 | with: 203 | use-quiet-mode: 'yes' 204 | folder-path: 'md/dir1, md/dir2' 205 | file-path: './README.md, ./LICENSE, ./md/file4.markdown' 206 | ``` 207 | 208 | ### Too many requests 209 | Use `retryOn429`, `retry-after`, `retryCount`, and `fallbackRetryDelay` in your custom configuration file. 210 | See https://github.com/tcort/markdown-link-check#config-file-format for details. 211 | 212 | Or mark 429 status code as alive: 213 | ```json 214 | { 215 | "aliveStatusCodes": [429, 200] 216 | } 217 | ``` 218 | 219 | ### GitHub links failure fix 220 | Use the following `httpHeaders` in your custom configuration file to fix GitHub links failure. 221 | 222 | ```json 223 | { 224 | "httpHeaders": [ 225 | { 226 | "urls": ["https://github.com/", "https://guides.github.com/", "https://help.github.com/", "https://docs.github.com/"], 227 | "headers": { 228 | "Accept-Encoding": "zstd, br, gzip, deflate" 229 | } 230 | } 231 | ] 232 | } 233 | ``` 234 | 235 | ## Example Usage 236 | 237 | Consider a workflow file that checks for the status of hyperlinks on push to the master branch, 238 | 239 | ``` yml 240 | name: Check .md links 241 | 242 | on: 243 | push: [master] 244 | 245 | jobs: 246 | markdown-link-check: 247 | runs-on: ubuntu-latest 248 | # check out the latest version of the code 249 | steps: 250 | - uses: actions/checkout@v3 251 | 252 | # Checks the status of hyperlinks in .md files in verbose mode 253 | - name: Check links 254 | uses: gaurav-nelson/github-action-markdown-link-check@v1 255 | with: 256 | use-verbose-mode: 'yes' 257 | ``` 258 | A file `test.md` exists, containing 259 | 260 | ![image](https://user-images.githubusercontent.com/53875297/159135478-87194037-f3d6-4ca9-9da8-f01dac482fbc.png) 261 | 262 | On running the workflow described above, the output shown below is obtained 263 | 264 | ![image](https://user-images.githubusercontent.com/53875297/159135426-9f439d39-8bb3-40f0-9255-9efe2b493c1a.png) 265 | 266 | 267 | ## Versioning 268 | GitHub Action - Markdown link check follows the [GitHub recommended versioning strategy](https://github.com/actions/toolkit/blob/master/docs/action-versioning.md). 269 | 270 | 1. To use a specific released version of the action ([Releases](https://github.com/gaurav-nelson/github-action-markdown-link-check/releases)): 271 | ```yml 272 | - uses: gaurav-nelson/github-action-markdown-link-check@1.0.1 273 | ``` 274 | 1. To use a major version of the action: 275 | ```yml 276 | - uses: gaurav-nelson/github-action-markdown-link-check@v1 277 | ``` 278 | 1. You can also specify a [specific commit SHA](https://github.com/gaurav-nelson/github-action-markdown-link-check/commits/master) as an action version: 279 | ```yml 280 | - uses: gaurav-nelson/github-action-markdown-link-check@44a942b2f7ed0dc101d556f281e906fb79f1f478 281 | ``` 282 | 283 |
284 |

285 | 286 | Buy me a coffee. 287 | 288 |

289 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: 'markdown-link-check' 2 | description: 'Check if all links are valid in markdown files.' 3 | author: 'Gaurav Nelson' 4 | branding: 5 | icon: 'link' 6 | color: 'green' 7 | inputs: 8 | use-quiet-mode: 9 | description: 'Use yes to enable markdown-link-check quiet mode which only list errors.' 10 | required: true 11 | default: 'no' 12 | use-verbose-mode: 13 | description: 'Use yes to enable markdown-link-check verbose mode which lists additional details.' 14 | required: true 15 | default: 'no' 16 | config-file: 17 | description: 'Specify path to a markdown-link-check JSON configuration file.' 18 | required: true 19 | default: 'mlc_config.json' 20 | folder-path: 21 | description: 'Specify path to a custom folder where your markdown files are located.' 22 | required: true 23 | default: '.' 24 | max-depth: 25 | description: 'Specify a max-depth of directories you want to search for markdown files.' 26 | required: true 27 | default: '-1' 28 | check-modified-files-only: 29 | description: 'Use yes to only check for modified markdown files instead of checking all markdown files.' 30 | required: true 31 | default: 'no' 32 | base-branch: 33 | description: 'Use this to specify the base branch against which the action finds the modififed files.' 34 | required: true 35 | default: 'master' 36 | file-extension: 37 | description: 'Use this to specify the file extension of Markdown files.' 38 | required: true 39 | default: '.md' 40 | file-path: 41 | description: 'Specify additional files you want to check' 42 | required: true 43 | default: '' 44 | 45 | runs: 46 | using: 'docker' 47 | image: 'Dockerfile' 48 | args: 49 | - ${{ inputs.use-quiet-mode }} 50 | - ${{ inputs.use-verbose-mode }} 51 | - ${{ inputs.config-file }} 52 | - ${{ inputs.folder-path }} 53 | - ${{ inputs.max-depth }} 54 | - ${{ inputs.check-modified-files-only }} 55 | - ${{ inputs.base-branch }} 56 | - ${{ inputs.file-extension }} 57 | - ${{ inputs.file-path }} 58 | -------------------------------------------------------------------------------- /entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eu 4 | 5 | NC='\033[0m' # No Color 6 | GREEN='\033[0;32m' 7 | YELLOW='\033[0;33m' 8 | BLUE='\033[0;34m' 9 | RED='\033[0;31m' 10 | 11 | npm i -g markdown-link-check@3.13.7 12 | echo "::group::Debug information" 13 | npm -g list --depth=1 14 | echo "::endgroup::" 15 | 16 | declare -a FIND_CALL 17 | declare -a COMMAND_DIRS COMMAND_FILES 18 | declare -a COMMAND_FILES 19 | 20 | USE_QUIET_MODE="$1" 21 | USE_VERBOSE_MODE="$2" 22 | CONFIG_FILE="$3" 23 | FOLDER_PATH="$4" 24 | MAX_DEPTH="$5" 25 | CHECK_MODIFIED_FILES="$6" 26 | BASE_BRANCH="$7" 27 | 28 | if [ -z "$8" ]; then 29 | FILE_EXTENSION=".md" 30 | else 31 | FILE_EXTENSION="$8" 32 | fi 33 | FILE_PATH="$9" 34 | 35 | if [ -f "$CONFIG_FILE" ]; then 36 | echo -e "${BLUE}Using markdown-link-check configuration file: ${YELLOW}$CONFIG_FILE${NC}" 37 | else 38 | echo -e "${BLUE}Cannot find ${YELLOW}$CONFIG_FILE${NC}" 39 | echo -e "${YELLOW}NOTE: See https://github.com/tcort/markdown-link-check#config-file-format to know more about" 40 | echo -e "customizing markdown-link-check by using a configuration file.${NC}" 41 | fi 42 | 43 | FOLDERS="" 44 | FILES="" 45 | 46 | echo -e "${BLUE}USE_QUIET_MODE: $1${NC}" 47 | echo -e "${BLUE}USE_VERBOSE_MODE: $2${NC}" 48 | echo -e "${BLUE}FOLDER_PATH: $4${NC}" 49 | echo -e "${BLUE}MAX_DEPTH: $5${NC}" 50 | echo -e "${BLUE}CHECK_MODIFIED_FILES: $6${NC}" 51 | echo -e "${BLUE}FILE_EXTENSION: $8${NC}" 52 | echo -e "${BLUE}FILE_PATH: $9${NC}" 53 | 54 | handle_dirs () { 55 | 56 | IFS=', ' read -r -a DIRLIST <<< "$FOLDER_PATH" 57 | 58 | for index in "${!DIRLIST[@]}" 59 | do 60 | if [ ! -d "${DIRLIST[index]}" ]; then 61 | echo -e "${RED}ERROR [✖] Can't find the directory: ${YELLOW}${DIRLIST[index]}${NC}" 62 | exit 2 63 | fi 64 | COMMAND_DIRS+=("${DIRLIST[index]}") 65 | done 66 | FOLDERS="${COMMAND_DIRS[*]}" 67 | 68 | } 69 | 70 | handle_files () { 71 | 72 | IFS=', ' read -r -a FILELIST <<< "$FILE_PATH" 73 | 74 | for index in "${!FILELIST[@]}" 75 | do 76 | if [ ! -f "${FILELIST[index]}" ]; then 77 | echo -e "${RED}ERROR [✖] Can't find the file: ${YELLOW}${FILELIST[index]}${NC}" 78 | exit 2 79 | fi 80 | if [ "$index" == 0 ]; then 81 | COMMAND_FILES+=("-wholename ${FILELIST[index]}") 82 | else 83 | COMMAND_FILES+=("-o -wholename ${FILELIST[index]}") 84 | fi 85 | done 86 | FILES="${COMMAND_FILES[*]}" 87 | 88 | } 89 | 90 | check_errors () { 91 | 92 | if [ -e error.txt ] ; then 93 | if grep -q "ERROR:" error.txt; then 94 | echo -e "${YELLOW}=========================> MARKDOWN LINK CHECK <=========================${NC}" 95 | cat error.txt 96 | printf "\n" 97 | echo -e "${YELLOW}=========================================================================${NC}" 98 | echo "MLC_OUTPUT<> "$GITHUB_ENV" 99 | cat error.txt >> "$GITHUB_ENV" 100 | echo "EOF" >> "$GITHUB_ENV" 101 | exit 113 102 | else 103 | echo -e "${YELLOW}=========================> MARKDOWN LINK CHECK <=========================${NC}" 104 | printf "\n" 105 | echo -e "${GREEN}[✔] All links are good!${NC}" 106 | printf "\n" 107 | echo -e "${YELLOW}=========================================================================${NC}" 108 | echo "MLC_OUTPUT=[✔] All links are good!" >> "$GITHUB_OUTPUT" 109 | fi 110 | else 111 | echo -e "${GREEN}All good!${NC}" 112 | echo "MLC_OUTPUT=All good!" >> "$GITHUB_OUTPUT" 113 | fi 114 | 115 | } 116 | 117 | add_options () { 118 | 119 | if [ -f "$CONFIG_FILE" ]; then 120 | FIND_CALL+=('--config' "${CONFIG_FILE}") 121 | fi 122 | 123 | if [ "$USE_QUIET_MODE" = "yes" ]; then 124 | FIND_CALL+=('-q') 125 | fi 126 | 127 | if [ "$USE_VERBOSE_MODE" = "yes" ]; then 128 | FIND_CALL+=('-v') 129 | fi 130 | 131 | } 132 | 133 | check_additional_files () { 134 | 135 | if [ -n "$FILES" ]; then 136 | if [ "$MAX_DEPTH" -ne -1 ]; then 137 | FIND_CALL=('find' ${FOLDERS} '-type' 'f' '(' ${FILES} ')' '-not' '-path' './node_modules/*' '-maxdepth' "${MAX_DEPTH}" '-exec' 'markdown-link-check' '{}') 138 | else 139 | FIND_CALL=('find' ${FOLDERS} '-type' 'f' '(' ${FILES} ')' '-not' '-path' './node_modules/*' '-exec' 'markdown-link-check' '{}') 140 | fi 141 | 142 | add_options 143 | 144 | FIND_CALL+=(';') 145 | 146 | set -x 147 | "${FIND_CALL[@]}" &>> error.txt 148 | set +x 149 | 150 | fi 151 | 152 | } 153 | 154 | if [ -z "$8" ]; then 155 | FOLDERS="." 156 | else 157 | handle_dirs 158 | fi 159 | 160 | if [ -n "$9" ]; then 161 | handle_files 162 | fi 163 | 164 | if [ "$CHECK_MODIFIED_FILES" = "yes" ]; then 165 | 166 | echo -e "${BLUE}BASE_BRANCH: $7${NC}" 167 | 168 | git config --global --add safe.directory '*' 169 | 170 | git fetch origin "${BASE_BRANCH}" --depth=1 > /dev/null 171 | MASTER_HASH=$(git rev-parse origin/"${BASE_BRANCH}") 172 | 173 | if [ -z "$FOLDERS" ]; then 174 | FOLDERS="." 175 | fi 176 | 177 | FIND_CALL=('markdown-link-check') 178 | 179 | add_options 180 | 181 | FOLDER_ARRAY=(${FOLDER_PATH//,/ }) 182 | mapfile -t FILE_ARRAY < <( git diff --name-only --diff-filter=AM "$MASTER_HASH" -- "${FOLDER_ARRAY[@]}") 183 | 184 | for i in "${FILE_ARRAY[@]}" 185 | do 186 | if [ "${i##*.}" == "${FILE_EXTENSION#.}" ]; then 187 | FIND_CALL+=("${i}") 188 | COMMAND="${FIND_CALL[*]}" 189 | $COMMAND &>> error.txt || true 190 | unset 'FIND_CALL[${#FIND_CALL[@]}-1]' 191 | fi 192 | done 193 | 194 | check_additional_files 195 | 196 | check_errors 197 | 198 | else 199 | 200 | if [ "$5" -ne -1 ]; then 201 | FIND_CALL=('find' ${FOLDERS} '-name' '*'"${FILE_EXTENSION}" '-not' '-path' './node_modules/*' '-maxdepth' "${MAX_DEPTH}" '-exec' 'markdown-link-check' '{}') 202 | else 203 | FIND_CALL=('find' ${FOLDERS} '-name' '*'"${FILE_EXTENSION}" '-not' '-path' './node_modules/*' '-exec' 'markdown-link-check' '{}') 204 | fi 205 | 206 | add_options 207 | 208 | FIND_CALL+=(';') 209 | 210 | set -x 211 | "${FIND_CALL[@]}" &>> error.txt 212 | set +x 213 | 214 | check_additional_files 215 | 216 | check_errors 217 | 218 | fi 219 | -------------------------------------------------------------------------------- /md/AdditionalFileTest1.md: -------------------------------------------------------------------------------- 1 | # AdditionalFileTest1 2 | 3 | ## Test 4 | 5 | Go to [AdditionalFileTest2](./AdditionalFileTest2.md#test) 6 | 7 | -------------------------------------------------------------------------------- /md/AdditionalFileTest2.md: -------------------------------------------------------------------------------- 1 | # AdditionalFileTest2 2 | 3 | ## Test 4 | 5 | Go to [AdditionalFileTest1](./AdditionalFileTest1.md#test) 6 | 7 | -------------------------------------------------------------------------------- /md/dir1/dir1level2/level-2a.md: -------------------------------------------------------------------------------- 1 | 2 | ## Test internal and external links 3 | 4 | www.google.com 5 | 6 | [This is a broken link](https://www.exampleexample.cox) 7 | 8 | [This is another broken link](http://ignored-domain.com) but its ignored using a 9 | configuration file. 10 | 11 | ### Alpha 12 | 13 | This [exists](#alpha). 14 | This [one does not](#does-not). 15 | References and definitions are [checked][alpha] [too][charlie]. 16 | 17 | ### Bravo 18 | 19 | Headings in `readme.md` are [not checked](file1.md#bravo). 20 | But [missing files are reported](missing-example.js). 21 | 22 | [alpha]: #alpha 23 | [charlie]: #charlie 24 | 25 | External file: [Charlie](./file2.md/#charlie) -------------------------------------------------------------------------------- /md/dir1/dir1level2/level-2b.md: -------------------------------------------------------------------------------- 1 | # Checking more links 2 | 3 | ## Bravo 4 | 5 | This [doesn't exists](#alpha). 6 | This [one does](#bravo). 7 | 8 | ## Charlie 9 | 10 | This is linked from file1. -------------------------------------------------------------------------------- /md/dir1/level-1a.md: -------------------------------------------------------------------------------- 1 | 2 | ## Test internal and external links 3 | 4 | www.google.com 5 | 6 | [This is a broken link](https://www.exampleexample.cox) 7 | 8 | [This is another broken link](http://ignored-domain.com) but its ignored using a 9 | configuration file. 10 | 11 | ### Alpha 12 | 13 | This [exists](#alpha). 14 | This [one does not](#does-not). 15 | References and definitions are [checked][alpha] [too][charlie]. 16 | 17 | ### Bravo 18 | 19 | Headings in `readme.md` are [not checked](file1.md#bravo). 20 | But [missing files are reported](missing-example.js). 21 | 22 | [alpha]: #alpha 23 | [charlie]: #charlie 24 | 25 | External file: [Charlie](./file2.md/#charlie) -------------------------------------------------------------------------------- /md/dir1/level-1b.md: -------------------------------------------------------------------------------- 1 | # Checking more links 2 | 3 | ## Bravo 4 | 5 | This [doesn't exists](#alpha). 6 | This [one does](#bravo). 7 | 8 | ## Charlie 9 | 10 | This is linked from file1. -------------------------------------------------------------------------------- /md/dir2/dir2level2/level-2a.md: -------------------------------------------------------------------------------- 1 | 2 | ## Test internal and external links 3 | 4 | www.google.com 5 | 6 | [This is a broken link](https://www.exampleexample.cox) 7 | 8 | [This is another broken link](http://ignored-domain.com) but its ignored using a 9 | configuration file. 10 | 11 | ### Alpha 12 | 13 | This [exists](#alpha). 14 | This [one does not](#does-not). 15 | References and definitions are [checked][alpha] [too][charlie]. 16 | 17 | ### Bravo 18 | 19 | Headings in `readme.md` are [not checked](file1.md#bravo). 20 | But [missing files are reported](missing-example.js). 21 | 22 | [alpha]: #alpha 23 | [charlie]: #charlie 24 | 25 | External file: [Charlie](./file2.md/#charlie) -------------------------------------------------------------------------------- /md/dir2/dir2level2/level-2b.md: -------------------------------------------------------------------------------- 1 | # Checking more links 2 | 3 | ## Bravo 4 | 5 | This [doesn't exists](#alpha). 6 | This [one does](#bravo). 7 | 8 | ## Charlie 9 | 10 | This is linked from file1. -------------------------------------------------------------------------------- /md/dir2/level-1a.md: -------------------------------------------------------------------------------- 1 | 2 | ## Test internal and external links 3 | 4 | www.google.com 5 | 6 | [This is a broken link](https://www.exampleexample.cox) 7 | 8 | [This is another broken link](http://ignored-domain.com) but its ignored using a 9 | configuration file. 10 | 11 | ### Alpha 12 | 13 | This [exists](#alpha). 14 | This [one does not](#does-not). 15 | References and definitions are [checked][alpha] [too][charlie]. 16 | 17 | ### Bravo 18 | 19 | Headings in `readme.md` are [not checked](file1.md#bravo). 20 | But [missing files are reported](missing-example.js). 21 | 22 | [alpha]: #alpha 23 | [charlie]: #charlie 24 | 25 | External file: [Charlie](./file2.md/#charlie) 26 | 27 | Modified. -------------------------------------------------------------------------------- /md/dir2/level-1b.md: -------------------------------------------------------------------------------- 1 | # Checking more links 2 | 3 | ## Bravo 4 | 5 | This [doesn't exists](#alpha). 6 | This [one does](#bravo). 7 | 8 | ## Charlie 9 | 10 | This is linked from file1. -------------------------------------------------------------------------------- /md/dir3/dir3level2/level-2a.md: -------------------------------------------------------------------------------- 1 | 2 | ## Test internal and external links 3 | 4 | www.google.com 5 | 6 | [This is a broken link](https://www.exampleexample.cox) 7 | 8 | [This is another broken link](http://ignored-domain.com) but its ignored using a 9 | configuration file. 10 | 11 | ### Alpha 12 | 13 | This [exists](#alpha). 14 | This [one does not](#does-not). 15 | References and definitions are [checked][alpha] [too][charlie]. 16 | 17 | ### Bravo 18 | 19 | Headings in `readme.md` are [not checked](file1.md#bravo). 20 | But [missing files are reported](missing-example.js). 21 | 22 | [alpha]: #alpha 23 | [charlie]: #charlie 24 | 25 | External file: [Charlie](./file2.md/#charlie) -------------------------------------------------------------------------------- /md/dir3/dir3level2/level-2b.md: -------------------------------------------------------------------------------- 1 | # Checking more links 2 | 3 | ## Bravo 4 | 5 | This [doesn't exists](#alpha). 6 | This [one does](#bravo). 7 | 8 | ## Charlie 9 | 10 | This is linked from file1. -------------------------------------------------------------------------------- /md/dir3/level-1b.md: -------------------------------------------------------------------------------- 1 | # Checking more links 2 | 3 | ## Bravo 4 | 5 | This [doesn't exists](#alpha). 6 | This [one does](#bravo). 7 | 8 | ## Charlie 9 | 10 | This is linked from file1. www.samplefailfailfail.co -------------------------------------------------------------------------------- /md/dir4/ok4.md: -------------------------------------------------------------------------------- 1 | # Ok4 2 | 3 | ## Test 4 | 5 | Go to [Ok5](../dir5/ok5.md#test) 6 | 7 | -------------------------------------------------------------------------------- /md/dir5/ok5.md: -------------------------------------------------------------------------------- 1 | # Ok5 2 | 3 | ## Test 4 | 5 | Go to [Ok4](../dir4/ok4.md#test) 6 | 7 | -------------------------------------------------------------------------------- /md/file1.md: -------------------------------------------------------------------------------- 1 | 2 | ## Test internal and external links 3 | 4 | www.google.com 5 | 6 | 7 | [This is a broken link](https://www.exampleexample.cox) 8 | 9 | [This is another broken link](http://ignored-domain.com) but its ignored using a 10 | configuration file. 11 | 12 | This is to test URLencoding. 13 | 14 | 15 | 16 | ### Alpha 17 | 18 | This [exists](#alpha). 19 | 20 | This [one does not](#does-not). 21 | References and definitions are [checked][alpha]. 22 | 23 | ### Bravo 24 | 25 | Headings in `readme.md` are [not checked](file1.md#bravo). 26 | 27 | But [missing files are reported](missing-example.js). 28 | 29 | [alpha]: #alpha 30 | -------------------------------------------------------------------------------- /md/file2.md: -------------------------------------------------------------------------------- 1 | # Checking more links 2 | 3 | ## Bravo 4 | 5 | This [doesn't exists](#alpha). 6 | This [one does](#bravo). 7 | 8 | ## Charlie 9 | 10 | This is linked from file1. 11 | 12 | ## change -------------------------------------------------------------------------------- /md/file3.markdown: -------------------------------------------------------------------------------- 1 | 2 | ## Test internal and external links 3 | 4 | www.google.com 5 | 6 | 7 | [This is a broken link](https://www.exampleexample.cox) 8 | 9 | [This is another broken link](http://ignored-domain.com) but its ignored using a 10 | configuration file. 11 | 12 | ### Delta 13 | 14 | This [exists](#delta). 15 | 16 | This [one does not](#does-not). 17 | References and definitions are [checked][delta]. 18 | 19 | ### Echo 20 | 21 | Headings in `readme.md` are [not checked](file3.markdown#echo). 22 | 23 | But [missing files are reported](missing-example.js). 24 | 25 | [delta]: #delta 26 | -------------------------------------------------------------------------------- /md/file4.markdown: -------------------------------------------------------------------------------- 1 | # Checking more links 2 | 3 | ## Echo 4 | 5 | This [doesn't exists](#alpha). 6 | This [one does](#echo). 7 | 8 | ## Foxtrot 9 | 10 | This is linked from file3. 11 | 12 | ## change -------------------------------------------------------------------------------- /mlc_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "ignorePatterns": [ 3 | { 4 | "pattern": "^http://ignored-domain.com" 5 | } 6 | ] 7 | } --------------------------------------------------------------------------------