Skip to content

[pull] main from mdn:main #7510

[pull] main from mdn:main

[pull] main from mdn:main #7510

name: Lint content
on:
pull_request:
paths:
- .github/workflows/pr-check-lint_content.yml
- .nvmrc
- "*.md"
- "files/**/*.md"
permissions:
contents: read
concurrency:
group: ci-${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number }}
cancel-in-progress: true
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Get changed files
id: check
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
# Use the GitHub API to get the list of changed files
# documentation: https://docs.github.com/rest/commits/commits#compare-two-commits
# Get files as newline-separated list
FILTERED_FILES=$(gh api repos/{owner}/{repo}/compare/${BASE_SHA}...${HEAD_SHA} \
--jq '.files | .[] | select(.status|IN("added", "modified", "renamed", "copied", "changed")) | .filename' | \
egrep -i "^.*\.md$" || true)
# Store as multiline output
EOF="$(openssl rand -hex 8)"
echo "DIFF_DOCUMENTS<<${EOF}" >> "$GITHUB_OUTPUT"
echo "${FILTERED_FILES}" >> "$GITHUB_OUTPUT"
echo "${EOF}" >> "$GITHUB_OUTPUT"
# Also set a simple flag for whether we have files
if [ -n "${FILTERED_FILES// /}" ]; then # Remove all spaces and check if anything remains
echo "HAS_FILES=true" >> "$GITHUB_OUTPUT"
else
echo "HAS_FILES=false" >> "$GITHUB_OUTPUT"
fi
- name: Setup Node.js environment
if: steps.check.outputs.HAS_FILES == 'true'
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version-file: ".nvmrc"
cache: npm
- name: Install
if: steps.check.outputs.HAS_FILES == 'true'
run: npm ci
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check CRLF line endings
id: crlf
if: steps.check.outputs.HAS_FILES == 'true'
env:
DIFF_DOCUMENTS: ${{ steps.check.outputs.DIFF_DOCUMENTS }}
run: |
EOF="$(openssl rand -hex 8)"
readarray -t files_to_lint <<< "$DIFF_DOCUMENTS"
printf "Files to process (%d files):\n" "${#files_to_lint[@]}"
printf "'%s'\n" "${files_to_lint[@]}"
CRLF_FAILED=true
CRLF_LOG=$(git ls-files --eol "${files_to_lint[@]}" | grep -E 'w/(mixed|crlf)') || CRLF_FAILED=false
echo "CRLF_LOG<<${EOF}" >> "$GITHUB_OUTPUT"
echo "${CRLF_LOG}" >> "$GITHUB_OUTPUT"
echo "${EOF}" >> "$GITHUB_OUTPUT"
echo "CRLF_FAILED=${CRLF_FAILED}" >> "$GITHUB_OUTPUT"
- name: Diff
if: steps.check.outputs.HAS_FILES == 'true'
run: |
git status
git diff HEAD --color=always --word-diff --word-diff-regex='[[:alnum:]_]+'
- name: Run markdownlint
id: markdownlint
if: steps.check.outputs.HAS_FILES == 'true'
env:
DIFF_DOCUMENTS: ${{ steps.check.outputs.DIFF_DOCUMENTS }}
run: |
EOF="$(openssl rand -hex 8)"
readarray -t files_to_lint <<< "$DIFF_DOCUMENTS"
MD_LINT_FAILED=false
MD_LINT_LOG=$(npx markdownlint-cli2 --fix "${files_to_lint[@]}" 2>&1) || MD_LINT_FAILED=true
echo "MD_LINT_LOG<<${EOF}" >> "$GITHUB_OUTPUT"
echo "${MD_LINT_LOG}" >> "$GITHUB_OUTPUT"
echo "${EOF}" >> "$GITHUB_OUTPUT"
echo "MD_LINT_FAILED=${MD_LINT_FAILED}" >> "$GITHUB_OUTPUT"
- name: Diff
if: steps.check.outputs.HAS_FILES == 'true'
run: |
git status
git diff HEAD --color=always --word-diff --word-diff-regex='[[:alnum:]_]+'
- name: Lint front-matter
id: frontmatter
if: steps.check.outputs.HAS_FILES == 'true'
env:
DIFF_DOCUMENTS: ${{ steps.check.outputs.DIFF_DOCUMENTS }}
run: |
EOF="$(openssl rand -hex 8)"
readarray -t files_to_lint <<< "$DIFF_DOCUMENTS"
FM_LINT_FAILED=false
FM_LINT_LOG=$(node scripts/front-matter_linter.js --fix true "${files_to_lint[@]}" 2>&1) || FM_LINT_FAILED=true
echo "FM_LINT_LOG<<${EOF}" >> "$GITHUB_OUTPUT"
echo "${FM_LINT_LOG}" >> "$GITHUB_OUTPUT"
echo "${EOF}" >> "$GITHUB_OUTPUT"
echo "FM_LINT_FAILED=${FM_LINT_FAILED}" >> "$GITHUB_OUTPUT"
- name: Diff
if: steps.check.outputs.HAS_FILES == 'true'
run: |
git status
git diff HEAD --color=always --word-diff --word-diff-regex='[[:alnum:]_]+'
- name: Run Prettier
id: prettier
if: steps.check.outputs.HAS_FILES == 'true'
env:
DIFF_DOCUMENTS: ${{ steps.check.outputs.DIFF_DOCUMENTS }}
run: |
EOF="$(openssl rand -hex 8)"
readarray -t files_to_lint <<< "$DIFF_DOCUMENTS"
PRETTIER_FAILED=false
PRETTIER_LOG=$(npx prettier --check "${files_to_lint[@]}" 2>&1) || PRETTIER_FAILED=true
echo "PRETTIER_LOG<<${EOF}" >> "$GITHUB_OUTPUT"
echo "${PRETTIER_LOG}" >> "$GITHUB_OUTPUT"
echo "${EOF}" >> "$GITHUB_OUTPUT"
echo "PRETTIER_FAILED=${PRETTIER_FAILED}" >> "$GITHUB_OUTPUT"
npx prettier -w "${files_to_lint[@]}"
- name: Diff
id: lint-diff
if: always() && steps.check.outputs.HAS_FILES == 'true'
run: |
git status
git diff HEAD --color=always --word-diff --word-diff-regex='[[:alnum:]_]+'
if [[ -n $(git diff) ]]; then
echo "FILES_MODIFIED=true" >> "$GITHUB_OUTPUT"
fi
- name: Collect artifact files
if: always() && steps.check.outputs.HAS_FILES == 'true'
env:
FILES_MODIFIED: ${{ steps.lint-diff.outputs.FILES_MODIFIED }}
MD_LINT_FAILED: ${{ steps.markdownlint.outputs.MD_LINT_FAILED }}
MD_LINT_LOG: ${{ steps.markdownlint.outputs.MD_LINT_LOG }}
run: |
rm -rf lint-results
mkdir -p lint-results
if [[ "$FILES_MODIFIED" == 'true' ]]; then
git diff HEAD > lint-results/lint.diff
fi
if [[ "$MD_LINT_FAILED" == 'true' ]]; then
echo "$MD_LINT_LOG" > lint-results/markdownlint.log
fi
- name: Upload artifact
if: always() && steps.check.outputs.HAS_FILES == 'true' && hashFiles('lint-results/*') != ''
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: lint-results
path: lint-results
- name: Fail if any issues pending
if: steps.lint-diff.outputs.FILES_MODIFIED == 'true' || steps.crlf.outputs.CRLF_FAILED == 'true' || steps.markdownlint.outputs.MD_LINT_FAILED == 'true' || steps.frontmatter.outputs.FM_LINT_FAILED == 'true'
env:
CRLF_FAILED: ${{ steps.crlf.outputs.CRLF_FAILED }}
MD_LINT_FAILED: ${{ steps.markdownlint.outputs.MD_LINT_FAILED }}
FM_LINT_FAILED: ${{ steps.frontmatter.outputs.FM_LINT_FAILED }}
PRETTIER_FAILED: ${{ steps.prettier.outputs.PRETTIER_FAILED }}
CRLF_LOG: ${{ steps.crlf.outputs.CRLF_LOG }}
MD_LINT_LOG: ${{ steps.markdownlint.outputs.MD_LINT_LOG }}
FM_LINT_LOG: ${{ steps.frontmatter.outputs.FM_LINT_LOG }}
PRETTIER_LOG: ${{ steps.prettier.outputs.PRETTIER_LOG }}
run: |
echo -e "\nPlease fix all the linting issues mentioned in the following logs and in the PR review comments."
if [[ ${CRLF_FAILED} == 'true' ]]; then
echo -e "\n\n🪵 In the following files make sure all the lines end with only Line Feed (LF) character and not with Carriage Return Line Feed (CRLF) characters:"
echo "${CRLF_LOG}"
echo "For more information refer https://gist.github.com/LunarLambda/3df0840b336a5e314e4ffdac03cbf619 ."
echo "You may use https://app.execeratics.com/LFandCRLFonline/?l=en online tool to convert line endings from CRLF to LF."
fi
if [[ ${MD_LINT_FAILED} == 'true' ]]; then
echo -e "\n\n🪵 Logs from markdownlint:"
echo "${MD_LINT_LOG}"
fi
if [[ ${FM_LINT_FAILED} == 'true' ]]; then
echo -e "\n\n🪵 Logs from front-matter linter:"
echo "${FM_LINT_LOG}"
fi
if [[ ${PRETTIER_FAILED} == 'true' ]]; then
echo -e "\n\n🪵 Logs from Prettier formatter:"
echo "${PRETTIER_LOG}"
echo -e "\nYou can use Prettier playground to format the files online (configuration pre-filled): https://prettier.io/playground/#N4Igxg9gdgLgprEAuEBiABABwIYGd7owAWc6CMAlgE6kBmFANqSTSADQgSaXS7KjYqVCAHcACoIR8U2BiOwBPPhwBGVbGADWcGAGVsAWzgAZClDjIYVAK5xV6rTt04wZgOaWbdkLjgGKnrYccAAemHBUFEawsgAqEVCCFHDStLK+HLjuTACK1hDwyGkMGSAAVrghutlweQUWSMWlAI758GLCmNIgeAC05nAAJkPsIFbYjO4AwhAGBtjIPQwMo1lQbkwAgjBWFCrW7RGm5kXp3kQwBgwA6kQU8LgucLpS9xQAbvcKi2C4yiDvWwASSgw1gujAkW4m1BuhgCiYpxK3kwwl813UmEWqJSEXeFg4Zl8VBgHWwbnmSNKOCoxMW8yomkGoigo1RZhg1wog2IyAAHAAGDg0VrUOBkikLRpnDgwbAqLk8ojIABMHGsvli8tSMpAfhUQ2Gg2M2HW1nJcAAYhAqPMdu5FtgDhAQABfV1AA \n"
fi
exit 1