Auto: Удалить требование для maven-release-plugin

Созданный на 26 мая 2020  ·  44Комментарии  ·  Источник: intuit/auto

Я начал работу по рефакторингу плагина auto maven чтобы попытаться сделать его более согласованным с остальной частью auto . Поступив так, я пришел к некоторым выводам.

Текущее требование для auto с плагином maven состоит в том, чтобы проект использовал maven-release-plugin . Это имеет несколько последствий, из-за которых он плохо подходит для auto .

Основная функция maven-release-plugin выполняет следующие шаги через release:prepare :

  1. Убедитесь, что в источниках нет незафиксированных изменений
  2. Убедитесь, что нет зависимостей SNAPSHOT
  3. Измените версию в POM с x-SNAPSHOT на новую версию
  4. Преобразуйте информацию SCM в POM, чтобы включить конечный пункт назначения тега.
  5. Запустите тесты проекта с измененными POM, чтобы убедиться, что все в рабочем состоянии.
  6. Зафиксируйте измененные POM
  7. Отметьте код в SCM именем версии
  8. Поднять версию в POM до нового значения y-SNAPSHOT
  9. Зафиксируйте измененные POM

И затем выпуск выполняется через release:perform :

  1. Оформить заказ по URL-адресу SCM с необязательным тегом
  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 с информацией <developers/> не предпринимаются.
  2. Информация owner и repo устанавливается через раздел <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 ?

Если это эквиваленты pom author полей npm repository и author тогда да.

Автор устанавливается через раздела pom.xml, что означает, что человек, выполняющий фиксацию, НЕ МОЖЕТ быть тем же самым, что и выбранный автор. Нет попытки сопоставить автора коммита git с Информация.

Это верно и для плагина npm. Локально auto не переопределит вашу конфигурацию git , но в среде CI может потребоваться установить author для фиксации`.

Информация о владельце и репо устанавливается через раздел, который может отличаться от фактического репозитория и владельца текущего клона.

Было бы иначе? В мире 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

Есть ли способ получить версию NUMBER из auto машиночитаемым способом? Я был удивлен, что команда auto version выдает ТИП повышения версии, а не число.

Вы можете использовать --quiet и он будет печатать только версию, созданную командой. или соедините его с --dry-run и вы увидите, какая версия будет опубликована следующей.

Я мог бы добавить флаг, чтобы version выдал актуальную версию. Это просто странно в сценариях с несколькими пакетами

Я могу видеть это. Вероятно, лучше оставить это вызывающему абоненту, чтобы выяснить, какую версию он ищет.

Здесь уместно ваше мнение о сценариях с несколькими пакетами - maven-release-plugin поддерживает этот тип сценария прямо из коробки. Это заставляет меня сомневаться, хочу ли я воспроизвести эту работу. Я нахожусь в тупике - с одной стороны, мой аргумент в пользу НЕ использования maven-release-plugin действителен, а с другой стороны, такие вещи, как управление версиями подмодулей, являются нетривиальным вариантом использования, который должны быть адресованы и покрываются maven-release-plugin.

Я нашел два метода использования maven-release-plugin, которые можно использовать для предотвращения изменения плагином maven репозитория во время release:prepare , и я буду тестировать их позже сегодня.

@hipstersmoothie У меня вопрос о поведении хуков getAuthor , getRepo и т. д. - 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 если это необходимо.

Попался - это то, что я понял, поэтому я изменил тесты, чтобы гарантировать, что неудачные хуки возвращают 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://github.com/terradatum/auto/tree/remove-maven-release-plugin-requirement

Я закомментировал код, который отправит мои изменения в центральное репо, чтобы я мог протестировать код на реальном проекте, не загрязняя удаленную историю.

Мы очень ценим любую помощь, которую вы можете мне оказать в этом вопросе - я бы хотел иметь возможность использовать тесты, чтобы проверить, насколько хорошо я могу изменять файлы pom.xml, вместо того, чтобы прибегать к старому методу «запустить код против реальные файлы, проверьте реальные файлы, запустите git reset --hard HEAD~1 чтобы избавиться от изменений, промойте и повторите. "

Кроме того, мне пришлось внести некоторые изменения в локальный package.json которые были несовместимы с корневым package.json , чтобы запускать шутливые тесты в IntelliJ - есть ли какие-либо рекомендации, которые вы можете мне дать по этому поводу, или он должен "просто работать" из коробки?

В частности, когда вы находитесь в каталоге плагинов maven и выполняете npm test - ВСЕ тесты завершаются запуском, потому что "test": "jest --maxWorkers=2 --config ../../package.json" .

И если я попытаюсь использовать IntelliJ Test Runner из редактора, я получу:

  ● 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)

Я могу решить свою проблему с IntelliJ, добавив файл jest.config.ts :

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

А затем добавляем jest-circus либо в корневой файл, либо в файлы maven package.json .

Просто заметил, что xml2js не будет выполнять эту работу, потому что он будет тихо УДАЛИТЬ все комментарии XML во время переводов XML => JSON => XML. Я пытался заставить это работать, и это все равно, что рвать зубы. Нет никакой гарантии, что XML будет выглядеть как оригинал при переходе через преобразования xml2js , и это нарушает условия сделки.

Чтобы запустить тесты только для одного плагина, я запускаю его из корневого каталога.

yarn test plugins/maven

Тогда возникает вопрос, можете ли вы легко показать все изменения, которые вы будете вносить, или артефакты, которые вы собираетесь создавать, без фактического внесения каких-либо изменений.

Это действительно кажется серьезным нарушителем. Есть ли в Java-средах стандартный интерфейс командной строки, позволяющий редактировать этот файл?

Для плагинов, у которых нет парсера для файла конфигурации (например, ruby), auto основном использует регулярное выражение для обновления файла.

У вас была возможность взглянуть на проблему beforeRun ? У меня есть обходной путь, но он кажется действительно хакерским ...

Мне действительно не нравится идея использования регулярных выражений с XML - она ​​подвержена ошибкам и нестабильна. Однако также кажется смехотворно сложной попытка использовать DOMParser или XMLSerializer только для изменения версии, поэтому я в первую очередь пытался работать с 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?

теперь я действительно подтолкнул

Приведет ли это к критическому изменению для любого плагина, который в настоящее время использует синхронное нажатие?

Неа. синхронизирующие касания должны работать одинаково. Это просто добавляет возможность задействовать обещание.

Я успешно выполнил эту работу с хрупким / подверженным ошибкам регулярным выражением. Меня беспокоит то, что элемент <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 и редко отлаживаю тесты. Можете ли вы запустить от root с помощью yarn test plugins/maven ?

Загрузка pom.xml в документ, а затем использование xpath для выбора узлов «/ project / version» и «/ project / parent / version».

Это действительно кажется хорошим методом. Если бы это могло сработать, это было бы хорошо.

Я склонен вернуться к использованию maven-release-plugin по смехотворно простой причине, что он обрабатывает обновление файлов pom.xml за меня.

Доступны ли для maven только такие вещи, как https://stackoverflow.com/questions/5726291/updating-version-numbers-of-modules-in-a-multi-module-maven-project ? вещь на основе mvn низкого уровня была бы идеальной.


Кстати, спасибо, что потратили на это столько времени!

Спасибо за отзыв и поддержку. Извините за напыщенную речь (иш) в предыдущем комментарии.

Отличный момент по поводу версии-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" lib находился перед "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 config в plugins/maven/package.json . Внесение изменений в корневые файлы конфигурации не оказало отрицательного воздействия на тесты или функциональность.

это в твоей ветке? Я, наверное, смогу это исправить

Еще нет ... Перед тем, как нажимать, я проверяю все тесты (и новые). Я свяжусь с вами, когда они будут готовы к просмотру.

Я только что переустановил master в свою ветку, и теперь у меня несколько ошибок сборки.

Сначала файл yarn.lock был обработан из-за конфликта слияния, поэтому мне пришлось удалить и перестроить его:

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.

Я очень надеялся, что смогу создать для этого пиар, но я обеспокоен, что он еще не готов.

Хорошо, я понял, что мне нужно сделать - я только что проверил файл yarn.lock из master а затем повторно запустил yarn clean && yarn install && yarn build && yarn test plugins/maven и я думаю, что у меня все хорошо. -идти.

Потрясающие! Я рассмотрю это сегодня. Извините, я не ответил на выходных!


: rocket: Проблема была выпущена в v9.40.0 : rocket:

Была ли эта страница полезной?
0 / 5 - 0 рейтинги