name: Test mkdlint Action
on:
push:
paths:
- '.github/actions/mkdlint/**'
- '.github/workflows/test-action.yml'
pull_request:
paths:
- '.github/actions/mkdlint/**'
- '.github/workflows/test-action.yml'
workflow_dispatch:
permissions:
contents: read
security-events: write
jobs:
test-binary-download:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
version: [latest, '0.11.0']
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Test binary download
id: test
uses: ./.github/actions/mkdlint
with:
files: 'README.md'
version: ${{ matrix.version }}
use-binary: true
upload-sarif: false
fail-on-error: false
- name: Verify outputs
shell: bash
run: |
echo "Exit code: ${{ steps.test.outputs.exit-code }}"
echo "Error count: ${{ steps.test.outputs.error-count }}"
echo "File count: ${{ steps.test.outputs.file-count }}"
echo "Binary path: ${{ steps.test.outputs.binary-path }}"
echo "Cache hit: ${{ steps.test.outputs.cache-hit }}"
if [ ! -f "${{ steps.test.outputs.binary-path }}" ]; then
echo "Error: Binary not found at ${{ steps.test.outputs.binary-path }}"
exit 1
fi
- name: Test cache hit on second run
id: test2
uses: ./.github/actions/mkdlint
with:
files: 'README.md'
version: ${{ matrix.version }}
use-binary: true
upload-sarif: false
fail-on-error: false
- name: Verify cache was used
shell: bash
run: |
echo "Cache hit on second run: ${{ steps.test2.outputs.cache-hit }}"
# First run might not have cache, but second run should
# (unless it's a fresh runner or different version)
test-cargo-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Test cargo build
id: test
uses: ./.github/actions/mkdlint
with:
files: 'README.md'
use-binary: false
upload-sarif: false
fail-on-error: false
- name: Verify binary was built
run: |
if [ ! -f "${{ steps.test.outputs.binary-path }}" ]; then
echo "Error: Binary not found after cargo build"
exit 1
fi
${{ steps.test.outputs.binary-path }} --version
test-sarif-upload:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Create test markdown with issues
run: |
mkdir -p test-docs
cat > test-docs/test.md << 'MDEOF'
# Test Document
This is a test.
Multiple blank lines above.
## Setup
Content here.
## Setup
Duplicate heading.
MDEOF
- name: Run with SARIF output
id: sarif
uses: ./.github/actions/mkdlint
with:
files: 'test-docs/'
output-format: sarif
sarif-file: results.sarif
upload-sarif: true
fail-on-error: false
- name: Verify SARIF file exists
run: |
if [ ! -f "results.sarif" ]; then
echo "Error: SARIF file not created"
exit 1
fi
# Verify it's valid JSON
jq . results.sarif > /dev/null
# Show SARIF structure
echo "SARIF file created successfully:"
jq '.runs[0].results | length' results.sarif
- name: Upload SARIF as artifact
uses: actions/upload-artifact@v4
with:
name: sarif-results
path: results.sarif
test-auto-fix:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Create test file with fixable issues
run: |
mkdir -p test-fix
cat > test-fix/fixable.md << 'MDEOF'
#No space after hash
Trailing spaces here:
Multiple trailing spaces:
- Item 1
- Item 2 (extra space)
- Item 3
MDEOF
- name: Run with auto-fix
uses: ./.github/actions/mkdlint
with:
files: 'test-fix/'
fix: true
fail-on-error: false
upload-sarif: false
- name: Verify fixes were applied
run: |
cat test-fix/fixable.md
# Check that heading now has space
if ! grep -q "^# No space" test-fix/fixable.md; then
echo "Error: Heading not fixed"
exit 1
fi
echo "Auto-fix succeeded!"
test-custom-config:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Create custom config
run: |
mkdir -p test-config
cat > test-config/.markdownlint.json << 'JSONEOF'
{
"default": true,
"MD013": false,
"MD033": false
}
JSONEOF
cat > test-config/test.md << 'MDEOF'
# Test
This line is very long and would normally fail MD013 line-length rule but we disabled it in config.
<div>HTML is normally not allowed but MD033 is disabled</div>
MDEOF
- name: Run with custom config
id: config
uses: ./.github/actions/mkdlint
with:
files: 'test-config/test.md'
config: 'test-config/.markdownlint.json'
upload-sarif: false
fail-on-error: true
- name: Verify no errors with custom config
run: |
if [ "${{ steps.config.outputs.error-count }}" != "0" ]; then
echo "Error: Custom config not respected"
exit 1
fi
test-disable-rules:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Create test file
run: |
mkdir -p test-disable
cat > test-disable/test.md << 'MDEOF'
# Test
This line is very long and exceeds the default line length limit of 80 characters which should trigger MD013.
<div>This HTML should trigger MD033</div>
MDEOF
- name: Run with disabled rules
id: disable
uses: ./.github/actions/mkdlint
with:
files: 'test-disable/'
disable: 'MD013,MD033'
upload-sarif: false
fail-on-error: true
- name: Verify rules were disabled
run: |
if [ "${{ steps.disable.outputs.error-count }}" != "0" ]; then
echo "Error: Rules not disabled correctly"
exit 1
fi
test-ignore-patterns:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Create test structure
run: |
mkdir -p test-ignore/node_modules test-ignore/src
echo "#Bad heading" > test-ignore/node_modules/test.md
echo "# Good heading" > test-ignore/src/test.md
- name: Run with ignore patterns
id: ignore
uses: ./.github/actions/mkdlint
with:
files: 'test-ignore/'
ignore: '**/node_modules/**'
upload-sarif: false
fail-on-error: false
- name: Verify ignored files were skipped
run: |
echo "Errors found: ${{ steps.ignore.outputs.error-count }}"
# node_modules/test.md should be ignored, only src/test.md should be checked
test-fail-on-error:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Create file with errors
run: |
mkdir -p test-fail
echo "#No space" > test-fail/bad.md
- name: Test fail-on-error true (should fail)
id: fail_true
continue-on-error: true
uses: ./.github/actions/mkdlint
with:
files: 'test-fail/'
fail-on-error: true
upload-sarif: false
- name: Verify it failed
run: |
if [ "${{ steps.fail_true.outcome }}" != "failure" ]; then
echo "Error: Should have failed with fail-on-error: true"
exit 1
fi
- name: Test fail-on-error false (should succeed)
id: fail_false
uses: ./.github/actions/mkdlint
with:
files: 'test-fail/'
fail-on-error: false
upload-sarif: false
- name: Verify it succeeded
run: |
if [ "${{ steps.fail_false.outcome }}" != "success" ]; then
echo "Error: Should have succeeded with fail-on-error: false"
exit 1
fi
test-output-formats:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Create test file
run: |
mkdir -p test-output
echo "#Bad" > test-output/test.md
- name: Test text format
uses: ./.github/actions/mkdlint
with:
files: 'test-output/'
output-format: text
upload-sarif: false
fail-on-error: false
- name: Test JSON format
uses: ./.github/actions/mkdlint
with:
files: 'test-output/'
output-format: json
upload-sarif: false
fail-on-error: false
- name: Test SARIF format
uses: ./.github/actions/mkdlint
with:
files: 'test-output/'
output-format: sarif
sarif-file: test-output.sarif
upload-sarif: false
fail-on-error: false
- name: Verify SARIF was created
run: |
if [ ! -f "test-output.sarif" ]; then
echo "Error: SARIF file not created"
exit 1
fi
test-verbosity:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Test verbose mode
uses: ./.github/actions/mkdlint
with:
files: 'README.md'
verbose: true
upload-sarif: false
fail-on-error: false
- name: Test quiet mode
uses: ./.github/actions/mkdlint
with:
files: 'README.md'
quiet: true
upload-sarif: false
fail-on-error: false
integration-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Create comprehensive test suite
run: |
mkdir -p integration-test/docs integration-test/vendor
# Good markdown
cat > integration-test/docs/good.md << 'MDEOF'
# Good Document
This is properly formatted.
## Section 1
Content here.
## Section 2
More content.
MDEOF
# Bad markdown (fixable)
cat > integration-test/docs/fixable.md << 'MDEOF'
#Bad heading
Trailing spaces:
- Extra space in list
- Normal item
MDEOF
# Vendor (should be ignored)
echo "#Bad" > integration-test/vendor/ignored.md
- name: Create config
run: |
cat > integration-test/.markdownlint.json << 'JSONEOF'
{
"default": true,
"MD013": { "line_length": 120 }
}
JSONEOF
- name: Run full workflow
id: full
uses: ./.github/actions/mkdlint
with:
files: 'integration-test/'
config: 'integration-test/.markdownlint.json'
ignore: '**/vendor/**'
output-format: sarif
sarif-file: integration.sarif
fix: true
upload-sarif: false
fail-on-error: false
- name: Verify results
run: |
echo "Exit code: ${{ steps.full.outputs.exit-code }}"
echo "Errors: ${{ steps.full.outputs.error-count }}"
echo "Files: ${{ steps.full.outputs.file-count }}"
# Verify fixes were applied
cat integration-test/docs/fixable.md
# Verify SARIF was created
if [ ! -f "integration.sarif" ]; then
echo "Error: SARIF not created"
exit 1
fi
# Verify vendor was ignored
jq '.runs[0].results[].locations[].physicalLocation.artifactLocation.uri' integration.sarif | \
grep -q vendor && echo "Error: Vendor files not ignored" && exit 1 || true
echo "Integration test passed!"
test-working-directory:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Create subdirectory structure
run: |
mkdir -p subdir/docs
echo "# Test" > subdir/docs/test.md
- name: Run from subdirectory
uses: ./.github/actions/mkdlint
with:
files: 'docs/'
working-directory: 'subdir'
upload-sarif: false
fail-on-error: false
test-job-summary:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Create test file with errors
run: |
mkdir -p test-summary
cat > test-summary/errors.md << 'TESTEOF'
#Bad heading
Some text here
## heading
## heading
TESTEOF
- name: Run with job summary enabled
id: summary-test
uses: ./.github/actions/mkdlint
with:
files: 'test-summary/'
upload-sarif: false
fail-on-error: false
job-summary: true
output-format: sarif
- name: Verify new outputs exist
run: |
echo "Warning count: ${{ steps.summary-test.outputs.warning-count }}"
echo "Duration ms: ${{ steps.summary-test.outputs.duration-ms }}"
# Duration should be a number > 0
if [ -z "${{ steps.summary-test.outputs.duration-ms }}" ]; then
echo "Error: duration-ms output is empty"
exit 1
fi
# warning-count should be set (can be 0)
if [ -z "${{ steps.summary-test.outputs.warning-count }}" ]; then
echo "Error: warning-count output is empty"
exit 1
fi
- name: Run with job summary disabled
uses: ./.github/actions/mkdlint
with:
files: 'test-summary/'
upload-sarif: false
fail-on-error: false
job-summary: false
test-changed-only:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Test changed-only on push (should lint all files)
id: push-test
uses: ./.github/actions/mkdlint
with:
files: 'README.md'
changed-only: true
upload-sarif: false
fail-on-error: false
- name: Verify push event lints normally
run: |
# On push events, changed-only should still lint the specified files
echo "Exit code: ${{ steps.push-test.outputs.exit-code }}"
test-summary:
runs-on: ubuntu-latest
needs:
- test-binary-download
- test-cargo-build
- test-sarif-upload
- test-auto-fix
- test-custom-config
- test-disable-rules
- test-ignore-patterns
- test-fail-on-error
- test-output-formats
- test-verbosity
- integration-test
- test-working-directory
- test-job-summary
- test-changed-only
if: always()
steps:
- name: Check all tests passed
run: |
if [ "${{ needs.test-binary-download.result }}" != "success" ] || \
[ "${{ needs.test-cargo-build.result }}" != "success" ] || \
[ "${{ needs.test-sarif-upload.result }}" != "success" ] || \
[ "${{ needs.test-auto-fix.result }}" != "success" ] || \
[ "${{ needs.test-custom-config.result }}" != "success" ] || \
[ "${{ needs.test-disable-rules.result }}" != "success" ] || \
[ "${{ needs.test-ignore-patterns.result }}" != "success" ] || \
[ "${{ needs.test-fail-on-error.result }}" != "success" ] || \
[ "${{ needs.test-output-formats.result }}" != "success" ] || \
[ "${{ needs.test-verbosity.result }}" != "success" ] || \
[ "${{ needs.integration-test.result }}" != "success" ] || \
[ "${{ needs.test-working-directory.result }}" != "success" ] || \
[ "${{ needs.test-job-summary.result }}" != "success" ] || \
[ "${{ needs.test-changed-only.result }}" != "success" ]; then
echo "❌ Some tests failed"
exit 1
else
echo "✅ All tests passed!"
fi