Add dead link check CI (#679)

This commit is contained in:
kazogihara 2022-07-21 22:52:35 +09:00 committed by GitHub
parent 2b993e8527
commit 41b5c4133b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 68 additions and 32 deletions

View File

@ -33,8 +33,34 @@ pip3 install mkdocs-material
Run with `mkdocs serve` Run with `mkdocs serve`
## Testing
If you want to check dead links, use markdown-link-check
```sh
npm install --save-dev markdown-link-check
```
Run with
```sh
find . -name \*.md -print0 | xargs -0 -n1 markdown-link-check -q -c markdown-link-check-config.yml
```
on directly under the repository.
OR
Run docker directly under the repository
```sh
docker run -v ${PWD}:/tmp:ro --rm -i --entrypoint "sh" ghcr.io/tcort/markdown-link-check:stable "-c" "find /tmp -name \*.md -print0 | xargs -0 -n1 markdown-link-check -q -c /tmp/markdown-link-check-config.yml"
```
### Maintainers ### Maintainers
- [@0xtim](https://github.com/0xTim) - [@0xtim](https://github.com/0xTim)
- [@mcdappdev](https://github.com/mcdappdev) - [@mcdappdev](https://github.com/mcdappdev)
See https://github.com/vapor/vapor/blob/master/.github/maintainers.md for more information. See https://github.com/vapor/vapor/blob/main/.github/maintainers.md for more information.

View File

@ -1,4 +1,4 @@
name: Build docs and check cloudformation name: Build docs and check cloudformation and dead links
on: on:
pull_request: pull_request:
@ -6,7 +6,7 @@ on:
- main - main
jobs: jobs:
build: check:
name: build docs name: build docs
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@ -21,4 +21,11 @@ jobs:
- name: Setup cloudformation linter - name: Setup cloudformation linter
uses: ScottBrenner/cfn-lint-action@v2.2.1 uses: ScottBrenner/cfn-lint-action@v2.2.1
- name: Run cloudformation lint - name: Run cloudformation lint
run: cfn-lint -t stack.yml run: cfn-lint -t stack.yml
- name: Check dead links
uses: gaurav-nelson/github-action-markdown-link-check@v1
with:
folder-path: '.'
config-file: 'markdown-link-check-config.yml'
use-verbose-mode: 'yes'
use-quiet-mode: 'yes'

View File

@ -1,6 +1,6 @@
# Client # Client
Vapor's client API allows you to make HTTP calls to external resources. It is built on [async-http-client](https://github.com/swift-server/async-http-client) and integrates with the [content](./content.md) API. Vapor's client API allows you to make HTTP calls to external resources. It is built on [async-http-client](https://github.com/swift-server/async-http-client) and integrates with the [content](content.md) API.
## Overview ## Overview
@ -28,7 +28,7 @@ There are methods for each of the HTTP verbs like `get`, `post`, and `delete`. T
### Content ### Content
Vapor's [content](./content.md) API is available for handling data in client requests and responses. To encode content, query parameters or add headers to the request, use the `beforeSend` closure. Vapor's [content](content.md) API is available for handling data in client requests and responses. To encode content, query parameters or add headers to the request, use the `beforeSend` closure.
```swift ```swift
let response = try await req.client.post("https://httpbin.org/status/200") { req in let response = try await req.client.post("https://httpbin.org/status/200") { req in

View File

@ -1,6 +1,6 @@
# Client # Client
Vapor的 `Client` API 允许您使用 HTTP 调用外部资源,它基于 [async-http-client](https://github.com/swift-server/async-http-client) 构建,并集成了 [Content](./content.md) API。 Vapor的 `Client` API 允许您使用 HTTP 调用外部资源,它基于 [async-http-client](https://github.com/swift-server/async-http-client) 构建,并集成了 [Content](content.md) API。
## 概述 ## 概述
@ -32,7 +32,7 @@ HTTP 的常用方法(例如 `get`, `post`, `delete`)都有便捷的调用方式
### Content ### Content
Vapor 的 [Content](./content.md) API 可用于处理客户请求和响应中的数据,如果要在请求体中添加参数或编码,请在 `beforeSend` 闭包中进行。 Vapor 的 [Content](content.md) API 可用于处理客户请求和响应中的数据,如果要在请求体中添加参数或编码,请在 `beforeSend` 闭包中进行。
```swift ```swift
let response = try await req.client.post("https://httpbin.org/status/200") { req in let response = try await req.client.post("https://httpbin.org/status/200") { req in

View File

@ -257,7 +257,7 @@ extension HTML: AsyncResponseEncodable {
} }
} }
``` ```
注意它允许自定义“Content-Type”头查看更多请查阅 [`HTTPHeaders` reference](https://api.vapor.codes/vapor/master/Vapor/) 注意它允许自定义“Content-Type”头查看更多请查阅 [`HTTPHeaders` reference](https://api.vapor.codes/vapor/main/Vapor/)
接下来,你可以在你的路由中使用 `HTML` 作为 response 接下来,你可以在你的路由中使用 `HTML` 作为 response

View File

@ -212,7 +212,7 @@ app.get("hello", ":name") { req -> String in
We can be sure that `req.parameters.get` will never return `nil` here since our route path includes `:name`. However, if you are accessing route parameters in middleware or in code triggered by multiple routes, you will want to handle the possibility of `nil`. We can be sure that `req.parameters.get` will never return `nil` here since our route path includes `:name`. However, if you are accessing route parameters in middleware or in code triggered by multiple routes, you will want to handle the possibility of `nil`.
!!! tip !!! tip
If you want to retrieve URL query params, e.g. `/hello/?name=foo` you need to use Vapor's Content APIs to handle URL encoded data in the URL's query string. See [`Content` reference](/content/) for more details. If you want to retrieve URL query params, e.g. `/hello/?name=foo` you need to use Vapor's Content APIs to handle URL encoded data in the URL's query string. See [`Content` reference](content.md) for more details.
`req.parameters.get` also supports casting the parameter to `LosslessStringConvertible` types automatically. `req.parameters.get` also supports casting the parameter to `LosslessStringConvertible` types automatically.

View File

@ -102,7 +102,7 @@ builder.create()
## MongoDB ## MongoDB
Fluent MongoDB 是一个集成了 [Fluent](../fluent/overview.zh.md) 和 [MongoKitten](https://github.com/OpenKitten/MongoKitten/) 的驱动程序。它利用 Swift 的强类型特性以及 Fluent 使用与 MongoDB 数据库无关的接口。 Fluent MongoDB 是一个集成了 [Fluent](../fluent/overview.md) 和 [MongoKitten](https://github.com/OpenKitten/MongoKitten/) 的驱动程序。它利用 Swift 的强类型特性以及 Fluent 使用与 MongoDB 数据库无关的接口。
MongoDB 中最常见的标识符是 ObjectId。你可以在项目中使用 `@ID(custom: .id)` 自定义标志符。 MongoDB 中最常见的标识符是 ObjectId。你可以在项目中使用 `@ID(custom: .id)` 自定义标志符。
如果需要在 SQL 中使用相同的模型,请不要使用 `ObjectId`。改为使用 `UUID` 如果需要在 SQL 中使用相同的模型,请不要使用 `ObjectId`。改为使用 `UUID`

View File

@ -60,7 +60,7 @@ app.migrations.add(MyMigration(), to: .myDatabase)
vapor run migrate vapor run migrate
``` ```
你也可以[通过 Xcode 运行这个命令](../advanced/commands.zh.md#xcode)。migrate 命令将检查数据库,查看自上次运行以来是否注册了新的迁移。如果有新的迁移,运行它之前会要求确认。 你也可以[通过 Xcode 运行这个命令](../advanced/commands.md#xcode)。migrate 命令将检查数据库,查看自上次运行以来是否注册了新的迁移。如果有新的迁移,运行它之前会要求确认。
### 撤销 ### 撤销
@ -93,6 +93,6 @@ try await app.autoMigrate()
## 下一步 ## 下一步
请查看[schema builder](schema.md) 和 [query builder](query.zh.md) 指南,以了解更多迁移相关的信息。 请查看[schema builder](schema.md) 和 [query builder](query.md) 指南,以了解更多迁移相关的信息。

View File

@ -517,7 +517,7 @@ Models expose a static method `query(on:)` that returns a query builder.
Planet.query(on: database).all() Planet.query(on: database).all()
``` ```
Learn more about querying in the [query](./query.md) section. Learn more about querying in the [query](query.md) section.
## Find ## Find

View File

@ -382,7 +382,7 @@ Note that for this migration to work, we need to be able to reference both the r
## Setting Model Space ## Setting Model Space
To define the [space for a model](/fluent/model/#database-space), pass the space to the `schema(_:space:)` when creating the table. E.g. To define the [space for a model](model.md#database-space), pass the space to the `schema(_:space:)` when creating the table. E.g.
```swift ```swift
try await db.schema("planets", space: "mirror_universe") try await db.schema("planets", space: "mirror_universe")

View File

@ -4,7 +4,7 @@ Willkommen zur Dokumentation von Vapor! Vapor ist ein Web-Framework für Swift,
## Einstieg ## Einstieg
Für die Installation, folge den Anweisungen im Abschnitt [Installation → macOS](install/macos.de.md). Nach der Installation, folge den Anweisungen [Erste Schritte → Hello, world](getting-started/hello-world.de.md) um deine erste Vapor-Anwendungen zu erstellen. Für die Installation, folge den Anweisungen im Abschnitt [Installation → macOS](install/macos.md). Nach der Installation, folge den Anweisungen [Erste Schritte → Hello, world](getting-started/hello-world.md) um deine erste Vapor-Anwendungen zu erstellen.
## Hilfen ## Hilfen

View File

@ -54,4 +54,4 @@ vapor --help
ausführst. Dir sollten nun mehrere Befehl der Toolbox angezeigt werden. ausführst. Dir sollten nun mehrere Befehl der Toolbox angezeigt werden.
Nach der Swift-Installation kannst du mit der Erstellung deiner ersten Vapor-Anwendung beginnen. Folge dazu den Anweisungen im Abschnitt [Erste Schritte → Hello, world](/hallo-world.de.md). Nach der Swift-Installation kannst du mit der Erstellung deiner ersten Vapor-Anwendung beginnen. Folge dazu den Anweisungen im Abschnitt [Erste Schritte → Hello, world](../getting-started/hello-world.md).

View File

@ -29,4 +29,4 @@ brew install vapor
## ##
Nach den Installationen kannst du mit der Erstellung deiner ersten Vapor-Anwendung beginnen. Folge dazu den Anweisungen im Abschnitt [Erste Schritte → Hello, world](../getting-started/hello-world.de.md). Nach den Installationen kannst du mit der Erstellung deiner ersten Vapor-Anwendung beginnen. Folge dazu den Anweisungen im Abschnitt [Erste Schritte → Hello, world](../getting-started/hello-world.md).

View File

@ -1,6 +1,6 @@
# Custom Tags # Custom Tags
You can create custom Leaf tags using the [`LeafTag`](https://api.vapor.codes/leaf-kit/latest/LeafKit/LeafSyntax/LeafTag.html) protocol. You can create custom Leaf tags using the [`LeafTag`](https://api.vapor.codes/leaf-kit/main/LeafKit/LeafTag) protocol.
To demonstrate this, let's take a look at creating a custom tag `#now` that prints the current timestamp. The tag will also support a single, optional parameter for specifying the date format. To demonstrate this, let's take a look at creating a custom tag `#now` that prints the current timestamp. The tag will also support a single, optional parameter for specifying the date format.

View File

@ -45,8 +45,7 @@ This tells Vapor to use the `LeafRenderer` when you call `req.view` in your code
Leaf has an internal cache for rendering pages. When the `Application`'s environment is set to `.development`, this cache is disabled, so that changes to templates take effect immediately. In `.production` and all other environments, the cache is enabled by default; any changes made to templates will not take effect until the application is restarted. Leaf has an internal cache for rendering pages. When the `Application`'s environment is set to `.development`, this cache is disabled, so that changes to templates take effect immediately. In `.production` and all other environments, the cache is enabled by default; any changes made to templates will not take effect until the application is restarted.
!!! warning !!! warning
For Leaf to be able to find the templates when running from Xcode, you must set the [custom working directory](/xcode/#custom-working-directory) for you Xcode workspace. For Leaf to be able to find the templates when running from Xcode, you must set the [custom working directory](../getting-started/xcode.md#custom-working-directory) for you Xcode workspace.
## Folder Structure ## Folder Structure
Once you have configured Leaf, you will need to ensure you have a `Views` folder to store your `.leaf` files in. By default, Leaf expects the views folder to be a `./Resources/Views` relative to your project's root. Once you have configured Leaf, you will need to ensure you have a `Views` folder to store your `.leaf` files in. By default, Leaf expects the views folder to be a `./Resources/Views` relative to your project's root.

View File

@ -31,7 +31,7 @@ let package = Package(
## 配置 ## 配置
将包添加到项目后,通常在 [`configure.swift`](../getting-started/folder-structure.zh.md#configureswift) 中进行配置,这样 Vapor 就可以使用它了。 将包添加到项目后,通常在 [`configure.swift`](../getting-started/folder-structure.md#configureswift) 中进行配置,这样 Vapor 就可以使用它了。
```swift ```swift
import Leaf import Leaf
@ -45,7 +45,7 @@ app.views.use(.leaf)
Leaf 有一个用于渲染页面的内部缓存。当 `Application` 的运行环境设置为 `.development` 时,此缓存被禁用,因此对模板的更改会立即生效。在 `.production` 环境和所有的其它环境中,默认启用缓存;应用重启之前,对模板所做的任何更改都不会生效。 Leaf 有一个用于渲染页面的内部缓存。当 `Application` 的运行环境设置为 `.development` 时,此缓存被禁用,因此对模板的更改会立即生效。在 `.production` 环境和所有的其它环境中,默认启用缓存;应用重启之前,对模板所做的任何更改都不会生效。
!!! 警告 !!! 警告
从 Xcode 运行项目时为了 Leaf 能够找到模板,你必须为你的 Xcode 工作区设置[自定义工作目录](../getting-started/xcode.zh.md#working-directory)。 从 Xcode 运行项目时为了 Leaf 能够找到模板,你必须为你的 Xcode 工作区设置[自定义工作目录](../getting-started/xcode.md#working-directory)。
## 目录结构 ## 目录结构

View File

@ -53,7 +53,7 @@ Leaf also supports many expressions you are familiar with in Swift.
## Context ## Context
In the example from [Getting Started](./getting-started.md), we used a `[String: String]` dictionary to pass data to Leaf. However, you can pass anything that conforms to `Encodable`. It's actually preferred to use `Encodable` structs since `[String: Any]` is not supported. This means you *can not* pass in an array, and should instead wrap it in a struct: In the example from [Getting Started](getting-started.md), we used a `[String: String]` dictionary to pass data to Leaf. However, you can pass anything that conforms to `Encodable`. It's actually preferred to use `Encodable` structs since `[String: Any]` is not supported. This means you *can not* pass in an array, and should instead wrap it in a struct:
```swift ```swift
struct WelcomeContext: Encodable { struct WelcomeContext: Encodable {

View File

@ -2,13 +2,13 @@
Redis can act as a storage provider for caching [session data](../advanced/sessions.md#session-data) such as user credentials. Redis can act as a storage provider for caching [session data](../advanced/sessions.md#session-data) such as user credentials.
If a custom [`RedisSessionsDelegate`](https://api.vapor.codes/redis/master/Redis/RedisSessionsDelegate/) isn't provided, a default will be used. If a custom [`RedisSessionsDelegate`](https://api.vapor.codes/redis/main/Redis/RedisSessionsDelegate/) isn't provided, a default will be used.
## Default Behavior ## Default Behavior
### SessionID Creation ### SessionID Creation
Unless you implement the [`makeNewID()`](https://api.vapor.codes/redis/master/Redis/RedisSessionsDelegate/#redissessionsdelegate.makeNewID()) method in [your own `RedisSessionsDelegate`](#RedisSessionsDelegate), all [`SessionID`](https://api.vapor.codes/vapor/master/Vapor/SessionID/) values will be created by doing the following: Unless you implement the [`makeNewID()`](https://api.vapor.codes/redis/main/Redis/RedisSessionsDelegate/#redissessionsdelegate.makeNewID()) method in [your own `RedisSessionsDelegate`](#redissessionsdelegate), all [`SessionID`](https://api.vapor.codes/vapor/main/Vapor/SessionID/) values will be created by doing the following:
1. Generate 32 bytes of random characters 1. Generate 32 bytes of random characters
1. base64 encode the value 1. base64 encode the value
@ -17,9 +17,9 @@ For example: `Hbxozx8rTj+XXGWAzOhh1npZFXaGLpTWpWCaXuo44xQ=`
### SessionData Storage ### SessionData Storage
The default implementation of `RedisSessionsDelegate` will store [`SessionData`](https://api.vapor.codes/vapor/master/Vapor/SessionData/) as a simple JSON string value using `Codable`. The default implementation of `RedisSessionsDelegate` will store [`SessionData`](https://api.vapor.codes/vapor/main/Vapor/SessionData/) as a simple JSON string value using `Codable`.
Unless you implement the [`makeRedisKey(for:)`](https://api.vapor.codes/redis/master/Redis/RedisSessionsDelegate/#redissessionsdelegate.makeRedisKey(for:)) method in your own `RedisSessionsDelegate`, `SessionData` will be stored in Redis with a key that prefixes the `SessionID` with `vrs-` (**V**apor **R**edis **S**essions) Unless you implement the [`makeRedisKey(for:)`](https://api.vapor.codes/redis/main/Redis/RedisSessionsDelegate/#redissessionsdelegate.makeRedisKey(for:)) method in your own `RedisSessionsDelegate`, `SessionData` will be stored in Redis with a key that prefixes the `SessionID` with `vrs-` (**V**apor **R**edis **S**essions)
For example: `vrs-Hbxozx8rTj+XXGWAzOhh1npZFXaGLpTWpWCaXuo44xQ=` For example: `vrs-Hbxozx8rTj+XXGWAzOhh1npZFXaGLpTWpWCaXuo44xQ=`
@ -39,11 +39,11 @@ app.sessions.use(.redis(delegate: CustomRedisSessionsDelegate()))
## RedisSessionsDelegate ## RedisSessionsDelegate
> API Documentation: [`RedisSessionsDelegate`](https://api.vapor.codes/redis/master/Redis/RedisSessionsDelegate/) > API Documentation: [`RedisSessionsDelegate`](https://api.vapor.codes/redis/main/Redis/RedisSessionsDelegate/)
An object that conforms to this protocol can be used to change how `SessionData` is stored in Redis. An object that conforms to this protocol can be used to change how `SessionData` is stored in Redis.
Only two methods are required to be implemented by a type conforming to the protocol: [`redis(_:store:with:)`](https://api.vapor.codes/redis/master/Redis/RedisSessionsDelegate/#redissessionsdelegate.redis(_:store:with:)) and [`redis(_:fetchDataFor:)`](https://api.vapor.codes/redis/master/Redis/RedisSessionsDelegate/#redissessionsdelegate.redis(_:fetchDataFor:)). Only two methods are required to be implemented by a type conforming to the protocol: [`redis(_:store:with:)`](https://api.vapor.codes/redis/main/Redis/RedisSessionsDelegate/#redissessionsdelegate.redis(_:store:with:)) and [`redis(_:fetchDataFor:)`](https://api.vapor.codes/redis/main/Redis/RedisSessionsDelegate/#redissessionsdelegate.redis(_:fetchDataFor:)).
Both are required, as the way you customize writing the session data to Redis is intrinsically linked to how it is to be read from Redis. Both are required, as the way you customize writing the session data to Redis is intrinsically linked to how it is to be read from Redis.

View File

@ -229,7 +229,7 @@ try app.jwt.signers.use(.rs256(key: .public(pem: rsaPublicKey)))
ECDSA is a more modern algorithm that is similar to RSA. It is considered to be more secure for a given key length than RSA[^1]. However, you should do your own research before deciding. ECDSA is a more modern algorithm that is similar to RSA. It is considered to be more secure for a given key length than RSA[^1]. However, you should do your own research before deciding.
[^1]: [https://sectigostore.com/blog/ecdsa-vs-rsa-everything-you-need-to-know/](https://sectigostore.com/blog/ecdsa-vs-rsa-everything-you-need-to-know/) [^1]: https://sectigostore.com/blog/ecdsa-vs-rsa-everything-you-need-to-know/
Like RSA, you can load ECDSA keys using PEM files: Like RSA, you can load ECDSA keys using PEM files:

View File

@ -10,7 +10,7 @@ The Install section of the docs goes over installing dependencies.
## Package.swift ## Package.swift
The first step to upgrading to Vapor 4 is to update your package's dependencies. Below is an example of an upgraded Package.swift file. You can also check out the updated [template Package.swift](https://github.com/vapor/template/blob/master/Package.swift). The first step to upgrading to Vapor 4 is to update your package's dependencies. Below is an example of an upgraded Package.swift file. You can also check out the updated [template Package.swift](https://github.com/vapor/template/blob/main/Package.swift).
```diff ```diff
-// swift-tools-version:4.0 -// swift-tools-version:4.0

View File

@ -0,0 +1,4 @@
{
"ignorePatterns": [{ "pattern": ".*(localhost|127.0.0.1).*" }],
"aliveStatusCodes": [403, 429, 200]
}