diff --git a/.github/workflows/vale.yml b/.github/workflows/vale.yml new file mode 100644 index 000000000..21b8d6593 --- /dev/null +++ b/.github/workflows/vale.yml @@ -0,0 +1,36 @@ +name: Vale + +on: + pull_request: + types: [opened, synchronize, reopened] + paths: + - 'website/**/*.md' + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + checks: write + pull-requests: write + +jobs: + vale: + name: Lint prose + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + with: + persist-credentials: false + + - name: Vale + uses: vale-cli/vale-action@d89dee975228ae261d22c15adcd03578634d429c # v2.1.1 + with: + files: website/ + vale_flags: "--minAlertLevel=warning" + reporter: github-pr-review + fail_on_error: true + filter_mode: added diff --git a/.vale.ini b/.vale.ini new file mode 100644 index 000000000..36e945df8 --- /dev/null +++ b/.vale.ini @@ -0,0 +1,19 @@ +StylesPath = .vale/styles +MinAlertLevel = warning + +Vocab = GardenerTerms, ThirdPartyProducts, TechJargon, General + +IgnoredScopes = code, tt, code block + +[*.md] +BasedOnStyles = Gardener + +TokenIgnores = (`[^`]+`), (<[^>]+>), (v[0-9]+(?:\.[0-9]+)*(?:alpha[0-9]+|beta[0-9]+)?), (/[^\s]+), (https?://\S+), ([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]+), (\w+\(s\)), (\*+\w+\**|\w+\*+) + +BlockIgnores = (?s)(\{\{.*?\}\}) + +[website/about/legal-disclosure.md] +BasedOnStyles = + +[website/archived/**] +BasedOnStyles = diff --git a/.vale/styles/Gardener/Articles.yml b/.vale/styles/Gardener/Articles.yml new file mode 100644 index 000000000..84c08c219 --- /dev/null +++ b/.vale/styles/Gardener/Articles.yml @@ -0,0 +1,40 @@ +extends: substitution +message: "Use '%s' instead of '%s'. The article depends on pronunciation, not spelling." +link: https://github.com/gardener/documentation/blob/master/website/documentation/contribute/documentation/style-guide/_index.md +level: warning +ignorecase: false +action: + name: replace +swap: + # Acronyms starting with vowel-sound letters that need "an" + # A (ay), E (ee), F (ef), H (aitch), I (eye), L (el), M (em), N (en), O (oh), R (ar), S (es), X (ex) + 'a OS': an OS + 'a HA': an HA + 'a HTTP': an HTTP + 'a HTML': an HTML + 'a SSH': an SSH + 'a SSL': an SSL + 'a API': an API + 'a OIDC': an OIDC + 'a OCI': an OCI + 'a SSD': an SSD + 'a SDK': an SDK + 'a XML': an XML + 'a IDE': an IDE + 'a IAM': an IAM + 'a HPA': an HPA + 'a FAQ': an FAQ + 'a ETCD': an ETCD + 'a NFS': an NFS + 'a RBAC': an RBAC + # Acronyms starting with consonant-sound letters that need "a" + # U (yoo), V (vee), W (double-yoo), C (see) when starts acronym + 'an VM': a VM + 'an VPA': a VPA + 'an VPC': a VPC + 'an VPN': a VPN + 'an URL': a URL + 'an URI': a URI + 'an GPU': a GPU + 'an CPU': a CPU + 'an SIG': a SIG diff --git a/.vale/styles/Gardener/CommandPrompt.yml b/.vale/styles/Gardener/CommandPrompt.yml new file mode 100644 index 000000000..ec2a16d80 --- /dev/null +++ b/.vale/styles/Gardener/CommandPrompt.yml @@ -0,0 +1,8 @@ +extends: existence +message: "Don't include the command prompt '%s' in code blocks. Show only the command itself." +level: error +link: https://github.com/gardener/documentation/blob/master/website/documentation/contribute/documentation/formatting-guide.md +scope: raw +tokens: + - '```[a-z]*\n\$\s' + - '`\$\s\w' diff --git a/.vale/styles/Gardener/Links.yml b/.vale/styles/Gardener/Links.yml new file mode 100644 index 000000000..f6867263e --- /dev/null +++ b/.vale/styles/Gardener/Links.yml @@ -0,0 +1,13 @@ +extends: existence +message: "Avoid generic link text '%s'. Use a descriptor of the link's destination instead." +level: warning +link: https://github.com/gardener/documentation/blob/master/website/documentation/contribute/documentation/style-guide/_index.md +scope: raw +nonword: true +tokens: + - '\[here\]\(' + - '\[click here\]\(' + - '\[this link\]\(' + - '\[this page\]\(' + - '\[read more\]\(' + - '\[learn more\]\(' diff --git a/.vale/styles/Gardener/Spelling.yml b/.vale/styles/Gardener/Spelling.yml new file mode 100644 index 000000000..9a39d12f5 --- /dev/null +++ b/.vale/styles/Gardener/Spelling.yml @@ -0,0 +1,27 @@ +extends: spelling +message: "Verify the spelling of '%s'. If the spelling is correct, please add the term to the appropriate vocabulary (`.vale/styles/config/vocabularies/`)." +level: error +append: true +ignore: + - GardenerTerms/accept.txt + - ThirdPartyProducts/accept.txt + - TechJargon/accept.txt + - General/accept.txt +filters: + # Uppercase acronyms (e.g. HTTP, YAML, REST) + - '[A-Z]{2,}' + # Uppercase acronym plurals (e.g. CAs, VMs, CRDs, APIs) + - '[A-Z]{2,}s\b' + # camelCase and PascalCase identifiers (e.g. kubeConfig, GardenNamespace) + - '[a-z]+[A-Z][a-zA-Z]+' + - '[A-Z][a-z]+[A-Z][a-zA-Z]+' + # Tokens with digits (e.g. IPv4, log4j, int64, v1alpha1) + - '[a-zA-Z]*[0-9]+[a-zA-Z0-9]*' + # CLI flags (e.g. --flag, -f) + - '--?[a-zA-Z][a-zA-Z0-9-]+' + # File extensions and dot-separated identifiers (e.g. .yaml, cert.gardener.cloud) + - '\.[a-zA-Z]{1,6}\b' + # Underscore-separated identifiers (e.g. config_key, _source) + - '_?[a-zA-Z]+_[a-zA-Z0-9_]+' + # Version strings (e.g. v1, v1.2, v1alpha1, v2beta1) + - '[vV][0-9]+(?:\.[0-9]+)*(?:alpha[0-9]+|beta[0-9]+)?' diff --git a/.vale/styles/Gardener/Terms.yml b/.vale/styles/Gardener/Terms.yml new file mode 100644 index 000000000..2c0dd9392 --- /dev/null +++ b/.vale/styles/Gardener/Terms.yml @@ -0,0 +1,17 @@ +extends: substitution +message: "Use '%s' instead of '%s'." +level: error +action: + name: replace +ignorecase: false +swap: + '(?