如何使用 Git 作为 Contract 和 Stub 的存储?
在多语言世界中,有些语言不使用二进制存储,如 Artifactory 和 Nexus 可以。从 Spring Cloud Contract 版本 2.0.0 开始,我们提供 在 SCM (Source Control Management) 存储库中存储合同和存根的机制。目前, 唯一支持的 SCM 是 Git。
存储库必须具有以下设置 (您可以从此处查看):
.
└── META-INF
└── com.example
└── beer-api-producer-git
└── 0.0.1-SNAPSHOT
├── contracts
│ └── beer-api-consumer
│ ├── messaging
│ │ ├── shouldSendAcceptedVerification.groovy
│ │ └── shouldSendRejectedVerification.groovy
│ └── rest
│ ├── shouldGrantABeerIfOldEnough.groovy
│ └── shouldRejectABeerIfTooYoung.groovy
└── mappings
└── beer-api-consumer
└── rest
├── shouldGrantABeerIfOldEnough.json
└── shouldRejectABeerIfTooYoung.json
在文件夹下:META-INF
-
我们按 (如 ) 对应用程序进行分组。
groupId
com.example
-
每个应用程序都由其 (表示,例如 )。
artifactId
beer-api-producer-git
-
接下来,每个应用程序都按其版本(如 )进行组织。开始 从 Spring Cloud Contract version 中,您可以指定如下版本 (假设您的版本遵循语义版本控制):
0.0.1-SNAPSHOT
2.1.0
-
+
或:要查找存根的最新版本(假设快照 始终是给定修订号的最新工件)。这意味着:latest
-
如果您有 、 、 和 ,我们假设 最新的是 。
1.0.0.RELEASE
2.0.0.BUILD-SNAPSHOT
2.0.0.RELEASE
2.0.0.BUILD-SNAPSHOT
-
如果您有 和 ,则我们假定最新的是 。
1.0.0.RELEASE
2.0.0.RELEASE
2.0.0.RELEASE
-
如果您有名为 或 的版本,我们将选择该文件夹。
latest
+
-
-
release
:查找存根的最新版本。这意味着:-
如果你有 , ,并且我们假设 最新的是 。
1.0.0.RELEASE
2.0.0.BUILD-SNAPSHOT
2.0.0.RELEASE
2.0.0.RELEASE
-
如果您有一个名为 的版本,我们将选择该文件夹。
release
-
-
最后,有两个文件夹:
-
contracts
:好的做法是存储每个 consumer 在具有 consumer 名称(如 )的文件夹中。这样,您 可以使用该功能。进一步的目录结构是任意的。beer-api-consumer
stubs-per-consumer
-
mappings
:Maven 或 Gradle Spring Cloud Contract 插件推送 此文件夹中的存根服务器映射。在使用者端,Stub Runner 会扫描此文件夹 以启动具有存根定义的存根服务器。文件夹结构是一个副本 的 1 个。contracts
协议约定
要控制合约来源的类型和位置(无论 binary storage 或 SCM 存储库),您可以在 存储库。Spring Cloud Contract 迭代已注册的协议解析器 并尝试获取 Contract (通过使用插件) 或 stub (从 Stub Runner)。
对于 SCM 功能,目前我们支持 Git 存储库。要使用它,
在需要放置存储库 URL 的属性中,您必须为存储库 URL 添加前缀
带有 .下面的清单显示了一些示例:git://
git://file:///foo/bar
git://https://github.com/spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git
git://[email protected]:spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git
制作人
对于生产者,要使用 SCM(源代码控制管理)方法,我们可以重用
我们用于外部合约的机制相同。我们路由 Spring Cloud Contract
使用以
协议。git://
您必须在 Maven 中手动添加目标或在
Gradle 的 Gradle 中。我们不会将存根推送到你的 git 中
存储 库。pushStubsToScm pushStubsToScm origin |
以下清单包括 Maven 和 Gradle 构建文件的相关部分:
- Maven 系列
-
<plugin> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-contract-maven-plugin</artifactId> <version>${spring-cloud-contract.version}</version> <extensions>true</extensions> <configuration> <!-- Base class mappings etc. --> <!-- We want to pick contracts from a Git repository --> <contractsRepositoryUrl>git://https://github.com/spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git</contractsRepositoryUrl> <!-- We reuse the contract dependency section to set up the path to the folder that contains the contract definitions. In our case the path will be /groupId/artifactId/version/contracts --> <contractDependency> <groupId>${project.groupId}</groupId> <artifactId>${project.artifactId}</artifactId> <version>${project.version}</version> </contractDependency> <!-- The contracts mode can't be classpath --> <contractsMode>REMOTE</contractsMode> </configuration> <executions> <execution> <phase>package</phase> <goals> <!-- By default we will not push the stubs back to SCM, you have to explicitly add it as a goal --> <goal>pushStubsToScm</goal> </goals> </execution> </executions> </plugin>
- Gradle
-
contracts { // We want to pick contracts from a Git repository contractDependency { stringNotation = "${project.group}:${project.name}:${project.version}" } /* We reuse the contract dependency section to set up the path to the folder that contains the contract definitions. In our case the path will be /groupId/artifactId/version/contracts */ contractRepository { repositoryUrl = "git://https://github.com/spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git" } // The mode can't be classpath contractsMode = "REMOTE" // Base class mappings etc. } /* In this scenario we want to publish stubs to SCM whenever the `publish` task is invoked */ publish.dependsOn("publishStubsToScm")
您还可以进一步自定义 gradle 任务。在以下示例中,
该任务经过自定义,可从本地 Git 存储库中选择 Contract:publishStubsToScm
publishStubsToScm {
// We want to modify the default set up of the plugin when publish stubs to scm is called
// We want to pick contracts from a Git repository
contractDependency {
stringNotation = "${project.group}:${project.name}:${project.version}"
}
/*
We reuse the contract dependency section to set up the path
to the folder that contains the contract definitions. In our case the
path will be /groupId/artifactId/version/contracts
*/
contractRepository {
repositoryUrl = "git://file://${new File(project.rootDir, "../target")}/contract_empty_git/"
}
// We set the contracts mode to `LOCAL`
contractsMode = "LOCAL"
}
- 重要
-
从 开始,以前用于自定义的闭包不再可用。应直接应用设置 中,如前面的示例所示。
2.3.0.RELEASE
customize{}
publishStubsToScm
publishStubsToScm
使用这样的设置:
-
将 git 项目克隆到临时目录
-
SCM 存根下载器将转到文件夹 以查找合同。例如,对于 ,路径将为 。
META-INF/groupId/artifactId/version/contracts
com.example:foo:1.0.0
META-INF/com.example/foo/1.0.0/contracts
-
测试是从 Contract 生成的。
-
存根是从 Contract 创建的。
-
测试通过后,存根将提交到克隆的存储库中。
-
最后,将推送发送到该存储库的 .
origin
本地存储 Contract 的 Producer
使用 SCM 作为存根和 Contract 目标的另一种选择是将 与生产者在本地签订合同,并且仅将合同和存根推送到 SCM。 以下项目显示了使用 Maven 和 Gradle 实现此目的所需的设置。
使用这样的设置:
-
从 default 目录中选取 Contract 。
src/test/resources/contracts
-
测试是从 Contract 生成的。
-
存根是从 Contract 创建的。
-
测试通过后:
-
git 项目被克隆到一个临时目录。
-
存根和合同将在克隆的存储库中提交。
-
-
最后,推送到该存储库的 .
origin
将与 Producer 的 Contract 和存根保存在外部存储库中
您还可以将合同保留在创建者存储库中,但将存根保留在外部 git 存储库中。 当您想使用基本消费者-生产者协作流但不能使用时,这最有用 使用构件存储库存储存根。
为此,请使用通常的创建者设置,然后添加目标并设置为要保留存根的存储库。pushStubsToScm
contractsRepositoryUrl
消费者
在消费者端,当传递参数时,
从注解中,
JUnit 4 规则、JUnit 5 扩展或属性,则可以传递
SCM 存储库,以协议为前缀。以下示例显示了如何执行此操作:repositoryRoot
@AutoConfigureStubRunner
git://
@AutoConfigureStubRunner(
stubsMode="REMOTE",
repositoryRoot="git://https://github.com/spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git",
ids="com.example:bookstore:0.0.1.RELEASE"
)
使用这样的设置:
-
git 项目被克隆到一个临时目录。
-
SCM 存根下载器将转到文件夹 查找存根定义和协定。例如,对于 ,路径将为 。
META-INF/groupId/artifactId/version/
com.example:foo:1.0.0
META-INF/com.example/foo/1.0.0/
-
Stub 服务器启动并馈送 Mapping。
-
消息收发定义在消息收发测试中读取和使用。