Auto: 删除对 maven-release-plugin 的要求

创建于 2020-05-26  ·  44评论  ·  资料来源: intuit/auto

我已经开始重构auto maven插件以尝试与auto的其余部分更加一致。 在这样做的过程中,我得出了一些结论。

maven插件对auto的当前要求是项目使用maven-release-plugin 。 这有几个后果,使其不适合auto

maven-release-plugin的主要功能通过release:prepare执行以下步骤:

  1. 检查源中没有未提交的更改
  2. 检查是否有 SNAPSHOT 依赖项
  3. 将 POM 中的版本从 x-SNAPSHOT 更改为新版本
  4. 转换 POM 中的 SCM 信息以包含标签的最终目的地
  5. 针对修改后的 POM 运行项目测试以确认一切正常
  6. 提交修改后的 POM
  7. 使用版本名称标记 SCM 中的代码
  8. 将 POM 中的版本提升到新值 y-SNAPSHOT
  9. 提交修改后的 POM

然后通过release:perform

  1. 从带有可选标签的 SCM URL 结帐
  2. 运行预定义的 Maven 目标以发布项目(默认deploy site-deploy

为了确保插件的行为方式与auto ,当前的实现使用了一些 git 黑客来处理release:prepare目标所做的提交。 换句话说, maven-release-plugin正在执行auto设计的工作,因此必须以一种不太优雅的方式“解决”。

同样重要的是用来提取库和作者信息的方法-目前的maven插件使用<scm/><developers/>的部分中的pom.xml来推导那个信息。 这与auto其余部分使用的方法不同,后者使用 git 元数据。 目前的实现有几个问题:

  1. author经由设置<developers/>的部分pom.xml ,这意味着人做的提交可以不相同,所选择的author 。 没有尝试将 git commit 作者与<developers/>信息对齐。
  2. ownerrepo信息是通过<scm/>部分设置的,这可能与当前克隆的实际存储库和所有者不同。

在对插件进行更深入的研究并将其与gradle插件进行比较时,似乎maven-release-plugin中唯一有用的目标是release:update-versions目标。 这个目标很容易被一些简单的 XML 处理所取代。

考虑到维护maven-release-plugin的开销和最小的优势,我认为应该取消该要求,并且auto maven插件应该在更多auto本土时尚。

enhancement released

所有44条评论

我完全同意!

我从 pom.xml 中获得的大部分信息点可能与我对这些字段的误解有关。 这里的任何更改都非常受欢迎。

我完全支持我们必须做的任何重大改变。 我们可能会推出一些在 #1156 中详述的较小的突破性更改

看起来我关于<scm/><developers/>两点是不正确的。 npm插件从package.json提取。 这是否意味着它们_应该_位于pom.xml

如果这些是 npm repositoryauthor字段的pom等价物,那么是的。

作者是通过设置 pom.xml 的一部分,这意味着执行提交的人可能与选定的作者不同。 没有尝试将 git commit 作者与信息。

这对于 npm 插件也是如此。 本地自动不会覆盖您的git配置,但在 CI 环境中,它可能必须将author为 commit`。

所有者和回购信息通过部分,这可能与当前克隆的实际存储库和所有者不同。

这会有所不同吗? 在 npm 世界中, repository字段通常指向包的代码。 在实践中,人们通常不会运行auto上的fork ,如果他们要我希望他们更新repository场他们叉

好的,这是有道理的 - 所以正确的行为是寻找那些东西(当前),如果它们在pom.xml没有找到,返回并假设它们已经被设置在.autorc (新行为)。

目前,如果它没有找到该插件将错误<scm/><developers/>的部分pom.xml

啊,是的,这绝对是一个错误。 它不应该抛出错误https://github.com/intuit/auto/blob/master/plugins/npm/src/index.ts#L504

有没有办法以机器可读的方式从auto获取版本号? 我很惊讶auto version命令产生版本凹凸的类型,而不是数字。

您可以使用--quiet并且它只会打印命令生成的版本。 或将其与--dry-run配对,您可以查看接下来将发布的版本。

我可能愿意添加一个标志以使version吐出实际版本。 这在多包场景中变得很奇怪

我知道。 最好将它留给调用者来确定它正在寻找哪个版本。

您关于多包场景的观点在这里很重要 - maven-release-plugin 支持这种类型的场景,即开即用。 这让我怀疑我是否想要重现该作品。 我发现自己陷入了僵局 - 一方面,我不使用 maven-release-plugin 的论点是有效的,而另一方面,像子模块版本管理这样的事情是一个不平凡的用例应该被解决,并且被 maven-release-plugin 覆盖。

我发现了两种使用 maven-release-plugin 的方法,可以用来防止 maven 插件在release:prepare期间修改存储库,并将在今天晚些时候测试它们。

@hipstersmoothie我有一个关于getAuthorgetRepo等钩子行为的问题 - RE:关于https://github.com/intuit/auto/issues/1260#issuecomment的评论 - 634280655,我正在查看测试,它们似乎与此相矛盾。

例子:
https://github.com/intuit/auto/blob/47d3b54ef1a7af990fe0ca898e747dd833fde3b1/plugins/maven/__tests__/maven.test.ts#L95

因此,当我返回undefined AuthorInformation不会引发任何错误。

关于我可能做错了什么的任何建议,或者我是否应该将throw重新引入我的钩子处理?

考虑到所有其他插件的工作方式,这绝对是错误的。 返回 undefined 是正确的方法。 这样core可以回退到本地配置的git用户,如果需要的话

Gotcha - 这就是我的想法,所以我修改了测试以确保失败的钩子返回undefined

看起来 gradle 和 cocoapods 插件如果找不到版本都会抛出错误。 我为 gradle 插件创建了一个错误 - 你想要另一个用于 cocoapods 的吗?

只是在这个问题上留下一个不。 感谢您的捕获!

我正在努力寻找一种在hooks.beforeRun期间测试值初始化的好方法。 具体来说,我有以下代码,当在调试下成功提取hooks.beforeRun期间的作者信息时,但测试失败:

    test("should get author from pom.xml", async () => {
      mockRead(`
        <project
          xmlns="http://maven.apache.org/POM/4.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
          <developers>
            <developer>
              <name>Andrew Lisowski</name>
              <email>[email protected]</email>
            </developer>
          </developers>
        </project>
      `);

      await hooks.beforeRun.promise({} as any);

      expect(await hooks.getAuthor.promise()).toStrictEqual(
        expect.objectContaining({
          email: "[email protected]",
          name: "Andrew Lisowski",
        })
      );
    });

什么情况是,测试得到的getAuthor前的钩beforeRun挂钩运行。 我看过其他测试这个的代码(gradle,s3),但我没有任何运气。

基本上,我需要一种方法来确定性地执行beforeRun钩子,但不知道该怎么做。

推一个分支,我可以检查一下

@hipstersmoothie这是分支: https :

我已经注释掉了将我的更改推送到中央存储库的代码,以便我可以在真实项目上测试代码而不会污染远程历史记录。

非常感谢您可以为我提供的任何帮助 - 我希望能够使用测试来检查我修改 pom.xml 文件的能力,而不是诉诸于“针对真实文件,检查真实文件,运行git reset --hard HEAD~1以消除更改,冲洗并重复。”

此外,为了在 IntelliJ 中运行 Jest 测试,我必须对与根package.json不兼容的本地package.json进行一些更改 - 有什么指导可以给我,还是应该“开箱即用”?

具体来说,当在 maven 插件目录中并运行npm test - 所有测试最终都会运行,因为"test": "jest --maxWorkers=2 --config ../../package.json"

如果我尝试从编辑器中使用 IntelliJ 测试运行器,我会得到:

  ● Test suite failed to run

    SyntaxError: /home/rbellamy/Development/Terradatum/auto/plugins/maven/__tests__/maven.test.ts: Unexpected token, expected "," (15:24)

      13 | }));
      14 | 
    > 15 | const mockRead = (result: string) =>
         |                         ^
      16 |   jest
      17 |     .spyOn(fs, "readFile")
      18 |     // @ts-ignore

      at Parser._raise (../../node_modules/@babel/parser/src/parser/location.js:241:45)
      at Parser._raise [as raiseWithData] (../../node_modules/@babel/parser/src/parser/location.js:236:17)
      at Parser.raiseWithData [as raise] (../../node_modules/@babel/parser/src/parser/location.js:220:17)
      at Parser.raise [as unexpected] (../../node_modules/@babel/parser/src/parser/util.js:149:16)
      at Parser.unexpected [as expect] (../../node_modules/@babel/parser/src/parser/util.js:129:28)
      at Parser.expect [as parseParenAndDistinguishExpression] (../../node_modules/@babel/parser/src/parser/expression.js:1293:14)
      at Parser.parseParenAndDistinguishExpression [as parseExprAtom] (../../node_modules/@babel/parser/src/parser/expression.js:1029:21)
      at Parser.parseExprAtom [as parseExprSubscripts] (../../node_modules/@babel/parser/src/parser/expression.js:539:23)
      at Parser.parseExprSubscripts [as parseMaybeUnary] (../../node_modules/@babel/parser/src/parser/expression.js:519:21)
      at Parser.parseMaybeUnary [as parseExprOps] (../../node_modules/@babel/parser/src/parser/expression.js:311:23)

我可以通过添加jest.config.ts文件来解决 IntelliJ 的问题:

module.exports = {
  clearMocks: true,
  moduleFileExtensions: ['js', 'ts'],
  testEnvironment: 'node',
  testMatch: ['**/*.test.ts'],
  testRunner: 'jest-circus/runner',
  transform: {
    '^.+\\.ts$': 'ts-jest'
  },
  verbose: true
}

然后将jest-circus到 root 或 maven package.json文件中。

只是注意到xml2js不会完成这项工作,因为它会在 XML => JSON => XML 转换期间默默地删除所有 XML 注释。 我一直在努力让它发挥作用,就像拔牙一样。 无法保证在通过xml2js转换时 XML 看起来会像原始文件一样,这是一个交易破坏者。

为了仅对一个插件运行测试,我从根目录运行它。

yarn test plugins/maven

这就引出了一个问题,即您是否可以轻松地显示您将要进行的所有更改或将要构建的工件,而无需实际进行一些更改。

这似乎是一个非常大的破坏者。 java 环境中是否有任何标准 CLI 允许编辑该文件?

对于没有配置文件解析器的插件(例如:ruby) auto主要使用正则表达式来更新文件。

你有机会看看beforeRun问题吗? 我有一个解决方法,但感觉真的很糟糕......

我真的不喜欢在 XML 中使用正则表达式的想法 - 它容易出错且脆弱。 然而,试图使用DOMParserXMLSerializer只是为了修改版本似乎也很复杂,这就是我首先尝试使用xml2js的原因。

现在看这个!

https://github.com/terradatum/auto/blob/remove-maven-release-plugin-requirement/plugins/maven/src/index.ts#L127

问题是您正在执行“同步”点击并在其中执行异步工作

改变这个

auto.hooks.beforeRun.tap(this.name, async () => {

对此

auto.hooks.beforeRun.tapPromise(this.name, async () => {

啊,之前的运行钩子现在是同步的,这才是真正的问题。 如果它变成AsyncSeriesHook而不是SyncHook它不会改变任何东西。 如果不清楚我在说什么,我可以将提交推送到您的分支

请做...让我让你成为贡献者。

前进!

刚推。 运行测试,现在只有两个失败。 beforeRun 钩子按预期工作。

@hipstersmoothie我没有看到对 terradatum/auto repo 的承诺?

现在我实际上已经推动了

这会导致当前使用同步点击的任何插件发生重大变化吗?

不。 同步水龙头应该工作相同。 这只是增加了点击承诺的能力

我已经使用脆弱/容易出错的正则表达式成功地完成了这项工作。 我担心的是<version/>元素在pom.xml文件中无处不在 - 用于工件版本以及依赖项和插件。 换句话说,正则表达式很可能会无意中更改它不应该更改的版本。

在尝试使用 XML DOM(通过 xmldom、xmldom-ts、xml2js、xml2json 等)时,我发现自己陷入了史无前例的泥潭。 我绝不认为自己是打字稿或 javascript 专家,所以也许这就是我失败的地方。

有两件事让我很生气:

  1. 我不知道如何让 IntelliJ 在调试模式下运行 Maven 测试(并且只运行 Maven 测试)。 有时它有效,有时它不起作用。
  2. 将 pom.xml 加载到Document ,然后使用 xpath 选择“/project/version”和“/project/parent/version”节点。

在这两个问题之间,我可能总共花了 12 到 16 个小时,我真的很沮丧。 我一直工作到今天早上 #1,我认为 #2 应该相对简单,但它似乎每时每刻都在与我作斗争。

我倾向于回到使用 maven-release-plugin 的原因是它为我处理更新 pom.xml 文件的可笑的简单原因。

我不知道如何让 IntelliJ 在调试模式下运行 Maven 测试(并且只运行 Maven 测试)。 有时它有效,有时它不起作用。

对不起,我在这里没有更多帮助。 我使用 VSCode 并且很少调试测试。 你能用yarn test plugins/maven从 root 运行吗?

将 pom.xml 加载到 Document 中,然后使用 xpath 选择“/project/version”和“/project/parent/version”节点。

这似乎是一个很好的方法。 如果这可以工作,那看起来不错。

我倾向于回到使用 maven-release-plugin 的原因是它为我处理更新 pom.xml 文件的可笑的简单原因。

是否只有基于插件的东西,如https://stackoverflow.com/questions/5726291/updating-version-numbers-of-modules-in-a-multi-module-maven-project可用于 maven? 一个低级别的基于 mvn 的东西将是完美的。


顺便说一句,感谢您花这么多时间在这上面!

感谢您的反馈和支持。 抱歉之前的评论。

关于versions-maven-plugin 的一个要点——我以前没有使用过它,也不知道它存在。 这肯定会让我更轻松......这是 maven-release-plugin 和尝试通过自动插件管理 pom.xml 文件之间的完美折衷。

我可以让yarn test plugins/maven工作。 我也非常喜欢使用调试器来检查东西,而不是更传统的console.log ,所以这可能是我让自己比我需要的更胃灼热的地方......

经过漫长而艰辛的旅程,我几乎有了我认为的完整解决方案,要么直接修改pom.xml文件,要么使用versions-maven-plugin设置版本。

有一些注意事项。 用于修改pom.xml的代码正在使用 DOM,这会产生以下后果:

  1. tsconfig.json处理中存在一个错误,要求"dom"库位于"es2017"中的"compilerOptions"

作品:

"compilerOptions": [ "dom", "es2017" ]

不起作用:

"compilerOptions": [ "es2017", "dom" ]

如果没有“修复”,则会发生以下情况:

$ tsc -b tsconfig.dev.json
node_modules/@types/jsdom/index.d.ts:28:40 - error TS2304: Cannot find name 'DocumentFragment'.

28         static fragment(html: string): DocumentFragment;
                                          ~~~~~~~~~~~~~~~~

node_modules/@types/jsdom/index.d.ts:45:28 - error TS2304: Cannot find name 'Node'.

45         nodeLocation(node: Node): ElementLocation | null;
                              ~~~~

node_modules/@types/jsdom/index.d.ts:188:19 - error TS2304: Cannot find name 'HTMLScriptElement'.

188         element?: HTMLScriptElement | HTMLLinkElement | HTMLIFrameElement | HTMLImageElement;
                      ~~~~~~~~~~~~~~~~~

node_modules/@types/jsdom/index.d.ts:188:39 - error TS2304: Cannot find name 'HTMLLinkElement'.

188         element?: HTMLScriptElement | HTMLLinkElement | HTMLIFrameElement | HTMLImageElement;
                                          ~~~~~~~~~~~~~~~
<snip - numerous other errors>
  1. jest测试需要testEnvironment: 'jsdom'而不是'node'

如果没有“修复”,则会发生以下情况:

$ jest --runInBand plugins/maven
 FAIL  plugins/maven/__tests__/maven.test.ts
  maven
    updatePomVersion
      ✕ should replace the previousVersion with the newVersion (39ms)

  ● maven › updatePomVersion › should replace the previousVersion with the newVersion

    ReferenceError: XPathEvaluator is not defined

      51 | ) => {
      52 |   const pomDom = new jsdom.JSDOM(content, {contentType: "text/xml"}).window.document;
    > 53 |   const evaluator = new XPathEvaluator();
         |                     ^
      54 |   const resolver = evaluator.createNSResolver(pomDom.documentElement);
      55 |   const expression = evaluator.createExpression("/project/version", resolver);
      56 |   const versionNode = expression.evaluate(pomDom.documentElement, XPathResult.FIRST_ORDERED_NODE_TYPE);

      at Object.exports.updatePomVersion (plugins/maven/src/index.ts:53:21)
      at Object.test (plugins/maven/__tests__/maven.test.ts:53:26)

无论是上述的“修复”的工作时,在插件的根配置,如设置为既不plugins/maven/tsconfig.json也不是jest的配置在plugins/maven/package.json 。 对根配置文件进行更改似乎不会对测试或功能产生负面影响。

这是在你的分支上吗? 我大概可以解决这个问题

还没有......我确保所有测试(和新测试)在推送之前通过。 当他们准备好供您查看时,我会通知您。

我只是将 master 重新定位到我的分支上,现在我遇到了几个构建错误。

首先yarn.lock文件因为合并冲突而被 borked,所以我不得不删除并重建它:

error Incorrect integrity when fetching from the cache for "babel-plugin-jest-hoist". Cache has "sha512-u+/W+WAjMlvoocYGTwthAiQSxDcJAyHpQ6oWlHdFZaaN+Rlk8Q7iiwDPg2lN/FyJtAYnKjFxbn7xus4HCFkg5g== sha1-EpyAulx/x1uvOkW5Pi43LVfKJnc=" and remote has "sha512-+AuoehOrjt9irZL7DOt2+4ZaTM6dlu1s5TTS46JBa0/qem4dy7VNW3tMb96qeEqcIh20LD73TVNtmVEeymTG7w==". Run `yarn cache clean` to fix the problem

一旦我这样做了,现在我收到@octokit/graphql错误:

$ tsc -b tsconfig.dev.json
packages/core/src/auto.ts:2018:13 - error TS2571: Object is of type 'unknown'.

2018         if (result?.[`hash_${commit}`]) {
                 ~~~~~~

packages/core/src/auto.ts:2019:27 - error TS2571: Object is of type 'unknown'.

2019           const number = (result[`hash_${commit}`] as ISearchResult).edges[0]
                               ~~~~~~

packages/core/src/release.ts:286:52 - error TS2769: No overload matches this call.
  Overload 1 of 2, '(o: ArrayLike<unknown> | { [s: string]: unknown; }): [string, unknown][]', gave the following error.
    Argument of type 'unknown' is not assignable to parameter of type 'ArrayLike<unknown> | { [s: string]: unknown; }'.
      Type 'unknown' is not assignable to type '{ [s: string]: unknown; }'.
  Overload 2 of 2, '(o: {}): [string, any][]', gave the following error.
    Argument of type 'unknown' is not assignable to parameter of type '{}'.

286       (acc, result) => [...acc, ...(Object.entries(result) as QueryEntry[])],
                                                       ~~~~~~


packages/core/src/__tests__/git.test.ts:209:12 - error TS2571: Object is of type 'unknown'.

209     expect(result!.data).not.toBeUndefined();
               ~~~~~~~


Found 4 errors.

error Command failed with exit code 2.

我非常希望我能够为此创建一个 PR - 但我担心它还没有准备好。

好的,我想出了我需要做的事情 - 我刚刚从master查看了yarn.lock文件,然后重新运行了yarn clean && yarn install && yarn build && yarn test plugins/maven ,我想我很好-走。

惊人的! 我今天会回顾一下。 抱歉我周末没有回复!


:rocket: 问题已在v9.40.0 :rocket:

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

theAdhocracy picture theAdhocracy  ·  6评论

tunnckoCore picture tunnckoCore  ·  4评论

zephraph picture zephraph  ·  10评论

thuringia picture thuringia  ·  14评论

aleclarson picture aleclarson  ·  9评论