

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用 Maven 快照
<a name="maven-snapshots"></a>

 Maven *快照*是 Maven 程序包的特殊版本，该版本引用了最新的生产分支代码。它是先于最终发布版本的开发版本。您可以通过附加到程序包版本的后缀 `SNAPSHOT` 来识别 Maven 程序包的快照版本。例如，版本 `1.1` 的快照是 `1.1-SNAPSHOT`。有关更多信息，请参阅 Apache Maven Project 网站上的 [What is a SNAPSHOT version?](https://maven.apache.org/guides/getting-started/index.html#What_is_a_SNAPSHOT_version)。

 AWS CodeArtifact 支持发布和使用 Maven 快照。仅支持使用基于时间的版本号的唯一快照。 CodeArtifact 不支持 Maven 2 客户端生成的非唯一快照。您可以将支持的 Maven 快照发布到任何 CodeArtifact 存储库。

**Topics**
+ [快照发布在 CodeArtifact](#maven-snapshot-publishing)
+ [使用快照版本](#maven-consuming-snapshot-versions)
+ [删除快照版本](#maven-deleting-snapshot-versions)
+ [使用 curl 进行快照发布](#maven-snapshot-publishing-curl)
+ [快照和外部连接](#maven-snapshot-external-connections)
+ [快照和上游存储库](#maven-snapshot-upstream-repositories)

## 快照发布在 CodeArtifact
<a name="maven-snapshot-publishing"></a>

AWS CodeArtifact 支持客户端（例如`mvn`）在发布快照时使用的请求模式。因此，您无需详细了解 Maven 快照的发布方式，即可按照构建工具或程序包管理器的文档进行操作。如果你正在做更复杂的事情，本节将详细介绍如何 CodeArtifact 处理快照。

 将 Maven 快照发布到 CodeArtifact 存储库时，其先前版本将保留在名为 build 的新版本中。每次发布 Maven 快照时，都会创建一个新的构建版本。快照的所有先前版本都保留在其构建版本中。发布 Maven 快照时，其程序包版本状态将设置为 `Published`，包含先前版本的版本的构建的状态设置为 `Unlisted`。此行为仅适用于程序包版本使用 `-SNAPSHOT` 作为后缀的 Maven 程序包版本。

例如，名为的 maven 包的快照版本`com.mycompany.myapp:pkg-1`会上传到名为的 CodeArtifact 存储库。`my-maven-repo`快照版本是 `1.0-SNAPSHOT`。到目前为止，尚未发布 `com.mycompany.myapp:pkg-1` 的任何版本。首先，在以下路径发布初始构建的资产：

```
PUT maven/my-maven-repo/com/mycompany/myapp/pkg-1/1.0-SNAPSHOT/pkg-1-1.0-20210728.194552-1.jar
PUT maven/my-maven-repo/com/mycompany/myapp/pkg-1/1.0-SNAPSHOT/pkg-1-1.0-20210728.194552-1.pom
```

请注意，由发布快照版本的客户端生成时间戳 `20210728.194552-1`。

上传 .pom 和 .jar 文件后，存储库中唯一存在的 `com.mycompany.myapp:pkg-1` 版本是 `1.0-20210728.194552-1`。即使在前面的路径中指定的版本是 `1.0-SNAPSHOT`，也会发生这种情况。此时的程序包版本状态为 `Unfinished`。

```
aws codeartifact list-package-versions --domain my-domain --repository \
  my-maven-repo --package pkg-1 --namespace com.mycompany.myapp --format maven
{
    "versions": [
        {
            "version": "1.0-20210728.194552-1",
            "revision": "GipMW+599JmwTcTLaXo9YvDsVQ2bcrrk/02rWJhoKUU=",
            "status": "Unfinished"
        }
    ],
    "defaultDisplayVersion": null,
    "format": "maven",
    "package": "pkg-1",
    "namespace": "com.mycompany.myapp"
}
```

接下来，客户端上传程序包版本的 `maven-metadata.xml` 文件：

```
PUT my-maven-repo/com/mycompany/myapp/pkg-1/1.0-SNAPSHOT/maven-metadata.xml
```

成功上传 maven-metadata.xml 文件后， CodeArtifact 会创建`1.0-SNAPSHOT`包版本并将`1.0-20210728.194552-1`版本设置为`Unlisted`。

```
aws codeartifact list-package-versions --domain my-domain --repository \
  my-maven-repo --package pkg-1 --namespace com.mycompany.myapp --format maven
{
    "versions": [
        {
            "version": "1.0-20210728.194552-1",
            "revision": "GipMW+599JmwTcTLaXo9YvDsVQ2bcrrk/02rWJhoKUU=",
            "status": "Unlisted"
        },
        {
            "version": "1.0-SNAPSHOT",
            "revision": "tWu8n3IX5HR82vzVZQAxlwcvvA4U/+S80edWNAkil24=",
            "status": "Published"
        }
    ],
    "defaultDisplayVersion": "1.0-SNAPSHOT",
    "format": "maven",
    "package": "pkg-1",
    "namespace": "com.mycompany.myapp"
}
```

此时，可以在构建中使用快照版本 `1.0-SNAPSHOT`。虽然存储库 `my-maven-repo` 中有 `com.mycompany.myapp:pkg-1` 的两个版本，但它们都包含相同的资产。

```
aws codeartifact list-package-version-assets --domain my-domain --repository \
  my-maven-repo --format maven --namespace com.mycompany.myapp \
 --package pkg-1 --package-version 1.0-SNAPSHOT--query 'assets[*].name'
[ 
     "pkg-1-1.0-20210728.194552-1.jar",
     "pkg-1-1.0-20210728.194552-1.pom"
]
```

将 `--package-version` 参数更改为 `1.0-20210728.194552-1`，运行如前所示的相同 `list-package-version-assets` 命令会得到相同的输出。

在向存储库中添加 `1.0-SNAPSHOT` 的额外构建时，会为每个新构建创建一个新的 `Unlisted` 程序包版本。每次都会更新版本 `1.0-SNAPSHOT` 的资产，因此版本始终引用该版本的最新构建。通过上传新构建的 `maven-metadata.xml` 文件，开始将 `1.0-SNAPSHOT` 更新为包含最新资产。

## 使用快照版本
<a name="maven-consuming-snapshot-versions"></a>

如果您请求快照，则会返回状态为 `Published` 的版本。这始终是 Maven 快照的最新版本。您也可以在 URL 路径中使用构建版本号（例如 `1.0-20210728.194552-1`）而不是快照版本（例如 `1.0-SNAPSHOT`）来请求快照的特定构建。要查看 Maven 快照的编译版本，请使用 [ListPackageVersions ](https://docs.aws.amazon.com/codeartifact/latest/APIReference/API_ListPackageVersions.html)API *指南中的 CodeArtifact API* 并将状态参数设置为`Unlisted`。

## 删除快照版本
<a name="maven-deleting-snapshot-versions"></a>

要删除 Maven 快照的所有构建版本，请使用 [DeletePackageVersions](https://docs.aws.amazon.com/codeartifact/latest/APIReference/API_DeletePackageVersions.html)API，指定要删除的版本。

## 使用 curl 进行快照发布
<a name="maven-snapshot-publishing-curl"></a>

如果您在亚马逊简单存储服务 (Amazon S3) Simple Storage Service 或其他项目存储库产品中存储了现有快照版本，则可能需要将其重新发布到。 AWS CodeArtifact由于 CodeArtifact支持 Maven 快照的方式（请参阅[快照发布在 CodeArtifact](#maven-snapshot-publishing)），因此使用通用 HTTP 客户端（例如）发布快照比发布 Maven 发行版本要复杂得多，如中所述。`curl` [使用 curl 进行发布](maven-curl.md)请注意，如果您使用 `mvn` 或 `gradle` 等 Maven 客户端来构建和部署快照版本，则本节不相关。您需要遵循该客户端的文档进行操作。

发布快照版本涉及发布快照版本的一个或多个构建。在中 CodeArtifact，如果快照版本有 *n* 个内部版本，则将有 *n \$1 1 个* CodeArtifact 版本：*n* 个版本的状态均为`Unlisted`，一个快照版本（最新发布的版本）的状态为`Published`。快照版本（即版本字符串包含“-SNAPSHOT”的版本）包含一组与最新发布的构建相同的资产。使用 `curl` 创建此结构的最简单方法如下：

1. 使用 `curl` 发布所有构建的所有资产。

1. 使用 `curl` 发布最后一个构建（即带有最新日期时间戳的构建）的 `maven-metadata.xml` 文件。这将创建一个版本字符串中带有“`-SNAPSHOT`”且具有正确资产集的版本。

1. 使用 [UpdatePackageVersionsStatus](https://docs.aws.amazon.com/codeartifact/latest/APIReference/API_UpdatePackageVersionsStatus.html)API 将所有非最新版本的状态设置为。`Unlisted`

 使用以下 `curl` 命令来发布程序包 `com.mycompany.app:pkg-1` 的快照版本 `1.0-SNAPSHOT` 的快照资产（例如 .jar 和 .pom 文件）：

```
curl --user "aws:$CODEARTIFACT_AUTH_TOKEN" -H "Content-Type: application/octet-stream" \
     -X PUT https://my_domain-111122223333.d.codeartifact.us-west-2.amazonaws.com/maven/my_maven_repo/com/mycompany/app/pkg-1/1.0-SNAPSHOT/pkg-1-1.0-20210729.171330-2.jar \
     --data-binary @pkg-1-1.0-20210728.194552-1.jar
```

```
curl --user "aws:$CODEARTIFACT_AUTH_TOKEN" -H "Content-Type: application/octet-stream" \
     -X PUT https://my_domain-111122223333.d.codeartifact.us-west-2.amazonaws.com/maven/my_maven_repo/com/mycompany/app/pkg-1/1.0-SNAPSHOT/pkg-1-1.0-20210729.171330-2.pom \
     --data-binary @pkg-1-1.0-20210728.194552-1.pom
```

使用这些示例时：
+ *my\$1domain*用您的 CodeArtifact 域名替换。
+ *111122223333*替换为您的 CodeArtifact 域名所有者的 AWS 账户 ID。
+ *us-west-2*替换 AWS 区域 为您的 CodeArtifact 域名所在的。
+ *my\$1maven\$1repo*替换为您的 CodeArtifact 存储库名称。

**重要**  
必须在 `--data-binary` 参数的值前面加上 `@` 字符。将值放在引号中时，`@` 必须包含在引号内。

每个构建可能有两个以上的资产需要上传。例如，除了主 JAR 和 `pom.xml` 之外，可能还有 Javadoc 和源 JAR 文件。没有必要发布包版本资产的校验和文件，因为会 CodeArtifact自动为每个上传的资源生成校验和。要验证资产是否已正确上传，请使用 `list-package-version-assets` 命令提取生成的校验和，并将其与原始校验和进行比较。有关如何 CodeArtifact 处理 Maven 校验和的更多信息，请参阅。[使用 Maven 校验和](maven-checksums.md)

使用以下 curl 命令来发布最新构建版本的 `maven-metadata.xml` 文件：

```
curl --user "aws:$CODEARTIFACT_AUTH_TOKEN" -H "Content-Type: application/octet-stream" \
     -X PUT https://my_domain-111122223333.d.codeartifact.us-west-2.amazonaws.com/maven/my_maven_repo/com/mycompany/app/pkg-1/1.0-SNAPSHOT/maven-metadata.xml \
     --data-binary @maven-metadata.xml
```

`maven-metadata.xml` 文件必须引用 `<snapshotVersions>` 元素中最新构建版本的至少一个资产。此外，必须存在 `<timestamp>` 值，且该值必须与资产文件名中的时间戳相匹配。例如，对于之前发布的 `20210729.171330-2` 构建，`maven-metadata.xml` 的内容将为：

```
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
  <groupId>com.mycompany.app</groupId>
  <artifactId>pkg-1</artifactId>
  <version>1.0-SNAPSHOT</version>
  <versioning>
    <snapshot>
      <timestamp>20210729.171330</timestamp>
      <buildNumber>2</buildNumber>
    </snapshot>
    <lastUpdated>20210729171330</lastUpdated>
    <snapshotVersions>
      <snapshotVersion>
        <extension>jar</extension>
        <value>1.0-20210729.171330-2</value>
        <updated>20210729171330</updated>
      </snapshotVersion>
      <snapshotVersion>
        <extension>pom</extension>
        <value>1.0-20210729.171330-2</value>
        <updated>20210729171330</updated>
      </snapshotVersion>
    </snapshotVersions>
  </versioning>
</metadata>
```

发布 `maven-metadata.xml` 后，最后一步是将所有其他构建版本（即除最新构建之外的所有构建版本）的程序包版本状态设置为 `Unlisted`。例如，如果 `1.0-SNAPSHOT` 版本有两个构建，第一个构建是 `20210728.194552-1`，则将该构建设置为 `Unlisted` 的命令是：

```
aws codeartifact update-package-versions-status --domain my-domain --domain-owner 111122223333 \
   --repository my-maven-repo --format maven --namespace com.mycompany.app --package pkg-1 \
   --versions 1.0-20210728.194552-1 --target-status Unlisted
```

## 快照和外部连接
<a name="maven-snapshot-external-connections"></a>

无法通过外部连接从 Maven 公共存储库获取 Maven 快照。 AWS CodeArtifact 仅支持导入 Maven 发行版本。

## 快照和上游存储库
<a name="maven-snapshot-upstream-repositories"></a>

通常，与上游存储库一起使用时，Maven 快照的工作方式与 Maven 发布版本相同，但如果您计划将同一程序包版本的快照发布到两个具有上游关系的存储库，则存在一定的限制。例如，假设一个 AWS CodeArtifact 域中有两个存储库，`R`以及`U`，其中`U`是的上游`R`。如果您在中发布新版本`R`，则当 Maven 客户端请求该快照版本的最新版本时，会 CodeArtifact 返回来自`U`的最新版本。这可能出乎意料，因为最新版本现在位于 `R` 中，而不是 `U` 中。有两种方法可以避免这种情况：

1. 如果 `U` 中存在 `1.0-SNAPSHOT`，则不要发布快照版本的内部版本（例如 `R` 中的 `1.0-SNAPSHOT`）。

1. 使用 CodeArtifact 包源控件在中`R`禁用该软件包的上游。后者将允许您在 `R` 中发布 `1.0-SNAPSHOT` 的内部版本，但它也将防止 `R` 从 `U` 中获取该程序包的其他任何尚未保留的版本。