Merge pull request #11129 from backstage/rugvip/vale
vale: update to support v2, common ignore list, and self-contained config
This commit is contained in:
@@ -8,9 +8,6 @@ airbrake
|
||||
Anddddd
|
||||
Apdex
|
||||
api
|
||||
Api
|
||||
apis
|
||||
args
|
||||
asciidoc
|
||||
async
|
||||
Atlassian
|
||||
@@ -19,7 +16,6 @@ autoscaling
|
||||
Autoscaling
|
||||
autoselect
|
||||
Avro
|
||||
aws
|
||||
backported
|
||||
backporting
|
||||
Bigtable
|
||||
@@ -38,7 +34,6 @@ changesets
|
||||
Changesets
|
||||
chanwit
|
||||
Chanwit
|
||||
ci
|
||||
CI/CD
|
||||
classname
|
||||
cli
|
||||
@@ -127,7 +122,6 @@ hoc
|
||||
horizontalpodautoscalers
|
||||
Hostname
|
||||
hotspots
|
||||
html
|
||||
http
|
||||
https
|
||||
Iain
|
||||
@@ -314,7 +308,6 @@ templaters
|
||||
Templaters
|
||||
theia
|
||||
thumbsup
|
||||
toc
|
||||
todo
|
||||
tolerations
|
||||
Tolerations
|
||||
@@ -339,7 +332,6 @@ unregistration
|
||||
untracked
|
||||
upsert
|
||||
upvote
|
||||
url
|
||||
URIs
|
||||
URLs
|
||||
utils
|
||||
@@ -0,0 +1,6 @@
|
||||
StylesPath = .
|
||||
Vocab = Backstage
|
||||
|
||||
[*.md]
|
||||
BasedOnStyles = Vale
|
||||
Vale.Terms = NO
|
||||
@@ -12,10 +12,18 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
# Vale does not support file excludes, so we use the script to generate a list of files instead
|
||||
# The action also does not allow args or a local config file to be passed in, so the files array
|
||||
# also contains an "--config=.github/vale/config.ini" option
|
||||
- name: generate vale args
|
||||
id: generate
|
||||
run: echo "::set-output name=args::$(node scripts/check-docs-quality.js --ci-args)"
|
||||
|
||||
- name: documentation quality check
|
||||
uses: errata-ai/vale-action@v1.4.0
|
||||
# Whitelist excluding ADOPTERS, CHANGELOG and OWNERS (no exclude flag exists)
|
||||
uses: errata-ai/vale-action@v1.5.0
|
||||
with:
|
||||
files: '[".changeset", ".github", "contrib", "docs", "microsite", "packages", "plugins", "CONTRIBUTING.md", "CODE_OF_CONDUCT.md", "GOVERNANCE.md", "README.md"]'
|
||||
# This also contains --config=.github/vale/config.ini ... :/
|
||||
files: '${{ steps.generate.outputs.args }}'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@ If you're contributing to the backend or CLI tooling, be mindful of cross-platfo
|
||||
|
||||
Also be sure to skim through our [ADRs](docs/architecture-decisions) to see if they cover what you're working on. In particular [ADR006: Avoid React.FC and React.SFC](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) `1.4.0` separately and make sure it is accessed by global command.
|
||||
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.
|
||||
|
||||
## Developer Certificate of Origin
|
||||
|
||||
|
||||
@@ -146,7 +146,7 @@ There are a few things to pay attention to, in order to make the documentation s
|
||||
|
||||
API documenter will not recognize arrow functions as functions, but rather as a constant that shows up in the list of exported variables. By declaring functions using the `function` keyword, they will show up in the list of functions. They will also get a much nicer documentation page for the individual function that shows information about parameters and return types.
|
||||
|
||||
This also extends to React components, since API documenter doesn't have any special handling of those. By always defining exported React components using the `function` keyword, we make them show up among the list of functions in the API reference, where they are then easily discoverable through the `(props)` args (which you should be sure to include!).
|
||||
This also extends to React components, since API documenter doesn't have any special handling of those. By always defining exported React components using the `function` keyword, we make them show up among the list of functions in the API reference, where they are then easily discoverable through the `(props)` argument (which you should be sure to include!).
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -64,8 +64,8 @@ if (process.env.HTTPS_PROXY) {
|
||||
|
||||
If your development environment is in the cloud (like with [AWS Cloud9](https://aws.amazon.com/cloud9/) or an instance of [Theia](https://theia-ide.org/)), you will need to update your configuration.
|
||||
|
||||
You will probably need to make some changes in `app-config.yaml` (or another config file like `app-config.local.yaml` if you've created it, see the [configuration doc](https://backstage.io/docs/conf/#supplying-configuration)).
|
||||
The exact values will depend on your setup but for instance, if your public url is `https://your-public-url.com` and the port `3000` and `8080` are open:
|
||||
You will probably need to make some changes in `app-config.yaml` (or another config file like `app-config.local.yaml` if you've created it, see the [configuration doc](https://backstage.io/docs/conf/#supplying-configuration)).
|
||||
The exact values will depend on your setup but for instance, if your public URL is `https://your-public-url.com` and the port `3000` and `8080` are open:
|
||||
|
||||
```yaml
|
||||
app:
|
||||
|
||||
@@ -230,7 +230,7 @@ name.
|
||||
### Test the new provider
|
||||
|
||||
You can `curl -i localhost:7007/api/auth/providerA/start` and which should
|
||||
provide a `302` redirect with a `Location` header. Paste the url from that
|
||||
provide a `302` redirect with a `Location` header. Paste the URL from that
|
||||
header into a web browser and you should be able to trigger the authorization
|
||||
flow.
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ The GitHub provider is a structure with three configuration keys:
|
||||
- `clientSecret`: The client secret tied to the generated client ID.
|
||||
- `enterpriseInstanceUrl` (optional): The base URL for a GitHub Enterprise
|
||||
instance, e.g. `https://ghe.<company>.com`. Only needed for GitHub Enterprise.
|
||||
- `callbackUrl` (optional): The callback url that GitHub will use when
|
||||
- `callbackUrl` (optional): The callback URL that GitHub will use when
|
||||
initiating an OAuth flow, e.g.
|
||||
`https://your-intermediate-service.com/handler`. Only needed if Backstage is
|
||||
not the immediate receiver (e.g. one OAuth app for many backstage instances).
|
||||
|
||||
@@ -161,7 +161,7 @@ $file: ./my-secret.txt
|
||||
|
||||
The `$include` keyword can be used to load configuration values from an external
|
||||
file. It's able to load and parse data from `.json`, `.yml`, and `.yaml` files.
|
||||
It's also possible to include a url fragment (`#`) to point to a value at the
|
||||
It's also possible to include a URL fragment (`#`) to point to a value at the
|
||||
given path in the file, using a dot-separated list of keys.
|
||||
|
||||
For example, the following would read `my-secret-key` from `my-secrets.json`:
|
||||
|
||||
@@ -18,8 +18,8 @@ GitLab, etc.) and passes the files to the generator for next steps.
|
||||
|
||||
There are two kinds of preparers available -
|
||||
|
||||
1. Common Git Preparer - Uses `git clone` on any repository url.
|
||||
2. Url Reader - Uses source code hosting provider's API to download files.
|
||||
1. Common Git Preparer - Uses `git clone` on any repository URL.
|
||||
2. URL Reader - Uses source code hosting provider's API to download files.
|
||||
(Faster and recommended)
|
||||
|
||||
### TechDocs Generator
|
||||
|
||||
@@ -461,7 +461,7 @@ Since the new SDK doesn't use the old way authentication, we don't need the keys
|
||||
|
||||
The new SDK needs the OpenStack Swift connection URL for connecting the Swift.
|
||||
So you need to add a new key called `openStackSwift.swiftUrl` and give the
|
||||
OpenStack Swift url here. Example url should look like that:
|
||||
OpenStack Swift URL here. Example URL should look like that:
|
||||
`https://example.com:6780/swift/v1`
|
||||
|
||||
##### That's it!
|
||||
|
||||
@@ -24,7 +24,7 @@ the code.
|
||||
- [`.github/`](https://github.com/backstage/backstage/tree/master/.github) -
|
||||
Standard GitHub folder. It contains - amongst other things - our workflow
|
||||
definitions and templates. Worth noting is the
|
||||
[styles](https://github.com/backstage/backstage/tree/master/.github/styles)
|
||||
[vale](https://github.com/backstage/backstage/tree/master/.github/vale)
|
||||
sub-folder which is used for a markdown spellchecker.
|
||||
|
||||
- [`.yarn/`](https://github.com/backstage/backstage/tree/master/.yarn) -
|
||||
@@ -212,9 +212,6 @@ future.
|
||||
common for companies to have their own npm registry, and this file makes sure
|
||||
that this folder always uses the public registry.
|
||||
|
||||
- [`.vale.ini`](https://github.com/backstage/backstage/tree/master/.vale.ini) -
|
||||
[Spell checker](https://github.com/errata-ai/vale) for Markdown files.
|
||||
|
||||
- [`.yarnrc`](https://github.com/backstage/backstage/tree/master/.yarnrc) -
|
||||
Enforces "our" version of Yarn.
|
||||
|
||||
|
||||
@@ -34,9 +34,9 @@ a structure with up to six elements:
|
||||
- `baseUrl` (optional): Needed if the Gerrit instance is not reachable at
|
||||
the base of the `host` option (e.g. `https://gerrit.company.com`) set the
|
||||
address here. This is the address that you would open in a browser.
|
||||
- `cloneUrl` (optional): The base url for HTTP clones. Will default to `baseUrl` if
|
||||
- `cloneUrl` (optional): The base URL for HTTP clones. Will default to `baseUrl` if
|
||||
not set. The address used to clone a repo is the `cloneUrl` plus the repo name.
|
||||
- `gitilesBaseUrl` (optional): This is needed for creating a valid user-friendly url
|
||||
- `gitilesBaseUrl` (optional): This is needed for creating a valid user-friendly URL
|
||||
that can be used for browsing the content of the provider. If not set a default
|
||||
value will be created in the same way as the "baseUrl" option. There is no
|
||||
requirement to have Gitiles for the Backstage Gerrit integration but without it
|
||||
|
||||
@@ -48,7 +48,7 @@ you can check [this documentation page][google gcs docs].
|
||||
To use this integration to import entities from a GCS bucket go to the Google
|
||||
console and browse the file you would like to import. Then copy the
|
||||
`Authenticated URL` and paste it into the text box in the `register component`
|
||||
form. This url should look like
|
||||
form. This URL should look like
|
||||
`https://storage.cloud.google.com/<bucket>/<path>/catalog-info.yaml`.
|
||||
|
||||
[google gcs docs]: https://cloud.google.com/docs/authentication/production#auth-cloud-implicit-nodejs
|
||||
|
||||
@@ -52,7 +52,7 @@ calling `${backend-url}/api/proxy/<your-proxy-uri>`. The reason why
|
||||
`backend-url` is referenced is because the backstage backend creates and runs
|
||||
the proxy. Backstage is structured in such a way that you could run the
|
||||
backstage frontend independently of the backend. So when calling your API you
|
||||
need to prepend the backend url to your http call.
|
||||
need to prepend the backend URL to your http call.
|
||||
|
||||
The recommended pattern for calling out to services is to wrap your calls in a
|
||||
[Utility API](../api/utility-apis.md). This section describes the steps to wrap
|
||||
|
||||
@@ -156,7 +156,7 @@ The Swagger UI package by expects to have a route to `/oauth2-redirect.html` whi
|
||||
the redirect callback for the OAuth2 Authorization Code flow, however, this file is not installed
|
||||
by this plugin.
|
||||
|
||||
Grab a copy of [oauth2-redirect.html](https://github.com/swagger-api/swagger-ui/blob/master/dist/oauth2-redirect.html)
|
||||
Grab a copy of [`oauth2-redirect.html`](https://github.com/swagger-api/swagger-ui/blob/master/dist/oauth2-redirect.html)
|
||||
and put it in the `app/public/` directory in order to enable Swagger UI to complete this redirection.
|
||||
|
||||
This also may require you to adjust `Content Security Policy` header settings of your Backstage application, so that the script in `oauth2-redirect.html` can be executed. Since the script is static we can add the hash of it directly to our CSP policy, which we do by adding the following to the `csp` section of the app configuration:
|
||||
|
||||
@@ -35,7 +35,7 @@ export class CostInsightsClient extends CostInsightsApi {
|
||||
|
||||
### Custom Setup
|
||||
|
||||
Default properties such as the title, subtitle and instructions page url can be overridden - even default UI such as chart itself. Additionally, alerts can be extended to support actions such as snoozing or dismissing.
|
||||
Default properties such as the title, subtitle and instructions page URL can be overridden - even default UI such as chart itself. Additionally, alerts can be extended to support actions such as snoozing or dismissing.
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ This can be used to run the kubernetes plugin locally against a mock service.
|
||||
## Steps
|
||||
|
||||
1. Start minikube
|
||||
2. Get the Kubernetes master base url `kubectl cluster-info`
|
||||
2. Get the Kubernetes master base URL `kubectl cluster-info`
|
||||
3. Apply manifests `kubectl apply -f dice-roller-manifests.yaml`
|
||||
4. Get service account token (see below)
|
||||
5. Start Backstage UI and backend
|
||||
|
||||
@@ -13,81 +13,104 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
const { execSync, spawnSync } = require('child_process');
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||
const commandExists = require('command-exists');
|
||||
const { spawnSync } = require('child_process');
|
||||
const { resolve: resolvePath, join: joinPath } = require('path');
|
||||
const fs = require('fs').promises;
|
||||
|
||||
const inheritStdIo = {
|
||||
stdio: 'inherit',
|
||||
};
|
||||
const IGNORED = [
|
||||
/^ADOPTERS\.md$/,
|
||||
/^OWNERS\.md$/,
|
||||
/^.*[/\\]CHANGELOG\.md$/,
|
||||
/^.*[/\\]api-report\.md$/,
|
||||
/^docs[/\\]releases[/\\].*-changelog\.md$/,
|
||||
];
|
||||
|
||||
const LINT_SKIPPED_MESSAGE =
|
||||
'Skipping documentation quality check (vale not found). Install vale linter (https://docs.errata.ai/vale/install) to enable.\n';
|
||||
const LINT_ERROR_MESSAGE = `Language linter (vale) generated errors. Please check the errors and review any markdown files that you changed.
|
||||
Possibly update .github/styles/vocab.txt to add new valid words.\n`;
|
||||
const VALE_NOT_FOUND_MESSAGE = `Language linter (vale) was not found. Please install vale linter (https://docs.errata.ai/vale/install).\n`;
|
||||
const rootDir = resolvePath(__dirname, '..');
|
||||
|
||||
// Note: Make sure the script is run as `node check-docs-quality.js [FILES]` instead of `./check-docs-quality.js [FILES]`
|
||||
// If the script receives arguments (file paths), the script is run exclusively on them. (e.g. when run via pre-commit hook)
|
||||
const getFilesToLint = () => {
|
||||
// Files have been provided as arguments
|
||||
if (process.argv.length > 2) {
|
||||
return process.argv.slice(2);
|
||||
}
|
||||
// Manual listing to avoid dependency install for listing files in CI
|
||||
async function listFiles(dir = '') {
|
||||
const files = await fs.readdir(dir || rootDir);
|
||||
const paths = await Promise.all(
|
||||
files
|
||||
.filter(file => file !== 'node_modules')
|
||||
.map(async file => {
|
||||
const path = joinPath(dir, file);
|
||||
|
||||
let command = `git ls-files | ./node_modules/.bin/shx grep ".md"`;
|
||||
if (process.platform === 'win32') {
|
||||
command = `git ls-files | .\\node_modules\\.bin\\shx grep ".md"`;
|
||||
}
|
||||
if (IGNORED.some(pattern => pattern.test(path))) {
|
||||
return [];
|
||||
}
|
||||
if ((await fs.stat(path)).isDirectory()) {
|
||||
return listFiles(path);
|
||||
}
|
||||
if (!path.endsWith('.md')) {
|
||||
return [];
|
||||
}
|
||||
return path;
|
||||
}),
|
||||
);
|
||||
return paths.flat();
|
||||
}
|
||||
|
||||
// Note this ignore list only applies locally, CI runs `.github/workflows/docs-quality-checker.yml`
|
||||
const ignored = ['', 'ADOPTERS.md', 'OWNERS.md'];
|
||||
|
||||
return execSync(command, {
|
||||
stdio: ['ignore', 'pipe', 'inherit'],
|
||||
})
|
||||
.toString()
|
||||
.split('\n')
|
||||
.filter(el => !ignored.includes(el));
|
||||
};
|
||||
|
||||
// Proceed with the script only if Vale linter is installed. Limit the friction and surprises caused by the script.
|
||||
// On CI, we want to ensure vale linter is run.
|
||||
commandExists('vale')
|
||||
.catch(() => {
|
||||
// Proceed with the script only if Vale linter is installed. Limit the friction and surprises
|
||||
// caused by the script. In CI, we want to ensure vale linter is run.
|
||||
async function exitIfMissingVale() {
|
||||
try {
|
||||
await require('command-exists')('vale');
|
||||
} catch (e) {
|
||||
if (process.env.CI) {
|
||||
console.log(VALE_NOT_FOUND_MESSAGE);
|
||||
console.log(
|
||||
`Language linter (vale) was not found. Please install vale linter (https://docs.errata.ai/vale/install).\n`,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
console.log(LINT_SKIPPED_MESSAGE);
|
||||
console.log(`Language linter (vale) generated errors. Please check the errors and review any markdown files that you changed.
|
||||
Possibly update .github/vale/Vocab/Backstage/accept.txt to add new valid words.\n`);
|
||||
process.exit(0);
|
||||
})
|
||||
.then(() => {
|
||||
const filesToLint = getFilesToLint();
|
||||
}
|
||||
}
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
// Windows
|
||||
try {
|
||||
const output = spawnSync('vale', filesToLint, inheritStdIo);
|
||||
async function runVale(files) {
|
||||
const result = spawnSync(
|
||||
'vale',
|
||||
['--config', resolvePath(rootDir, '.github/vale/config.ini'), ...files],
|
||||
{
|
||||
stdio: 'inherit',
|
||||
},
|
||||
);
|
||||
|
||||
// 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.log(LINT_ERROR_MESSAGE);
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
process.exit(1);
|
||||
}
|
||||
} else {
|
||||
// Unix
|
||||
const output = spawnSync('vale', filesToLint, inheritStdIo);
|
||||
if (output.status !== 0) {
|
||||
console.log(LINT_ERROR_MESSAGE);
|
||||
process.exit(1);
|
||||
}
|
||||
if (result.status !== 0) {
|
||||
// TODO(Rugvip): This logic was here before but seems a bit odd, could use some verification on windows.
|
||||
// If it contains system level error. In this case vale does not exist.
|
||||
if (process.platform !== 'win32' || result.error) {
|
||||
console.log(`Language linter (vale) generated errors. Please check the errors and review any markdown files that you changed.
|
||||
Possibly update .github/vale/Vocab/Backstage/accept.txt to add new valid words.\n`);
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const files = await listFiles();
|
||||
|
||||
if (process.argv.includes('--ci-args')) {
|
||||
process.stdout.write(
|
||||
// Workaround for not being able to pass arguments to the vale action
|
||||
JSON.stringify(['--config=.github/vale/config.ini', ...files]),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
await exitIfMissingVale();
|
||||
|
||||
const success = await runVale(files);
|
||||
if (!success) {
|
||||
process.exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(error => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user