feat: add Vale linting for generated Markdown - #1878
Conversation
- 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 SummaryThis 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.
Confidence Score: 2/5The 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
|
| 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. |
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
| "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", |
There was a problem hiding this comment.
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.
| "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.| run: php example.php ${{ matrix.sdk }} ${{ matrix.platform }} | ||
|
|
||
| - name: Setup Vale | ||
| uses: errata-ai/setup-vale@v3 |
There was a problem hiding this comment.
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.| @@ -1,4 +1,4 @@ | |||
| # {{ spec.info.title }} {{sdk.name}} SDK | |||
| # {{ spec.info.title }} {{sdk.name | caseLower}} SDK | |||
There was a problem hiding this comment.
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.
| # {{ 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!
What does this PR do?
Adds Vale linting for Markdown generated by the SDK Generator.
examples/.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:
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.