【问题标题】:Update versions contained in README on maven release更新 Maven 版本的 README 中包含的版本
【发布时间】:2016-04-10 07:39:30
【问题描述】:

我在 github 上维护一个开源项目,该项目包含 README.md 文件,安装说明包含项目的当前版本 1.0.0-SNAPSHOT

发布新版本到maven central时,是否可以自动更新README.md中包含的这个版本号?

使用maven-release-plugin 执行发布,pom.xml 中的版本更新良好,但我在文档中找不到任何内容来正确更新此外部文件。

例子:

README.md 文件当前位于1.0.0-SNAPSHOT。它位于 Maven 源/资源之外,但它在 git 上进行管理。在mvn release:prepare 上,它应该更新为1.0.0,然后maven 应该在标记新版本之前提交/推送更改。然后,在mvn release:perform 上应该转到下一个开发版本1.0.1-SNAPSHOT

(Link to the project)

【问题讨论】:

  • @Marged 不,不要认为它是一样的。就我而言,README.md 文件不在 Maven 源代码中,但在 git 上进行管理。因此,我希望发布插件使用新版本对其进行更新,然后在 mvn release:prepare 期间在 git 上标记新版本之前提交/推送更改。在mvn release:perform 上,它应该会转到下一个开发版本,例如1.0.1-SNAPSHOT
  • 这很棘手。 README.md 是一个不应在最终 JAR 中的外部文件。这意味着您需要在发布之前替换该令牌,提交更改,将其推送并将文件回滚到该令牌。由于prepareperform 有两个步骤,我什至不确定你能否有效地做到这一点。如果您在之后执行prepareclean 会怎样?然后README会被改变,除非你手动回滚。
  • @Tunaki 是的,这是我认为的主要问题。此外,release:perform 要求将所有更改推送到 git,因此在此阶段对 README.md 文件进行更改会破坏事情......除非立即将更改推送到 git。如果现在什么都不存在,也许我可以尝试编写一个 Maven 插件来执行此操作?不使用令牌,而是用新版本替换旧版本的简单字符串
  • 我认为这里存在概念问题。版本替换不是问题:您可以在发布前执行一个目标,并使用maven-replacer-plugin 替换令牌。但问题是确保在出现问题时不会产生副作用。

标签: java maven


【解决方案1】:

您可以尝试编写一个 bash 脚本来构建您的项目并修改 README.md 文件。比如:

#!/bin/sh
VERSION=$1
mvn clean package
#modify the string manipulation command accordingly
sed -e "s/{VERSION}/${VERSION}/" ./README.md-tpl > ./README.md 

运行脚本时,您可以将版本号作为第一个参数传递。您可以使用默认 README.md-tpl 文件的完整路径。

【讨论】:

  • 它也应该在 Windows 上运行。我想保留这个“maven native”。
  • 你可以开始使用Docker了,它抽象了所有的环境问题,解决了OS相关的问题
  • 我已经使用 Docker 大约 1 年了,谢谢它很棒,但它不能解决我最初的问题 :(。构建应该作为标准的 maven 构建运行。
【解决方案2】:

您可以使用 maven-resources-plugin 来实现这一点,就像 cmets 中提到的那样。

我没试过,但配置应该是这样的:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-resources-plugin</artifactId>
  <version>3.0.1</version>
  <executions>
    <execution>
      <id>readme-md</id>
      <phase>process-resources</phase>
      <goals>
        <goal>copy-resources</goal>
      </goals>
      <configuration>
        <outputDirectory>${project.basedir}</outputDirectory>
        <resources>                                        
          <resource>
            <directory>${project.basedir}</directory>
            <includes>
              <include>README.md</include>
            </includes>
            <filtering>true</filtering>
          </resource>
        </resources>
        <encoding>UTF-8</encoding>
      </configuration>            
    </execution>
  </executions>
</plugin>

并且在你想要的版本的 README.md 中放置占位符 ${project.version}

这里结合的两个功能是copy-resourcesfiltering

我们告诉插件将资源从目录${project.basedir}(maven 解析到根目录)复制到根目录,但只包括与README.md 匹配的文件。

过滤选项将所有占位符替换为变量,这些变量可以定义为系统属性、项目属性、在 pom.xml 或命令行中定义的过滤器资源。在这种情况下,我们使用项目属性 version

尽管 cmets 正确地提到了最终的不一致,以防发布出错。您可以通过在 mvn release:perform 成功后显式调用 mvn resources:resources 来克服这个问题。我希望这会有所帮助。

【讨论】:

  • 是的,在资源中包含 README.md 似乎是一个非常聪明的想法。我不知道这是可能的。唯一的缺点是这个文件将包含在打包的 jar 文件中,但我认为这不是问题!而且肯定可以在 jar 插件配置中排除它。谢谢!
  • 我个人认为将它包含在二进制文件中并不是一个缺点。我什至认为这是一个很大的优势。您的 README.md 是文档的一部分,发行版与其文档之间应该存在 1:1 的关系。让工具在存储库中很好地呈现它们只是一种奖励,但不应该是阅读它的唯一可能方式。
  • 很高兴我能帮上忙 :)
  • 问题是它只适用于第一个版本。对于下一个版本,{$project.version} 占位符将替换为有效的项目版本。我需要找到一种方法在发布后将它们恢复...
  • 对。没有想到这一点。比我推荐的,将 README.md 放在 src/main/doc 下并将其从它们的根文件夹中复制
【解决方案3】:

以马文斯的回答为基础,
您可以将 README.md 保存在您通常的位置,并且只包含一个 sn-p 文本。

诀窍在于,虽然 Markdown 不允许包含文本,但它允许包含 svg-image 并且 svg-image 可以包含可以在所有浏览器中选择和复制的文本:

<svg xmlns="http://www.w3.org/2000/svg"
     xml:lang="en-GB" width="auto" height="7em">
    <style>
        svg {
            font-family: monospace;
            font-size: medium;
        }
    </style>

    <text x="0" y="1em">
        <tspan x="1em" dy="1em">&lt;dependency&gt;</tspan>
        <tspan x="3em" dy="1em">&lt;groupId&gt;${project.groupId}&lt;/groupId&gt;</tspan>
        <tspan x="3em" dy="1em">&lt;artifactId&gt;${project.artifactId}&lt;/artifactId&gt;</tspan>
        <tspan x="3em" dy="1em">&lt;version&gt;${project.version}&lt;/version&gt;</tspan>
        <tspan x="1em" dy="1em">&lt;/dependency&gt;</tspan>
    </text>
    
</svg>

这将呈现为:

<dependency>
  <groupId>${project.groupId}</groupId>
  <artifactId>${project.artifactId}</artifactId>
  <version>${project.version}</version>
</dependency>

(粘贴时会变成单行,但没关系。pom.xml 通常是自动格式化的)

您将该图像放入名为“templates”的目录中,并将副本放入“docimages”目录中。

现在您可以使用普通的图像参考将图像添加到 README.md:
![mvn dependency](docimages/version.svg)
请注意,您引用的是“docimages”目录中的那个,不是“模板”目录中的那个。

现在您只需要在 pom.xml 中复制和过滤图像源代码的作业:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-resources-plugin</artifactId>
  <version>3.0.1</version>
  <executions>
    <execution>
      <id>readme-md</id>
      <phase>process-resources</phase>
      <goals>
        <goal>copy-resources</goal>
      </goals>
      <configuration>
        <outputDirectory>${project.basedir}/docimages</outputDirectory>
        <resources>                                        
          <resource>
            <directory>${project.basedir/templates}</directory>
            <includes>
              <include>version.svg</include>
            </includes>
            <filtering>true</filtering>
          </resource>
        </resources>
        <encoding>UTF-8</encoding>
      </configuration>            
    </execution>
  </executions>
</plugin>

“过滤所有自述文件有什么好处?”你可能会问。
简单:README.md 可以很大,并且可以包含各种变量作为您不想替换的文档的一部分。这只会替换 SVG 文件中的变量。

【讨论】:

  • 聪明。我只是希望当您将 svg 图像嵌入到 github markdown 文件时,您不必单击它两次来实际选择文本。
  • 不幸的是,每个 Markdown 渲染器的做法都不同。我希望有一种正式的方式来包含文本,但我通常不喜欢肮脏的黑客。
【解决方案4】:

我有一些建议。

首先,我将 ${project.version} 替换为 README.md 中的版本,并按照 Marvin 的建议将其移至 src/main/doc 文件夹。

然后,我在构建中向maven-resources-plugin 添加了一个执行,如下所示:

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-resources-plugin</artifactId>
        <version>3.0.1</version>
        <executions>
            <execution>
                <id>readme</id>
                <phase>process-resources</phase>
                <goals>
                    <goal>copy-resources</goal>
                </goals>
                <configuration>
                    <outputDirectory>${project.basedir}</outputDirectory>
                    <resources>
                        <resource>
                            <directory>src/main/doc</directory>
                            <includes>
                                <include>README.md</include>
                            </includes>
                            <filtering>true</filtering>
                        </resource>
                    </resources>
                    <encoding>UTF-8</encoding>
                </configuration>
            </execution>
        </executions>
    </plugin>

现在,每次插件运行时,它都会替换 README.md 中的项目版本并将其复制到 ${project.basedir}

最后,在maven-release-plugin插件中,我添加了几个目标来运行上面的插件,然后将新更新的README.md添加到commit前的索引中:

   <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-release-plugin</artifactId>
        <version>3.0.0-M4</version>
        <configuration>
            <preparationGoals>resources:copy-resources@readme scm:add -Dincludes=README.md</preparationGoals>
            <completionGoals>resources:copy-resources@readme scm:add -Dincludes=README.md</completionGoals>
        </configuration>
    </plugin>

现在每次发布插件提交pom.xml,它也会提交README.md

【讨论】:

    猜你喜欢
    • 2018-09-27
    • 2023-03-06
    • 1970-01-01
    • 2018-09-02
    • 2021-10-27
    • 2015-08-02
    • 2016-07-24
    • 1970-01-01
    • 2015-08-04
    相关资源
    最近更新 更多