Skip to content

feat: add Vale linting for generated Markdown - #1878

Open
kekubhai wants to merge 2 commits into
appwrite:mainfrom
kekubhai:main
Open

feat: add Vale linting for generated Markdown#1878
kekubhai wants to merge 2 commits into
appwrite:mainfrom
kekubhai:main

Conversation

@kekubhai

@kekubhai kekubhai commented Sep 6, 2026

Copy link
Copy Markdown

What does this PR do?

Adds Vale linting for Markdown generated by the SDK Generator.

  • Adds a shared Vale configuration and Appwrite terminology rules.
  • Validates generated Markdown under examples/.
  • Fixes the generated PHP README heading that failed Vale.
  • Adds a validation script and Composer command for local Markdown linting.
  • Runs Vale validation in CI after SDK generation.
  • Documents how to run the Markdown validation locally.

This ensures changes to generated Markdown templates can be caught automatically instead of only being discovered after generation.

Test Plan

Verified the generator and Vale validation for the PHP, Python, and Go SDK outputs.

Commands/results:

  • Generated PHP SDK → Vale: 0 errors, 0 warnings
  • Generated Python SDK → Vale: 0 errors, 0 warnings
  • Generated Go SDK → Vale: 0 errors, 0 warnings

Also verified the existing repository checks pass.

Related PRs and Issues

Closes #1822.

Have you read the [Contributing Guidelines on issues](https://github.com/appwrite/appwrite/blob/master/CONTRIBUTING.md)?

Yes.

- Add Vale configuration (.vale.ini) with Google and Appwrite style guides
- Include 38 Google style rule definitions for consistent documentation standards
- Add custom Appwrite Terms rule to enforce 'test' over 'spec' terminology
- Configure Vale to ignore code blocks and generated API documentation
- Add validation workflow step to check generated SDK examples with Vale
- Update CONTRIBUTING.md with Vale linting instructions
- Add markdown validation script (scripts/validate-markdown.sh)
- Update PHP README template with linting best practices
- Update composer.json dependencies for documentation tooling
- Suppress inappropriate rules for auto-generated API docs and SDK-specific content
@greptile-apps

greptile-apps Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR introduces Vale-based linting for generated Markdown, including a vendored Google style set, Appwrite terminology rules, CI validation, a local Composer command, documentation, and a PHP README template adjustment.

  • Adds Vale 3.20.0 setup and validation to each SDK-generation matrix job.
  • Adds shared Vale configuration and generated-document suppressions.
  • Adds a local Markdown-validation shell script and contributor instructions.
  • Refreshes several locked PHP development dependencies.

Confidence Score: 2/5

The PR is not yet safe to merge because the documented local lint command cannot execute and the new CI dependency is not pinned immutably.

The non-executable validation script breaks the newly advertised Composer workflow, while the mutable action reference introduces avoidable CI supply-chain exposure; the PHP heading also renders the SDK acronym incorrectly.

Files Needing Attention: composer.json, scripts/validate-markdown.sh, .github/workflows/validation.yml, templates/php/README.md.twig

Security Review

The workflow executes the third-party Vale setup action through a mutable tag. Pinning it to an immutable commit is necessary to preserve the repository's existing CI supply-chain protections.

Important Files Changed

Filename Overview
.github/workflows/validation.yml Adds generated-Markdown validation but references the third-party setup action through a mutable tag.
composer.json Adds a local lint command that directly invokes a newly committed non-executable script.
scripts/validate-markdown.sh Implements clear Vale prerequisite and failure handling, but its committed mode prevents the documented direct invocation.
.vale.ini Configures Google and Appwrite styles with targeted generated-document suppressions.
templates/php/README.md.twig Lowercases the PHP SDK name despite the configuration explicitly preserving proper-noun capitalization.
composer.lock Refreshes multiple unrelated development packages, but the resulting constraints remain compatible with PHP 8.5.
CONTRIBUTING.md Documents generation and Vale commands, though the documented Composer command is currently blocked by script permissions.

Fix all with Greploop Fix All in Claude Code Fix All in Codex

Prompt To Fix All With AI
### Issue 1
composer.json:19
**Lint script is not executable**

The new Composer command invokes `./scripts/validate-markdown.sh` directly, but the script is committed with mode `100644`. On Unix checkouts, `composer lint-markdown` exits with “Permission denied” before Bash or Vale runs.

```suggestion
        "lint-markdown": "bash ./scripts/validate-markdown.sh examples",
```

### Issue 2
.github/workflows/validation.yml:103
**Action uses a mutable tag**

The new third-party action is referenced through the mutable `v3` tag, unlike the SHA-pinned actions elsewhere in this workflow. If that tag is moved or the publisher is compromised, substituted code executes in this pull-request workflow with runner access and the job's default token. Pin the action to a full commit SHA.

**How this was verified:** The pull-request workflow directly executes `errata-ai/setup-vale@v3` without an immutable commit reference or restricted permissions.

### Issue 3
templates/php/README.md.twig:1
**PHP acronym is lowercased**

Applying `caseLower` changes the generated README title from “PHP SDK” to “php SDK.” This contradicts the Vale configuration, which says SDK names are proper nouns that should not be lowercased and already disables heading-capitalization checks for generated READMEs.

```suggestion
# {{ spec.info.title }} {{sdk.name}} SDK
```

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "Merge branch 'appwrite:main' into main" | Re-trigger Greptile

Comment thread composer.json
"refactor": "vendor/bin/rector process",
"refactor:check": "vendor/bin/rector process --dry-run",
"lint-twig": "uvx djlint==1.40.10 templates/ --lint",
"lint-markdown": "./scripts/validate-markdown.sh examples",

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.

P1 Lint script is not executable

The new Composer command invokes ./scripts/validate-markdown.sh directly, but the script is committed with mode 100644. On Unix checkouts, composer lint-markdown exits with “Permission denied” before Bash or Vale runs.

Suggested change
"lint-markdown": "./scripts/validate-markdown.sh examples",
"lint-markdown": "bash ./scripts/validate-markdown.sh examples",
Prompt To Fix With AI
This is a comment left during a code review.
Path: composer.json
Line: 19

Comment:
**Lint script is not executable**

The new Composer command invokes `./scripts/validate-markdown.sh` directly, but the script is committed with mode `100644`. On Unix checkouts, `composer lint-markdown` exits with “Permission denied” before Bash or Vale runs.

```suggestion
        "lint-markdown": "bash ./scripts/validate-markdown.sh examples",
```

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Claude Code Fix in Codex

run: php example.php ${{ matrix.sdk }} ${{ matrix.platform }}

- name: Setup Vale
uses: errata-ai/setup-vale@v3

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.

P1 security Action uses a mutable tag

The new third-party action is referenced through the mutable v3 tag, unlike the SHA-pinned actions elsewhere in this workflow. If that tag is moved or the publisher is compromised, substituted code executes in this pull-request workflow with runner access and the job's default token. Pin the action to a full commit SHA.

How this was verified: The pull-request workflow directly executes errata-ai/setup-vale@v3 without an immutable commit reference or restricted permissions.

Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/validation.yml
Line: 103

Comment:
**Action uses a mutable tag**

The new third-party action is referenced through the mutable `v3` tag, unlike the SHA-pinned actions elsewhere in this workflow. If that tag is moved or the publisher is compromised, substituted code executes in this pull-request workflow with runner access and the job's default token. Pin the action to a full commit SHA.

**How this was verified:** The pull-request workflow directly executes `errata-ai/setup-vale@v3` without an immutable commit reference or restricted permissions.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Claude Code Fix in Codex

@@ -1,4 +1,4 @@
# {{ spec.info.title }} {{sdk.name}} SDK
# {{ spec.info.title }} {{sdk.name | caseLower}} SDK

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.

P2 PHP acronym is lowercased

Applying caseLower changes the generated README title from “PHP SDK” to “php SDK.” This contradicts the Vale configuration, which says SDK names are proper nouns that should not be lowercased and already disables heading-capitalization checks for generated READMEs.

Suggested change
# {{ spec.info.title }} {{sdk.name | caseLower}} SDK
# {{ spec.info.title }} {{sdk.name}} SDK
Prompt To Fix With AI
This is a comment left during a code review.
Path: templates/php/README.md.twig
Line: 1

Comment:
**PHP acronym is lowercased**

Applying `caseLower` changes the generated README title from “PHP SDK” to “php SDK.” This contradicts the Vale configuration, which says SDK names are proper nouns that should not be lowercased and already disables heading-capitalization checks for generated READMEs.

```suggestion
# {{ spec.info.title }} {{sdk.name}} SDK
```

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Claude Code Fix in Codex

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.

📚 Documentation: Add Vale linting for all generated docs and examples

1 participant