Skip to content

Run the Markdown Linter on markdownlint-cli2 instead of Super Linter - #10640

Merged
Amaury Levé (Evangelink) merged 13 commits into
mainfrom
nohwnd-fix-markdownlint-workflow-c4c
Aug 25, 2026
Merged

Run the Markdown Linter on markdownlint-cli2 instead of Super Linter#10640
Amaury Levé (Evangelink) merged 13 commits into
mainfrom
nohwnd-fix-markdownlint-workflow-c4c

Conversation

@nohwnd

@nohwnd Jakub Jareš (nohwnd) commented Aug 18, 2026

Copy link
Copy Markdown
Member

The Markdown Linter workflow has never run. All 63 runs since 2026-05-22 ended in startup_failure, because it is the only workflow in the repository referencing an action outside actions/* and github/*, and this repository restricts Actions to a selected list that does not include super-linter/super-linter. The run is rejected before any job starts, which is why there is no log, no check run and no annotation to notice.

Run markdownlint-cli2 instead, pinned to 0.23.2 — the version bundled by DavidAnson/markdownlint-cli2-action@v24.2.0 that markdownlint.yml runs on every pull request. The scheduled report and the gate now apply the same rules from .markdownlint-cli2.jsonc, including its ignores, so the report cannot flag anything the gate would let through. .github/dependabot.yml ignores that action so the two pins can only move together, by hand; Dependabot only sees the action and would otherwise bump one side alone and silently give the two different rule sets.

Two further bugs: the lint step failed the job on violations, which skipped the agent that writes the report, so the workflow could only ever have reported a clean tree; and VALIDATE_ALL_CODEBASE=false lints only files differing from the default branch, which on a scheduled run on main is nothing. It now scans all 86 tracked Markdown files.

Failure handling

The agent job needs markdownlint, and detection and safe_outputs chain off agent, so a red lint job takes the whole reporting path down with it and the scheduled run says nothing at all. The lint job therefore always succeeds, including when the linter could not run. A red run is not the failure signal here; the issue the agent files is.

The two outcomes are kept apart in the log rather than in the exit code:

  • Lint resultsmarkdownlint-cli2 exited 0 or 1. The log holds findings and the agent reports on them as usual.
  • Tooling failure — the npm install failed, or markdownlint-cli2 exited above 1: 2 is an execution or configuration error, 124 or 137 a timeout. The log is rewritten with MARKDOWNLINT_RUN_FAILED as its first line, followed by the error output. The prompt checks that marker before anything else and must then file a workflow-failure issue saying Markdown went unlinted, rather than analysing the error text as findings or reporting a clean run.

A ::error:: annotation is still emitted in the failure case, so the run surfaces in the UI without breaking the reporting chain.

Stalls are bounded at three levels, because each one alone leaves a gap. Each command runs under timeout --kill-after=30s 3m: the plain job timeout would kill the step before it could mark the log, and timeout without a kill grace only sends SIGTERM, which a hung process can ignore. timeout-minutes: 10 on the job is the backstop. The numbers have to keep that order — worst case is 3m30s per command, so 7 minutes for the pair, leaving 3 minutes for checkout, the marker write and the artifact upload.

Also drops the unused packages: read and statuses: write permissions and a dead step whose output no job consumed. The workflow keeps no source: field, so gh aw update cannot restore the blocked action; a comment in the frontmatter records why.

Security review

Required by the gh-aw safe-update warning on the first compile: super-linter/super-linter@4ce20838 is removed and no action is added — actions/checkout and actions/upload-artifact only move within the file at their existing pins. No secrets added or removed; the job no longer needs the GITHUB_TOKEN Super Linter consumed. Permissions are reduced, never widened. The one new network access is npm install --global markdownlint-cli2@0.23.2 fetching that pinned version from the npm registry.

Verification

  • Exit handling under bash -e with the linter stubbed: 0 and 1 leave the log untouched; 2, 124 and 137 prepend MARKDOWNLINT_RUN_FAILED; the step exits 0 in every case so the reporting chain survives.
  • The kill grace was checked against a process that traps and ignores SIGTERM. Without it the command outlived its cap entirely; with it the command is killed and reports 137.
  • npx markdownlint-cli2@0.23.2 "**/*.md": 86 files, 0 issues.
  • python .github/scripts/check_action_pins.py: passes, 2343 references across 49 files.
  • Dispatched the compiled workflow on the branch: activation, markdownlint and agent all green, install and lint steps succeeding, no marker in the log. The job takes about 20 seconds against the 10 minute cap.

Note for whoever recompiles this: the lock file is generated with gh aw compile --action-mode action --action-tag v0.86.2. A locally installed gh aw resolves gh-aw's own actions/checkout scaffolding to v7.0.0 while .github/aw/actions-lock.json pins v7.0.1, so a local recompile on the wrong version reintroduces the stale pins of #10258 and fails the pin audit.

Fixes the dead scheduled Markdown report. History for the related gate: #10163, #10196, #10214.

🤖

The Markdown Linter workflow has never run. All 63 runs since 2026-05-22 ended in
startup_failure, because it is the only workflow in the repository that references an
action outside actions/* and github/*, and this repository restricts Actions to a
selected list:

  patterns_allowed: dotnet/arcade/.github/workflows/*,
                    peter-evans/create-pull-request@*,
                    DavidAnson/markdownlint-cli2-action@*
  verified_allowed: false

super-linter/super-linter is not on that list, so the run was rejected before any job
started. This is the same failure that took out the markdownlint gate in #10636.

Swap Super Linter for markdownlint-cli2, pinned to 0.23.1, the version bundled by
DavidAnson/markdownlint-cli2-action@v24.1.0 that markdownlint.yml already runs on every
pull request. The scheduled report and the pull request gate now apply the same rules
from .markdownlint-cli2.jsonc, including its ignores, so the report cannot flag anything
the gate would let through.

Two more bugs fixed along the way:

- The lint step no longer fails the job when it finds violations. Super Linter failed the
  job, which skipped the agent that was supposed to write the report, so the workflow
  could not have reported violations even if it had started.
- Super Linter ran with VALIDATE_ALL_CODEBASE=false, which lints only files that differ
  from the default branch. On a scheduled run on main that is nothing. markdownlint-cli2
  scans all 86 tracked Markdown files.

Also drop the now-unused packages: read and statuses: write permissions, and the dead
check-results step whose output no job consumed.

The workflow keeps no source: field. It came from
githubnext/agentics/workflows/markdown-linter.md@main, and relinking it would let
gh aw update restore the blocked action and break the workflow again.

Compiled with gh aw v0.86.0 using --action-mode release --action-tag 435186c5, matching
the pins in the other lock files; .github/scripts/check_action_pins.py passes.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings August 18, 2026 13:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Replaces the blocked Super Linter job with markdownlint-cli2 for scheduled Markdown reporting.

Changes:

  • Aligns scheduled linting with the pull-request Markdown gate.
  • Preserves lint logs while reducing permissions.
  • Regenerates the compiled agentic workflow.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
.github/workflows/markdown-linter.md Defines the new markdownlint-cli2 workflow.
.github/workflows/markdown-linter.lock.yml Compiles the updated workflow definition.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread .github/workflows/markdown-linter.md
Comment thread .github/workflows/markdown-linter.md Outdated
The step swallowed every exit code, so an npm or configuration failure looked
the same as a clean run: the log held a stack trace instead of lint results,
and the agent went on to report "no issues" over a run that never linted.

markdownlint-cli2 exits 0 clean, 1 with violations, and 2 when it fails to run.
Keep 0 and 1 green, because violations are what the agent reports on, and fail
the job for anything above that.

Also update the workflow catalog entry, which still described this workflow as
running Super Linter.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 19, 2026 07:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Conflict in .github/workflows/markdown-linter.lock.yml: #10657 bumped the
gh-aw setup pin from 435186c5 to 48e5fa3f across every lock file, while this
branch removed super-linter from the same header block.

Resolved by regenerating the lock file from its .md source with
`gh aw compile --action-mode release --action-tag 48e5fa3f` rather than editing
the generated file, so it picks up the new pin and keeps this branch's changes.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 24, 2026 08:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comment thread .github/workflows/markdown-linter.md Outdated
npx exits 1 when it cannot resolve or download the package, which is the same
code markdownlint-cli2 uses for "violations found". A registry outage therefore
kept the job green and handed the agent an npm error log to report as if it
were lint results — the misleading report this step was meant to prevent.

Install the pinned version in a separate step, which fails the job on its own,
and run the installed binary so the tolerated exit code 1 can only come from
markdownlint-cli2 itself.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 24, 2026 08:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Keep the scheduled workflow aligned with markdownlint-cli2-action v24.2.0 on main.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 021b7d71-92b8-40a1-a0ab-5a6d768c5b1a
Copilot AI review requested due to automatic review settings August 24, 2026 11:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment thread .github/workflows/markdown-linter.md Outdated
Conflict in .github/workflows/markdown-linter.lock.yml: #10678 upgraded the
agentic workflows to gh-aw 0.86.2, which changes the compiler version and moves
the setup action to github/gh-aw-actions, while this branch rewrote the same
job.

Resolved by upgrading the local gh aw to v0.86.2 and regenerating the lock file
from its .md source with `--action-mode action --action-tag v0.86.2`, matching
how the other lock files on main are now built, rather than editing the
generated file.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 24, 2026 11:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Comment thread .github/workflows/markdown-linter.md
Comment thread .github/workflows/markdown-linter.md Outdated
The agent job needs the markdownlint job, so failing that job on a tooling
error skipped the agent and, with it, detection and safe_outputs. A registry
outage or a broken config produced a red scheduled run and no issue at all,
which is the unattended silence this workflow is meant to remove.

Keep the job green and hand the agent a log whose first line is
MARKDOWNLINT_RUN_FAILED, and teach the prompt to check for that marker before
anything else and report a workflow failure rather than lint findings. The npm
install keeps its own step and marks the log the same way instead of failing,
so an install failure is reported rather than swallowed.

Also stop Dependabot from bumping DavidAnson/markdownlint-cli2-action on its
own. It pins the CLI version it bundles, and this workflow installs that same
version by hand, so an unattended bump of one side would silently give the
scheduled report and the pull request gate different rule sets.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 25, 2026 12:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Comment thread .github/workflows/markdown-linter.md Outdated
Conflict in .github/dependabot.yml: main added an ignore entry for
github/gh-aw/actions/setup while this branch added one for
DavidAnson/markdownlint-cli2-action. Both are wanted, so both are kept.

The lock file merged cleanly and was left as merged rather than regenerated:
the local gh aw resolves gh-aw's own actions/checkout scaffolding to v7.0.0,
while .github/aw/actions-lock.json pins v7.0.1, so recompiling here reintroduces
the stale pins of #10258. The merged file keeps main's correct pins and this
branch's lint job, and the pin audit passes.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 25, 2026 12:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

Conflict in .github/workflows/markdown-linter.lock.yml: #10729 pinned the
threat-detection model on every agentic workflow, so both sides carry a
different generated metadata hash for the same file.

The .md source merged cleanly and keeps both changes, so the lock file was
regenerated from it with `gh aw compile --action-mode action --action-tag
v0.86.2`. The result has main's threat-detection pin and this branch's lint
job, and the pin audit passes.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 25, 2026 13:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

Comment thread .github/workflows/markdown-linter.md
Comment thread .github/workflows/README.md Outdated
Without timeout-minutes the job inherits GitHub's six-hour default, so a stalled
npm install or linter holds the workflow's concurrency group for hours and then
fails the job. The agent job needs this one, so that failure also skips the
reporting chain and the scheduled run says nothing -- the silence this workflow
exists to remove. The pull request gate finishes in seconds under a 5 minute
cap; 10 leaves headroom.

Also correct the workflow catalog: this workflow has only schedule and
workflow_dispatch triggers, so the trigger column is "Schedule + manual".

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 25, 2026 13:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Suppressed comments (1)

.github/workflows/markdown-linter.md:88

  • A hung linter is also killed only by the job timeout, bypassing the status > 1 marker path and skipping the reporting chain. Give the process its own timeout below the job cap so the resulting status is recorded as MARKDOWNLINT_RUN_FAILED and uploaded for the agent.
        markdownlint-cli2 "**/*.md" > markdownlint.log 2>&1 || status=$?

Comment thread .github/workflows/markdown-linter.md Outdated
The job-level timeout added in the previous commit caps the runaway, but
GitHub kills the job when it fires, so the script never runs its marker branch:
no log is written, no artifact is uploaded, and the agent job is skipped. A
stall was still a red run with no issue.

Wrap both commands in `timeout 5m`, below the job's 10 minute cap. timeout
exits 124, which is greater than 1 and so already routes into the existing
failure branch; the messages name the timeout specifically. Verified against a
real stall: exit 124 marks the log and the step still exits 0.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 25, 2026 14:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Suppressed comments (2)

.github/workflows/markdown-linter.md:69

  • GNU timeout only sends SIGTERM by default; if npm or one of its child processes does not terminate, this command keeps waiting until the job-level timeout kills the job, so no marker is uploaded. Add a short kill-after grace period so a stalled install is guaranteed to reach the failure branch.
        timeout 5m npm install --global markdownlint-cli2@0.23.2 > install.log 2>&1 || status=$?

.github/workflows/markdown-linter.md:101

  • As with the install timeout, this only sends SIGTERM. If the linter does not terminate, the job-level timeout fires before this branch can prepend MARKDOWNLINT_RUN_FAILED or upload the log. Use a kill-after grace period to guarantee termination and preserve the reporting path.
        timeout 5m markdownlint-cli2 "**/*.md" > markdownlint.log 2>&1 || status=$?

Comment thread .github/workflows/markdown-linter.md
The two commands run in sequence, so a 5 minute cap on each could consume the
whole 10 minute job cap before the second one wrote and uploaded its failure
marker. GitHub would then kill the job and the stall would go unreported again,
which is what the command caps were added to prevent.

Cut both command caps to 3 minutes: 3 + 3 leaves 4 minutes for checkout, the
marker write and the artifact upload. The job takes about 15 seconds in
practice, so 3 minutes is still roughly 45x the observed install and 18x the
lint. The comments now state the arithmetic so the three numbers stay
consistent.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 25, 2026 14:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

`timeout` alone sends only SIGTERM, so a command that ignores it keeps running
and the job-level timeout kills the job before the failure marker is written or
uploaded. The command caps could not bound a genuinely hung process.

Add --kill-after=30s to both commands. The grace period forces SIGKILL, which
surfaces as 137 rather than 124, so both codes now count as a timeout. Worst
case is 3m plus 30s per command, 7 minutes for the pair, still inside the 10
minute job cap.

Verified against a process that traps and ignores SIGTERM: without the grace
period it outlived its cap entirely; with it the command is killed, reports 137
and the log is marked.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 25, 2026 14:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

@Evangelink Amaury Levé (Evangelink) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the latest head. The previously identified version-coupling, failure-reporting, timeout, and documentation issues are resolved, and the generated workflow, action pins, permissions, artifact flow, and shell failure paths are consistent.

@Evangelink
Amaury Levé (Evangelink) merged commit a6f1a7d into main Aug 25, 2026
36 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the nohwnd-fix-markdownlint-workflow-c4c branch August 25, 2026 15:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants