Comencé el trabajo de refactorizar el complemento auto
maven
para tratar de ser más consistente con el resto de auto
. Al hacerlo, he llegado a algunas conclusiones.
El requisito actual para auto
con el complemento maven
es que el proyecto use maven-release-plugin
. Esto tiene varias consecuencias que lo hacen un mal ajuste para auto
.
La funcionalidad principal de maven-release-plugin
ejecuta los siguientes pasos a través de release:prepare
:
Y luego se realiza un lanzamiento a través de release:perform
:
deploy
site-deploy
)Para garantizar que el complemento se comporte de manera coherente con auto
, la implementación actual utiliza algunos git hackery para deshacerse de las confirmaciones realizadas por el objetivo release:prepare
. En otras palabras, el maven-release-plugin
está haciendo el trabajo para el que está diseñado auto
y, por lo tanto, tiene que "solucionarse" de una manera menos elegante.
De igual importancia es el método utilizado para extraer el repositorio y la información del autor; actualmente, el complemento maven
usa las secciones <scm/>
y <developers/>
de pom.xml
para derivar Esa información. Esto se desvía de la metodología utilizada por el resto de auto
que usa metadatos de git. La implementación actual tiene varios problemas:
author
se establece a través de la sección <developers/>
de pom.xml
, lo que significa que la persona que realiza la confirmación NO PUEDE ser la misma que el author
. No se intenta alinear el autor de la confirmación de git con la información <developers/>
.owner
y repo
se establece a través de la sección <scm/>
, que puede ser diferente del repositorio y propietario real del clon actual.Al hacer un análisis más profundo del complemento, y al compararlo con el complemento gradle
, parece que el único objetivo de maven-release-plugin
que sería de beneficio es el release:update-versions
objetivo. Ese objetivo podría reemplazarse fácilmente con un simple manejo de XML.
Dada la sobrecarga de mantener el maven-release-plugin
y la ventaja mínima, mi opinión es que el requisito debe eliminarse, y el complemento auto
maven
debe implementarse en un auto
- moda nativa.
¡Estoy completamente de acuerdo!
La mayoría de sus puntos con la información que obtengo del pom.xml probablemente estén relacionados con mi malentendido de esos campos. Cualquier cambio aquí es más que bienvenido.
Estoy totalmente a favor de cualquier cambio importante que tengamos que hacer. Probablemente podamos lanzar algunos de los cambios de ruptura más pequeños detallados en el n. ° 1156
Parece que mis dos puntos sobre <scm/>
y <developers/>
son incorrectos. El complemento npm
extrae del package.json
. ¿Significa esto que _deben_ estar ubicados en el pom.xml
?
Si esos son los pom
equivalentes de los campos npm repository
y author
, entonces sí.
El autor se establece a través del
sección del pom.xml, lo que significa que la persona que realiza la confirmación NO PUEDE ser la misma que el autor seleccionado. No hay ningún intento de alinear el autor de git commit con el información.
Esto también es cierto para el complemento npm. Localmente auto no anulará su configuración git
, pero en un entorno CI puede que tenga que configurar author
para confirmar`.
La información del propietario y del repositorio se establece a través del
sección, que puede ser diferente al repositorio real y al propietario del clon actual.
¿Sería esto diferente? En npm world, el campo repository
generalmente apunta al código del paquete. En la práctica, uno generalmente no ejecuta auto
en un fork
y si lo hicieran, espero que actualicen el campo repository
en su fork
Está bien, eso tiene sentido, por lo que el comportamiento adecuado es buscar esas cosas (actuales), y si NO se encuentran en el pom.xml
, regrese y asuma que se han establecido en el .autorc
(nuevo comportamiento).
Actualmente, el complemento generará un error si no encuentra las secciones <scm/>
y <developers/>
en las pom.xml
.
Ah, sí, eso es definitivamente un error. No debe arrojar errores https://github.com/intuit/auto/blob/master/plugins/npm/src/index.ts#L504
¿Hay alguna manera de obtener la versión NUMBER de auto
de forma legible por máquina? Me sorprendió que el comando auto version
produzca el TIPO de aumento de versión, en lugar del número.
Puede usar --quiet
y solo imprimirá la versión producida por el comando. o combínelo con --dry-run
y podrá ver qué versión se publicará a continuación.
Podría estar dispuesto a agregar una bandera para hacer que version
escupe la versión real. Esto se vuelve extraño en escenarios de paquetes múltiples
Puedo ver eso. Probablemente sea mejor dejar eso a la persona que llama para que averigüe qué versión está buscando.
Su punto sobre los escenarios de paquetes múltiples es pertinente aquí: el complemento de lanzamiento de maven admite ese tipo de escenario, listo para usar. Esto me hace cuestionar si me gustaría reproducir ese trabajo. Me encuentro en un punto muerto: por un lado, mi argumento para NO usar maven-release-plugin es válido, mientras que, por el otro, cosas como la administración de versiones de submódulos es un caso de uso no trivial que debe abordarse y está cubierto por el complemento maven-release-plugin.
Encontré dos métodos para usar el complemento maven-release-plugin que podrían usarse para evitar que el complemento maven modifique el repositorio durante release:prepare
, y los probaré más tarde hoy.
@hipstersmoothie Tengo una pregunta sobre el comportamiento de los ganchos de getAuthor
, getRepo
, etc. - RE: el comentario sobre https://github.com/intuit/auto/issues/1260#issuecomment - 634280655, estoy mirando las pruebas y parecen contradecir eso.
Entonces, cuando devuelvo un undefined
AuthorInformation
no se produce ningún error.
¿Alguna sugerencia sobre lo que puedo estar haciendo mal o si debo volver a introducir throw
en el manejo de mi gancho?
Eso es definitivamente incorrecto dado cómo funcionan todos los demás complementos. Regresar sin definir es el camino correcto. De esa manera core
puede recurrir al usuario git
configurado localmente si es necesario
Entendido, eso es lo que pensé, así que modifiqué las pruebas para garantizar que los ganchos fallidos devuelvan undefined
.
Parece que los complementos de gradle y cocoapods arrojan errores si no pueden encontrar una versión. Creé un error para el complemento de gradle: ¿quieres otro para cocoapods?
Simplemente deje un no en el tema. ¡Gracias por la captura!
Estoy luchando con un buen método para probar la inicialización de valores durante hooks.beforeRun
. Específicamente, tengo el siguiente código, que cuando está bajo depuración extrae con éxito la información del autor durante el tap hooks.beforeRun
, pero falla la prueba:
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",
})
);
});
Lo que está sucediendo es que la prueba está llegando al gancho getAuthor
ANTES de que se ejecute el gancho beforeRun
. He visto otro código que prueba esto (gradle, s3) y no estoy teniendo suerte.
Básicamente, necesito una forma de ejecutar de manera determinista el gancho beforeRun
y no puedo averiguar cómo hacerlo.
empuja una rama y puedo comprobarlo
@hipstersmoothie aquí está la rama: https://github.com/terradatum/auto/tree/remove-maven-release-plugin-requirement
He comentado el código que enviaría mis cambios al repositorio central para poder probar el código en un proyecto real sin contaminar el historial remoto.
Cualquier ayuda que pueda brindarme con esto es muy apreciada; me encantaría poder usar las pruebas para verificar qué tan bien puedo modificar los archivos pom.xml, en lugar de recurrir al método de la vieja escuela de "ejecutar el código contra archivos reales, verifique los archivos reales, ejecute git reset --hard HEAD~1
para deshacerse de los cambios, enjuague y repita. "
Además, tuve que hacer algunos cambios en el package.json
local que eran incompatibles con la raíz package.json
para ejecutar las pruebas de broma en IntelliJ: ¿hay alguna guía que pueda darme al respecto? ¿O debería "simplemente funcionar" fuera de la caja?
Específicamente, cuando está en el directorio de complementos de Maven y ejecuta npm test
- TODAS las pruebas terminan ejecutándose porque "test": "jest --maxWorkers=2 --config ../../package.json"
.
Y si trato de usar IntelliJ Test Runner desde el editor, obtengo:
● 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)
Puedo resolver mi problema con IntelliJ agregando un archivo 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
}
Y luego agregando jest-circus
a los archivos root o maven package.json
.
Acabo de notar que xml2js
no va a hacer el trabajo porque ELIMINARÁ silenciosamente todos los comentarios XML durante las traducciones XML => JSON => XML. He intentado que funcione y es como sacar dientes. No hay garantía de que el XML se parezca en algo al original cuando se mueva a través de las transformaciones xml2js
, y eso es un factor decisivo.
Para ejecutar pruebas para un solo complemento, lo ejecuto desde la raíz.
yarn test plugins/maven
Esto luego plantea la pregunta de si puede o no mostrar fácilmente todos los cambios que estaría haciendo o los artefactos que estaría construyendo sin realmente hacer algunos cambios.
Eso parece un factor decisivo. ¿Existe alguna CLI estándar enviada en entornos Java que permita la edición de ese archivo?
Para los complementos que no tienen un analizador para el archivo de configuración (por ejemplo: ruby) auto
usa principalmente expresiones regulares para actualizar el archivo.
¿Tuviste la oportunidad de ver el problema beforeRun
? Tengo una solución, pero se siente realmente horrible ...
Realmente no me gusta la idea de usar expresiones regulares con XML: es propenso a errores y frágil. Sin embargo, también parece ridículamente complejo intentar usar DOMParser
o XMLSerializer
solo para modificar la versión, por lo que estaba tratando de trabajar con xml2js
en primer lugar.
¡Mirando esto ahora!
El problema es que estás haciendo un toque "sincrónico" y haciendo un trabajo asincrónico dentro de él.
Cambia esto
auto.hooks.beforeRun.tap(this.name, async () => {
a esto
auto.hooks.beforeRun.tapPromise(this.name, async () => {
Ah, el gancho antes de ejecutar está sincronizado en este momento, ese es el verdadero problema. No cambiaría nada si se convirtiera en AsyncSeriesHook
lugar de SyncHook
. Puedo enviar un compromiso a su rama si no está claro lo que estoy diciendo
Por favor, hazlo ... déjame convertirte en colaborador.
¡Adelante!
Solo empujado. Ejecuté las pruebas y ahora solo dos fallan. el gancho beforeRun funciona como se esperaba.
@hipstersmoothie ¿No veo el compromiso con el repositorio terradatum / auto?
ahora realmente he empujado
¿Causará eso un cambio importante para cualquier complemento que esté utilizando actualmente el grifo síncrono?
No. Los grifos de sincronización deberían funcionar igual. Esto solo agrega la capacidad de aprovechar una promesa
He logrado que esto funcione con expresiones regulares frágiles / propensas a errores. Mi preocupación es que el elemento <version/>
se usa EN TODAS PARTES en un archivo pom.xml
, para la versión del artefacto Y para las dependencias y complementos. En otras palabras, es muy probable que la expresión regular cambie inadvertidamente una versión que no debería.
Al intentar trabajar con XML DOM (a través de xmldom, xmldom-ts, xml2js, xml2json, etc.), me encontré atrapado en un atolladero de proporciones épicas. De ninguna manera me considero un experto en mecanografiado o javascript, así que tal vez ahí es donde me estoy cayendo.
Dos cosas me están pateando el trasero:
Document
y luego use xpath para seleccionar los nodos "/ project / version" y "/ project / parent / version".Entre esos dos problemas, probablemente he pasado de 12 a 16 horas en total, y me estoy frustrando mucho. Tenía el # 1 trabajando hasta esta mañana, y creo que el # 2 debería ser relativamente simple, pero parece estar peleando conmigo a cada paso.
Me inclino a volver a usar maven-release-plugin por la razón ridículamente simple de que se encarga de actualizar los archivos pom.xml por mí.
No puedo averiguar cómo hacer que IntelliJ ejecute las pruebas de maven (y SOLO las pruebas de maven) en modo de depuración. A veces funciona, a veces no.
Lo siento, no soy de mayor ayuda aquí. Utilizo VSCode y rara vez depuro las pruebas. ¿Puedes ejecutar desde root con yarn test plugins/maven
?
Cargar el pom.xml en un documento y luego usar xpath para seleccionar los nodos "/ project / version" y "/ project / parent / version".
Parece un buen método. Si eso pudiera funcionar, parece bueno.
Me inclino a volver a usar maven-release-plugin por la razón ridículamente simple de que se encarga de actualizar los archivos pom.xml por mí.
¿Solo hay material basado en complementos como https://stackoverflow.com/questions/5726291/updating-version-numbers-of-modules-in-a-multi-module-maven-project disponible para maven? una cosa basada en mvn de bajo nivel sería perfecta.
Por cierto, ¡gracias por dedicar tanto tiempo a esto!
Gracias por los comentarios y el apoyo. Perdón por el comentario anterior despotricando (ish).
Un gran punto sobre las versiones-maven-plugin: no he trabajado con él antes y no tenía idea de que existía. Eso ciertamente me facilitará las cosas ... Es un compromiso perfecto entre el complemento de lanzamiento de maven y tratar de administrar los archivos pom.xml a través del complemento automático.
Puedo hacer que yarn test plugins/maven
funcione. También soy un gran admirador de usar el depurador para inspeccionar cosas, en lugar del más tradicional console.log
, así que probablemente es ahí donde me estoy causando más acidez de la que necesito ...
Después de un largo y arduo viaje, casi tengo lo que considero una solución completa, que modificará los archivos pom.xml
directamente o usará versions-maven-plugin
para configurar versiones.
Hay algunas advertencias. El código utilizado para modificar pom.xml
está funcionando con un DOM, lo que tiene las siguientes consecuencias:
tsconfig.json
que requiere que "dom"
lib esté antes de "es2017"
en "compilerOptions"
:obras:
"compilerOptions": [ "dom", "es2017" ]
no funciona:
"compilerOptions": [ "es2017", "dom" ]
Sin la "corrección", ocurre lo siguiente:
$ 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
requieren testEnvironment: 'jsdom'
en lugar de 'node'
.Sin la "corrección", ocurre lo siguiente:
$ 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)
Ninguna de las "correcciones" anteriores funciona cuando se establece en las configuraciones raíz del complemento, por ejemplo, ni plugins/maven/tsconfig.json
ni una configuración de jest
en plugins/maven/package.json
. Hacer los cambios en los archivos de configuración raíz no pareció afectar negativamente las pruebas o la funcionalidad.
¿Está esto en tu sucursal? Probablemente pueda arreglar esto
Todavía no ... Me estoy asegurando de que todas las pruebas (y las nuevas) pasen antes de seguir adelante. Te enviaré un ping cuando estén listos para que los revises.
Acabo de volver a basar el maestro en mi rama y ahora recibo varios errores de compilación.
Primero, el archivo yarn.lock
se bloqueó debido a un conflicto de fusión, así que tuve que eliminarlo y reconstruirlo:
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
Una vez que hice eso, ahora recibo @octokit/graphql
errores:
$ 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.
Tenía muchas esperanzas de poder crear un RP para esto, pero me preocupa que aún no esté listo.
De acuerdo, resolví lo que tenía que hacer: simplemente revisé el archivo yarn.lock
de master
y luego volví a ejecutar yarn clean && yarn install && yarn build && yarn test plugins/maven
y creo que estoy bien -ir.
¡Impresionante! Revisaré esto hoy. ¡Siento no haber respondido durante el fin de semana!
: rocket: El problema se publicó en v9.40.0
: rocket: