Я начал работу по рефакторингу плагина auto
maven
чтобы попытаться сделать его более согласованным с остальной частью auto
. Поступив так, я пришел к некоторым выводам.
Текущее требование для auto
с плагином maven
состоит в том, чтобы проект использовал maven-release-plugin
. Это имеет несколько последствий, из-за которых он плохо подходит для auto
.
Основная функция maven-release-plugin
выполняет следующие шаги через release:prepare
:
И затем выпуск выполняется через release:perform
:
deploy
site-deploy
)Чтобы гарантировать, что плагин ведет себя в соответствии с auto
, текущая реализация использует некоторые хакерские приемы git для удаления коммитов, сделанных целью release:prepare
. Другими словами, maven-release-plugin
выполняет работу, для которой предназначен auto
, и поэтому его нужно «обходить» менее чем изящным образом.
Не менее важен метод, используемый для извлечения информации о репозитории и авторе - в настоящее время плагин maven
использует разделы <scm/>
и <developers/>
pom.xml
для получения эта информация. Это отклоняется от методологии, используемой остальной частью auto
которая использует метаданные git. Текущая реализация имеет несколько проблем:
author
устанавливается через раздел <developers/>
pom.xml
, что означает, что человек, выполняющий фиксацию, НЕ МОЖЕТ быть таким же, как выбранный author
. Попытки сопоставить автора коммита git с информацией <developers/>
не предпринимаются.owner
и repo
устанавливается через раздел <scm/>
, который может отличаться от фактического репозитория и владельца текущего клона.При более глубоком изучении плагина и сравнении его с плагином gradle
выясняется, что единственная цель из maven-release-plugin
которая была бы полезной, - это release:update-versions
Цель. Эту цель можно легко заменить простой обработкой XML.
Учитывая накладные расходы на поддержку maven-release-plugin
и минимальное преимущество, я считаю, что это требование должно быть снято, а плагин auto
maven
должен быть реализован в более auto
-родный мод.
Я полностью согласен!
Большинство ваших пунктов с информацией, которую я получаю из 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, смотрю тесты и они вроде противоречат тому.
Итак, когда я возвращаю 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
.
Глядя на это сейчас!
Проблема в том, что вы делаете "синхронное" нажатие и выполняете асинхронную работу внутри него.
Измените это
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, так что, может быть, именно здесь я падаю.
Две вещи надрывают мне задницу:
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, что имеет следующие последствия:
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>
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: