feat: TechDocs - Add vale linter to check words quality in md files. (#2631)

* fix(docs): typos which were reflacted from vale linter's command

* feat: Implement Vale linter (#2031)
Initialize .vale.ini file
Add 'lint:docs' script to package.json, to lint all md files except the ones which are located in node_modules
Generate 'vocab.txt' by using command 'yarn run lint:docs' | grep -o ''[a-z A-Z]*'' | grep -o '[a-z A-Z]*' | sort | uniq > .github/styles/vocab.txt
Add steps to github workflow 'master' to check docs quality

* chore: Separate workflow for quality checking

* chore: Added 'shx' dev dependency to support grep command in cross platform

* feat: Add script to operate same quality check process on different platform

* ignore: remove lint:docs from lint-stages which was added for experiment purpose

* fix: check-all-files on push event & check-changed-files on pull_request event

* chore(CI): triggle workflow only when there is any updates in .md file(s) on pull request

* fix: use spawnSync to solve 'The command line is too long.' error

* fix: github workflow syntax

* fix: prettier error

* chore: add vale command directly to lint-staged

* chore: use shebang for easy access

* fix: windows script issue & remove shebang

* chore: Add shebang flag

* chore: better error message related to vale

* chore: mention vale linter in documentation

* fix: spelling errors & add keywords to vocab.txt
This commit is contained in:
Mayursinh Sarvaiya
2020-10-02 10:50:47 +05:30
committed by GitHub
parent 73440c7d9a
commit 5c6a0356c0
22 changed files with 336 additions and 21 deletions
+203
View File
@@ -0,0 +1,203 @@
abc
Apdex
api
Api
apis
args
asciidoc
async
Avro
backrub
Balachandran
Bigtable
Blackbox
bool
boolean
Chai
changeset
changesets
Changesets
changset
chanwit
Chanwit
cisphobia
cissexist
classname
cli
cncf
codeblocks
Codecov
codehilite
Codehilite
codeowners
config
Config
configs
const
cookiecutter
css
dariddler
deadnaming
destructured
dev
devs
discoverability
Discoverability
dls
docgen
Dockerfile
Dockerize
dockerode
Docusaurus
eg
Ek
env
Env
eslint
facto
failover
Figma
Firekube
Fredrik
github
Github
Gitlab
graphql
graphviz
Hackathons
haproxy
heroku
Hostname
http
https
img
incentivised
inlinehilite
interop
javascript
Javascript
jq
js
json
jsx
Kaewkasi
Knex
kubectl
kubernetes
learnings
lerna
Lerna
magiclink
mailto
Malus
md
microsite
middleware
minikube
Minikube
misgendering
mkdocs
Mkdocs
monorepo
Monorepo
monorepos
msw
namespace
Namespaces
neuro
newrelic
nginx
Niklas
nohoist
nonces
npm
nvm
oauth
Oauth
Okta
Oldsberg
onboarding
Onboarding
pagerduty
Patrik
Phoen
plantuml
Pomaceous
postgres
pre
prebaked
preconfigured
Preprarer
Prerequisities
productional
Protobuf
proxying
Proxying
pygments
pymdownx
Raghunandan
rankdir
readme
Readme
Redash
repo
Repo
repos
rerender
rollbar
Rollbar
Rollup
Rosaceae
rst
rsync
ruleset
sam
scaffolded
scaffolder
Scaffolder
semlas
Serverless
Sinon
smartsymobls
sparklines
Spotifiers
spotify
Spotify
squidfunk
src
subkey
superfences
Superfences
talkdesk
Talkdesk
tasklist
techdocs
templated
templater
Templater
templaters
Templaters
Thauer
theres
toc
tolerations
Tolerations
toolsets
touchpoints
ui
upvote
url
utils
validators
Voi
Wealthsimple
Weaveworks
xyz
yaml
Zalando
Zhou
Billett
cloudbuild
Grafana
Iain
Snyk
@@ -0,0 +1,18 @@
name: Check Markdown files quality
on:
pull_request:
branches: [master]
paths:
- '**.md'
jobs:
check-all-files:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: documentation quality check
uses: errata-ai/vale-action@v1.3.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+4
View File
@@ -0,0 +1,4 @@
StylesPath = .github/styles
[*.md]
BasedOnStyles = Vale
+2
View File
@@ -76,6 +76,8 @@ If you're contributing to the backend or CLI tooling, be mindful of cross-platfo
Also be sure to skim through our [ADRs](https://github.com/spotify/backstage/tree/master/docs/architecture-decisions) to see if they cover what you're working on. In particular [ADR006: Avoid React.FC and React.SFC](https://github.com/spotify/backstage/blob/master/docs/architecture-decisions/adr006-avoid-react-fc.md) is one to look out for.
If there are any updates in `markdown` file please make sure to run `yarn run lint:docs`. Though it is checked on `lint-staged`. It is required to install [vale](https://docs.errata.ai/vale/install) separately and make sure it is accessed by global command.
# Creating Changesets
We use [changesets](https://github.com/atlassian/changesets) to help us prepare releases. It helps us make sure that every package affected by a change gets a proper version number and an entry in its `CHANGELOG.md`. To make the process of generating releases easy. it helps when contributors include changesets with their pull requests.
+1 -1
View File
@@ -4,7 +4,7 @@
Deploying to heroku is relatively easy following these steps.
First, make sure you have the [heroku CLI installed](https://devcenter.heroku.com/articles/heroku-cli) and log into it as well as loging into Heroku's [container registry](https://devcenter.heroku.com/articles/container-registry-and-runtime).
First, make sure you have the [heroku CLI installed](https://devcenter.heroku.com/articles/heroku-cli) and log into it as well as login into Heroku's [container registry](https://devcenter.heroku.com/articles/container-registry-and-runtime).
```bash
$ heroku login
@@ -88,7 +88,7 @@ Some good examples exist here:
- https://github.com/spotify/backstage/blob/master/plugins/scaffolder-backend/src/scaffolder/stages/prepare/file.ts
- https://github.com/spotify/backstage/blob/master/plugins/scaffolder-backend/src/scaffolder/stages/prepare/github.ts
### Registerinng your own Preparer
### Registering your own Preparer
You can register the preparer that you have created with the `PreparerBuilder`
by using the `PreparerKey` from the Catalog, for example like this:
+1 -1
View File
@@ -35,4 +35,4 @@ well as a selection of Python Markdown extensions that TechDocs supports.
Not right now. We are currently using MkDocs to generate the documentation from
source, so the files have to be in Markdown format. However, in the future we
want to support other static site generators which will make it possible to use
otherfile formats.
other file formats.
+1 -1
View File
@@ -166,7 +166,7 @@ because it fulfills all the principles above:
**Fulfills Input/Output Principle**: Verifies the output changes when the
input changes
**Fufills Blackbox Principle**: Does not verify _how_ the `<Loading />`
**Fulfills Blackbox Principle**: Does not verify _how_ the `<Loading />`
component is mounted, just that it is mounted in response to the input.
**Fulfills Scalability Principle**: If we decide to refactor the entire way
+1 -1
View File
@@ -73,7 +73,7 @@ Referenced by: [alert\$](#alert).
### Observer
This file contains non-react related core types used throught Backstage.
This file contains non-react related core types used through Backstage.
Observer interface for consuming an Observer, see TC39.
+1 -1
View File
@@ -135,7 +135,7 @@ Referenced by: [activeThemeId\$](#activethemeid).
### Observer
This file contains non-react related core types used throught Backstage.
This file contains non-react related core types used through Backstage.
Observer interface for consuming an Observer, see TC39.
+1 -1
View File
@@ -93,7 +93,7 @@ Referenced by: [error\$](#error).
### Observer
This file contains non-react related core types used throught Backstage.
This file contains non-react related core types used through Backstage.
Observer interface for consuming an Observer, see TC39.
@@ -11,7 +11,8 @@ The following Utility API implements this type:
### createAuthRequester()
A utility for showing login popups or similar things, and merging together
multiple requests for different scopes into one request that inclues all scopes.
multiple requests for different scopes into one request that includes all
scopes.
The passed in options provide information about the login provider, and how to
handle auth requests.
@@ -30,7 +31,7 @@ createAuthRequester&lt;AuthResponse&gt;(
### authRequest\$()
Observers panding auth requests. The returned observable will emit all current
Observers pending auth requests. The returned observable will emit all current
active auth request, at most one for each created auth requester.
Each request has its own info about the login provider, forwarded from the auth
@@ -156,7 +157,7 @@ Referenced by: [authRequest\$](#authrequest).
### Observer
This file contains non-react related core types used throught Backstage.
This file contains non-react related core types used through Backstage.
Observer interface for consuming an Observer, see TC39.
+1 -1
View File
@@ -81,7 +81,7 @@ Referenced by: [sessionState\$](#sessionstate).
### Observer
This file contains non-react related core types used throught Backstage.
This file contains non-react related core types used through Backstage.
Observer interface for consuming an Observer, see TC39.
@@ -62,7 +62,7 @@ Referenced by: [sessionState\$](#sessionstate).
### Observer
This file contains non-react related core types used throught Backstage.
This file contains non-react related core types used through Backstage.
Observer interface for consuming an Observer, see TC39.
+3 -3
View File
@@ -35,7 +35,7 @@ remove(key: string): Promise&lt;void&gt;
### set()
Save persistant data, and emit messages to anyone that is using observe\$ for
Save persistent data, and emit messages to anyone that is using observe\$ for
this key
<pre>
@@ -85,7 +85,7 @@ Referenced by: [observe\$](#observe), [StorageApi](#storageapi).
### Observer
This file contains non-react related core types used throught Backstage.
This file contains non-react related core types used through Backstage.
Observer interface for consuming an Observer, see TC39.
@@ -129,7 +129,7 @@ export interface StorageApi {
remove(key: string): Promise&lt;void&gt;;
/**
* Save persistant data, and emit messages to anyone that is using observe$ for this key
* Save persistent data, and emit messages to anyone that is using observe$ for this key
*
* @param {String} key Unique key associated with the data.
*/
+6 -1
View File
@@ -16,6 +16,7 @@
"test": "lerna run test --since origin/master -- --coverage",
"test:all": "lerna run test -- --coverage",
"lint": "lerna run lint --since origin/master --",
"lint:docs": "node ./scripts/check-docs-quality",
"lint:all": "lerna run lint --",
"lint:type-deps": "node scripts/check-type-dependencies.js",
"docgen": "lerna run docgen",
@@ -46,7 +47,8 @@
"lerna": "^3.20.2",
"lint-staged": "^10.1.0",
"prettier": "^2.0.5",
"recursive-readdir": "^2.2.2"
"recursive-readdir": "^2.2.2",
"shx": "^0.3.2"
},
"husky": {
"hooks": {
@@ -61,6 +63,9 @@
],
"*.{json,md}": [
"prettier --write"
],
"*.md": [
"vale"
]
},
"jest": {
@@ -23,7 +23,7 @@ The component itself only handles the display area, so you can use standard JS t
This will step through each of the keys and based on their types display them in a logical way.
### Primatives
### Primitives
Any non complex value will be displayed using `{value}` which will just output the value as text.
@@ -1,7 +1,7 @@
## hello mock docs
!!! test
Testing somethin
Testing something
Abbreviations:
Some text about MOCDOC
+1 -1
View File
@@ -18,7 +18,7 @@ Right now, the following API formats are supported:
- [AsyncAPI](https://www.asyncapi.com/docs/specifications/latest/)
- [GraphQL](https://graphql.org/learn/schema/)
Other formats are displayed as plain text, but this can easily be extented.
Other formats are displayed as plain text, but this can easily be extended.
To fill the catalog with APIs, [provide entities of kind API](https://backstage.io/docs/features/software-catalog/descriptor-format#kind-api).
To link that an component implements an API, see [`implementsApis` property on components](https://backstage.io/docs/features/software-catalog/descriptor-format#specimplementsapis-optional).
+1 -1
View File
@@ -81,7 +81,7 @@ costInsights:
In the `Cost Overview` panel, users can choose from a dropdown of business metrics to see costs as they relate to a metric, such as daily active users. Metrics must be defined as keys on the `metrics` field. A user-friendly name is **required**. Metrics will be provided to the `getDailyCost` and `getProjectCosts` API methods via the `metric` parameter.
**Note:** Cost Insights displays daily cost without a metric by default. The dropdown text for this default can be overriden by assigning it a value on the `dailyCost` field.
**Note:** Cost Insights displays daily cost without a metric by default. The dropdown text for this default can be overridden by assigning it a value on the `dailyCost` field.
```yaml
## ./app-config.yaml
+68
View File
@@ -0,0 +1,68 @@
#!/usr/bin/env node
/*
* Copyright 2020 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const { execSync, spawnSync } = require('child_process');
const path = require('path');
const listFilesTrackedByGit = 'git ls-files';
const inheritStdIo = {
stdio: 'inherit',
};
const ERROR_MESSAGE =
'Please install vale linter(https://docs.errata.ai/vale/install). Ignore this message if already installed.\n';
// xargs is not supported by shx.
if (process.platform === 'win32') {
const validMDFilesCommand = `${listFilesTrackedByGit} | .\\node_modules\\.bin\\shx grep ".md"`;
try {
// get list of all md files except in directories of gitignore.
let filesToLint = execSync(validMDFilesCommand, {
stdio: ['ignore', 'pipe', 'inherit'],
});
// set all file(s) path as absolute path
filesToLint = filesToLint
.toString()
.split('\n')
.map(filepath => (filepath ? path.join(process.cwd(), filepath) : null))
.filter(Boolean);
const output = spawnSync('vale', filesToLint, inheritStdIo);
// if the command does not succeed
if (output.status !== 0) {
// if it contains system level error. [in this case vale does not exist]
if (output.error) {
console.error(ERROR_MESSAGE);
}
process.exit(1);
}
} catch (e) {
console.error(e.message);
process.exit(1);
}
} else {
const validMDFilesCommand = `${listFilesTrackedByGit} | ./node_modules/.bin/shx grep ".md"`;
// use xargs
try {
execSync(`${validMDFilesCommand} | xargs vale`, inheritStdIo);
} catch (e) {
console.error(ERROR_MESSAGE);
process.exit(1);
}
}
+15 -1
View File
@@ -10430,6 +10430,11 @@ es6-iterator@^2.0.3, es6-iterator@~2.0.3:
es5-ext "^0.10.35"
es6-symbol "^3.1.1"
es6-object-assign@^1.0.3:
version "1.1.0"
resolved "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz#c2c3582656247c39ea107cb1e6652b6f9f24523c"
integrity sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=
es6-promise@^4.0.3:
version "4.2.8"
resolved "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
@@ -20703,7 +20708,7 @@ shell-quote@1.7.2:
resolved "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2"
integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==
shelljs@^0.8.2, shelljs@^0.8.3:
shelljs@^0.8.1, shelljs@^0.8.2, shelljs@^0.8.3:
version "0.8.4"
resolved "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz#de7684feeb767f8716b326078a8a00875890e3c2"
integrity sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==
@@ -20724,6 +20729,15 @@ shortid@^2.2.14:
dependencies:
nanoid "^2.1.0"
shx@^0.3.2:
version "0.3.2"
resolved "https://registry.npmjs.org/shx/-/shx-0.3.2.tgz#40501ce14eb5e0cbcac7ddbd4b325563aad8c123"
integrity sha512-aS0mWtW3T2sHAenrSrip2XGv39O9dXIFUqxAEWHEOS1ePtGIBavdPJY1kE2IHl14V/4iCbUiNDPGdyYTtmhSoA==
dependencies:
es6-object-assign "^1.0.3"
minimist "^1.2.0"
shelljs "^0.8.1"
side-channel@^1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.2.tgz#df5d1abadb4e4bf4af1cd8852bf132d2f7876947"