Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions .github/workflows/markdownlint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Markdownlint

on:
push:
branches: [main]
pull_request:
branches: [main]

# Automatically cancel in-progress runs on the same branch
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
markdownlint:
name: Lint changed Markdown/MDX files
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Get changed files
id: changed
uses: tj-actions/changed-files@v45
with:
files: |
**/*.md
**/*.mdx
files_ignore: |
**/reference/**
en/database/tables/**
release-notes/api/**
release-notes/database/**
blueprint-templates/**
api-sources/**
downloads/**

- name: Set up Node
if: steps.changed.outputs.any_changed == 'true'
uses: actions/setup-node@v4
with:
node-version: '22'

- name: Install markdownlint-cli2
if: steps.changed.outputs.any_changed == 'true'
run: npm install -g markdownlint-cli2

- name: Run markdownlint-cli2 on changed files
if: steps.changed.outputs.any_changed == 'true'
continue-on-error: true
run: markdownlint-cli2 ${{ steps.changed.outputs.all_changed_files }}
8 changes: 4 additions & 4 deletions .markdownlintignore
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
**/**/*.{cs,xml,yml}
/downloads/
/en/api/archive-providers/reference/
/en/api/mdo-providers/reference/
/en/api/reference/
/en/automation/crmscript/reference/
**/reference/
/en/database/tables/
/config/
/release-notes/api/
/release-notes/database/
/blueprint-templates/
/api-sources/
/vale/
.gitignore
.mintignore
3 changes: 2 additions & 1 deletion config/nav-contribute.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,6 @@
]
},
"contribute/configure-mintlify",
"contribute/deployment"
"contribute/deployment",
"contribute/automated-tests"
]
73 changes: 73 additions & 0 deletions contribute/automated-tests.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
uid: automated-tests
title: Automated tests
description: Every check that runs against a PR or on a schedule for this repo - markdownlint, Vale, build validation, and broken-link checking - what each covers, whether it blocks a merge, and where to look when one flags something.
keywords: ['ci', 'automated tests', 'markdownlint', 'vale', 'broken links', 'mint validate', 'automations']
author: digitaldiina
date: 08.10.2026
content_type: concept
language: en
---

This page is the single reference for every automatic check that runs against this repo, whether it is triggered by a pull request or runs on its own schedule. It does not duplicate the general mechanics already covered in [Mintlify deployment and CI/CD][1] - only what each check covers and how to act on it.

## Per-PR checks

| Check | Runs via | Blocking? | Configured in |
|---|---|---|---|
| Markdownlint | GitHub Action (`.github/workflows/markdownlint.yml`) | No - advisory | This repo, `.markdownlint.yaml` / `.markdownlintignore` |
| Vale | Mintlify CI Checks add-on | No - Warning level | Mintlify dashboard (Add-ons > CI Checks), using this repo's `.vale.ini` |
| Build validation | Mintlify preview deployment | Yes - a failed build shows as a red "Mintlify Deployment" check | Mintlify, automatic on every PR (see [Deploy trigger mechanics][2]) |
| Broken links (internal) | Mintlify CI Checks add-on | No - Warning level | Mintlify dashboard (Add-ons > CI Checks) |

### Markdownlint

Lints only the `.md`/`.mdx` files changed in a PR (or pushed directly to `main`) using this repo's own `.markdownlint.yaml` rules. Results appear in the workflow run's log in the GitHub Actions tab - a flagged line does not block the merge, but is worth fixing before requesting review. See [markdownlint][3] for how to interpret and fix a specific rule violation, and how to run the same linter locally.

### Vale

Prose-style linting (tone, terminology, formatting), configured entirely by this repo's `.vale.ini` - no separate setup needed once the add-on is toggled on in the Mintlify dashboard. Set to Warning level to match markdownlint's advisory-only posture; results show on the PR's checks list from Mintlify's own GitHub App.

### Build validation - why there is no separate `mint validate` step

`mint validate` is a build/schema validator (`docs.json` schema, MDX parse errors, OpenAPI spec validation) - it is unrelated to Vale and does not check broken links or accessibility; those are separate CLI commands (`mint broken-links`, `mint a11y`). It is not run as its own GitHub Action here because the PR preview deployment already performs the equivalent build validation on every PR, live, as part of generating the preview - adding a duplicate `mint validate` Action would just re-check what the preview build already checked. A failed build already surfaces as the red "Mintlify Deployment" check described in [Deployment][2].

### Broken links (per-PR)

Mintlify's Broken Links add-on scans the whole site's internal links (not external URLs) on every PR and reports results the same way as the Vale check above. It is set to Warning level for the same advisory-first reasoning as the other checks.

<Note>
A Mintlify community report (October 2025) describes a case where a page serving a 404 still returned an HTTP 200 status, which could make this check under-report a real broken link. Do not treat "no broken links flagged" here as a guarantee - see the scheduled check and fallback tool below for a second opinion.
</Note>

## Scheduled check: repo-wide broken-link detection

A per-PR link check only catches breaks introduced by that PR. A separate, Mintlify-hosted automation periodically re-scans the *entire* site, catching drift from any source - including direct admin-bypass pushes that skip PR review entirely.

* **Type:** `broken-link-detection` (`mint automations create --type broken-link-detection`)
* **Cadence:** `0 6 1,15 * *` - the 1st and 15th of each month, run at 06:00. Standard cron has no native "every 2 weeks" field; this is the closest non-drifting approximation of a biweekly cadence (actual gaps land at 13-16 days depending on the month).
* **Auto-merge:** off. When the automation finds and fixes a broken link, it opens a PR like any other change - it goes through the same manual review as everything else in this repo, it does not merge itself.
* **What it does:** for each broken internal link, it checks whether the target page was renamed or moved and updates the link, or - if the target was removed entirely - edits the surrounding copy to remove or replace the reference.
* **Cost:** billed in Mintlify credits per run (rough public estimate: ~285 credits/run) - a real operating cost, not a free background job.

See [issue #81][4] for the setup record (creation command, confirmed `mint automations list` output).

## Fallback: manual broken-link check

`tools/triage-broken-links.py` (built during [#129][5]) plus the `mint broken-links` CLI remain the trusted manual method for a broken-link sweep, separating genuine breaks from known false positives. Reach for this:

* Right after a large structural change (a folder move, a nav overhaul) rather than waiting for the next scheduled automation run.
* As a second opinion if the scheduled automation or the per-PR add-on reports "no breaks found" but something looks off - see the HTTP-200-masking-a-404 caveat above.

## Related content

* [Mintlify deployment and CI/CD][1] - the deploy pipeline and PR preview mechanics these checks build on.
* [markdownlint][3] - rule details and local usage.
* [Reviewing a PR][6] - the review checklist that links back here.

[1]: ./deployment
[2]: ./deployment#deploy-trigger-mechanics
[3]: ./markdown-guide/markdownlint
[4]: https://github.com/SuperOfficeDocs/docs/issues/81
[5]: https://github.com/SuperOfficeDocs/docs/issues/129
[6]: ./review/index
20 changes: 11 additions & 9 deletions contribute/markdown-guide/markdownlint.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -61,35 +61,37 @@ Don't use HTML comments (`<!-- like this -->`) to turn off a rule for a single l

`.markdownlint.yaml` is already tuned to avoid needing most per-file overrides (for example, `MD013`'s line-length limits are generous and `MD041` doesn't require a specific front-matter title). If you hit a rule that genuinely needs a one-off exception, check with the DX team first rather than reaching for an HTML comment — the current MDX-safe mechanism for disabling a rule inline hasn't been established yet.

## Runs automatically on every pull request

A GitHub Action lints every changed `.md`/`.mdx` file on each PR, using this repo's own `.markdownlint.yaml` and `.markdownlintignore`. It is advisory only for now - a lint issue shows up in the Action's log but does not block the PR from merging. See [Automated tests][8] for the full list of checks that run against this repo and how to read their results.

## Command-line linting

You can optionally install [markdownlint-cli][6], a command-line interface that allows you to do bulk linting. This is useful for bulk editing but it can also be added to a build pipeline as automatic testing.
You can optionally install [markdownlint-cli2][6], a command-line interface that allows you to do bulk linting - the same tool the pull request Action above uses. This is useful for bulk editing.

**Install:**

```sh
npm install -g markdownlint-cli
npm install -g markdownlint-cli2
```

**Use:**

```sh
markdownlint -f -i *.cs *.xml --disable MD013 MD041 -c .markdownlint.yaml PATH
markdownlint-cli2 PATH
```

* -f will automatically fix problems that have a defined fix, for example, whitespace
* -i ignores whatever follows, in this case, all cs and XML files. To omit API from the run, add api/ to the path.
* --disable turns off the listed rules
* -c specifies the markdownlint config file. In this case, we use the one inside the `superoffice-docs` repo
`markdownlint-cli2` auto-discovers `.markdownlint.yaml` (the rule configuration) and `.markdownlintignore` (excluded paths, such as generated reference content) from the repo root - no need to repeat them as flags. `PATH` can be a single file, a glob, or a space-separated list of files. Add `--fix` to automatically resolve issues that have a defined fix, such as whitespace.

See [GitHub issue 373][7] regarding why we exclude rules MD013 and MD041.
See [GitHub issue 373][7] regarding why we exclude rules MD013 and MD041 in `.markdownlint.yaml`.

[2]: ./index
[3]: https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint
[4]: https://github.com/DavidAnson/markdownlint#rules--aliases
[5]: https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md
[6]: https://github.com/igorshubovych/markdownlint-cli
[6]: https://github.com/DavidAnson/markdownlint-cli2
[7]: https://github.com/SuperOfficeDocs/superoffice-docs/issues/373
[8]: ../automated-tests

[img1]: /media/loc/en/contribute/mdlint-list-warning.png
[img2]: /media/loc/en/contribute/mdlint-list-hover.png
Expand Down
3 changes: 2 additions & 1 deletion contribute/review/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ GitHub blocks self-approval of your own PR at the API level, so the Code Owner c

* [Markdown formatting][3] - no linting errors
* [Style guide][2]
* Automatic tests should pass.
* Automatic tests should pass - see [Automated tests][9] for the full list (markdownlint, Vale, broken-link checks) and where to read their results. Markdownlint and Vale are advisory only for now: a flagged issue is worth a look, but it does not block the merge on its own.
* The [Mintlify preview deployment][8] should build successfully, and the changed pages should look correct in it.
* Reference to deleted pages should be removed from toc and other content.
* Reference to moved or renamed pages should be updated so no links break.
Expand All @@ -63,3 +63,4 @@ GitHub blocks self-approval of your own PR at the API level, so the Code Owner c
[6]: https://github.com/SuperOfficeDocs/docs/blob/main/.github/CODEOWNERS
[7]: ../branch-strategy
[8]: ./check-changes#preview
[9]: ../automated-tests
Loading