Coding  Life

Coding Life

1655881622

Build a CICD Pipeline on AWS CodePipeline with CodeBuild and GIT

In this tutorial as we use AWS CodePipeline to create a CI/CD pipeline on AWS. We'll deploy a NodeJS application from Github out to a target environment in AWS Elastic Beanstalk to provide easy integration and deployment from dev to production.

AWS CodePipeline is a fully managed continuous delivery service that helps you automate your release pipelines for fast and reliable application and infrastructure updates. CodePipeline automates the build, test, and deploy phases of your release process every time there is a code change, based on the release model you define. This enables you to rapidly and reliably deliver features and updates. You can easily integrate AWS CodePipeline with third-party services such as GitHub or with your own custom plugin. With AWS CodePipeline, you only pay for what you use. There are no upfront fees or long-term commitments.

AWS CodeBuild is a fully managed continuous integration service that compiles source code, runs tests, and produces software packages that are ready to deploy. With CodeBuild, you don’t need to provision, manage, and scale your own build servers. CodeBuild scales continuously and processes multiple builds concurrently, so your builds are not left waiting in a queue. You can get started quickly by using prepackaged build environments, or you can create custom build environments that use your own build tools. With CodeBuild, you are charged by the minute for the compute resources you use.

Git is software for tracking changes in any set of files, usually used for coordinating work among programmers collaboratively developing source code during software development. Its goals include speed, data integrity, and support for distributed, non-linear workflows.

Reference Link: https://aws.amazon.com/getting-started/hands-on/create-continuous-delivery-pipeline/

Subscribe: https://www.youtube.com/c/CloudGurus/featured 

#cicd   #git #aws 

Build a CICD Pipeline on AWS CodePipeline with CodeBuild and GIT
Archie  Clayton

Archie Clayton

1655696461

Effective CI/CD for Large Systems

Effective CI/CD for Large Systems

CI/CD brings tremendous value to development teams. The rapid availability of feedback helps developers make informed decisions about their design choices and lets teams deploy with confidence. But when systems become large and test times go from seconds to hours, how do we get our groove back? In this talk, we’ll explore strategies for validating large, complex systems, such as:
- Setting well-defined component boundaries
- Flexibly modeling dependencies between these components
- Ranking tests by cost versus value
- Testing in production with canary launches and feature flags

These and similar techniques let us minimize test times, maximize confidence, and free our teams up to focus on delivering value to customers.

#devops #cicd 

Effective CI/CD for Large Systems

Canalización De Prueba Automatizada Con GitLab CI/CD Y Selenium Grid

CI/CD ha ganado mucha atracción y es probablemente uno de los temas más comentados por los novatos en DevOps. Con la disponibilidad de herramientas de CI/CD disponibles en el mercado, configurar y operar una canalización de CI/CD se ha vuelto mucho más fácil de lo que era hace 5 o 6 años. En ese entonces no había contenedores y la única herramienta de CI/CD que dominaba la esfera era Jenkins . Jenkins le proporcionó un ejecutor de tareas, por lo que puede definir sus trabajos para que se ejecuten secuencialmente o en paralelo.

Hoy, el escenario es diferente. Tenemos numerosas herramientas de CI/CD disponibles en el mercado que nos brindan características y funcionalidades adicionales en comparación con Jenkins. Una de estas herramientas de CI/CD de renombre es GitLab CI y eso es precisamente lo que trataremos en este artículo.

En este artículo, configuraremos una canalización de CI/CD con GitLab CI/CD y ejecutaremos pruebas de Selenium a través de LambdaTest, un Selenium Grid en línea de más de 3000 navegadores reales.

Integre y automatice sus conjuntos de pruebas de Selenium con GitLab CI en LambdaTest .

Conceptos básicos de CI/CD

CI/CD es una colección de las mejores prácticas que se siguen para garantizar que entrega actualizaciones de productos a su aplicación web de manera consistente y confiable. Su aplicación web seguramente crecerá con cada sprint que se lleve a un nuevo ciclo de lanzamiento. Inicialmente, puede tener un pequeño equipo responsable de los cambios de código en su aplicación web. En tales casos, no le importaría hacer todo directamente, construye el código, lo prueba usted mismo y lo implementa en la producción.

Sin embargo, a medida que su equipo crece, habrá muchos puntos de interacción y la probabilidad de error aumenta a medida que intenta migrar todos los cambios de código de un entorno de prueba a otro. Aquí es donde la canalización de CI/CD juega un papel fundamental.

Cualquier negocio exitoso que se ejecute en línea depende en gran medida de cómo se configuren sus canalizaciones de CI/CD. En uno de los artículos en los que explicaba el crecimiento y escalabilidad de Uber , decía que:

Uber está ahora en 400 ciudades y 70 países. Tienen más de 6000 empleados, 2000 de los cuales son ingenieros. Hace apenas un año y medio había apenas 200 ingenieros. Esos ingenieros han producido más de 1000 microservicios que se almacenan en más de 8000 repositorios git.

Si observa qué tan rápido puede crecer un negocio, entonces puede imaginar los desafíos que Uber podría tener que enfrentar para coordinar con 10x ingenieros en el futuro, en solo un año y medio, si no hubieran incorporado una canalización de CI/CD. En el mundo actual, sería extremadamente difícil imaginar una aplicación web escalable en términos de velocidad y consistencia sin seguir las mejores prácticas de CI/CD. Ahora bien, ¿qué son CI y CD? CI se refiere a Integración Continua y CD implica Entrega Continua. Combinando ambos se puede lograr un Despliegue Continuo. Veamos lo que realmente significan.!

¿Qué es la integración continua?

En los modelos SDLC tradicionales, los desarrolladores migrarían las nuevas funciones a un entorno una por una y de forma aislada. Esto creaba problemas cuando tenía varios desarrolladores trabajando en varias funciones. La integración continua es una práctica que garantiza que los desarrolladores puedan realizar numerosos cambios en la rama principal de su aplicación web a través de un repositorio compartido, de manera sistemática. Al aprovechar la práctica de la integración continua, sus desarrolladores pueden integrar código sobre revisiones, mejoras de productos, etc. en un repositorio compartido, varias veces al día. De esa manera, su lanzamiento general al mercado puede acelerarse, permitiéndole ser ágil.

Si ha otorgado acceso de edición para el repositorio de GitHub a los desarrolladores de su equipo, solo necesita asegurarse de que los desarrolladores sigan las mejores prácticas, el estilo del código y, lo que es más importante, que los casos de prueba no estén fallando. Siempre que se cumplan estos requisitos, no debe prohibir que nadie verifique su código. Esto ayudaría a su empresa a escalar continuamente.

¿Qué es la entrega continua?

En cuanto a la entrega continua, solo ocurre después de que se realiza la IC. Como sugiere el nombre, la práctica Continuous Delivery garantiza que tenga una canalización automática configurada para implementar cambios de código de un entorno de prueba a otro.

Continuous Delivery incluye todos los pasos necesarios para que su software sea implementable. Esto incluye la ejecución de pruebas exhaustivas, el control de calidad mediante herramientas de prueba, la ejecución de compilaciones, la firma de código, la documentación y la implementación en entornos de preproducción o aceptación del usuario.

¡No confunda la entrega continua con la implementación continua!

Piense en la entrega continua como todo excepto la implementación. Usted prepara la implementación, pero en realidad no la implementa en los servidores de producción. Lo deja a los pasos de intervención humana que realmente asegurarán cuándo y dónde implementar. La entrega continua es adecuada para equipos en los que no se requiere implementación continua. Sin embargo, la implementación continua es una práctica que solo se puede implementar si tiene un sistema de migración bien definido que lo hace inviable para organizaciones con menos empleados a bordo. ¡Lo que nos lleva a nuestras próximas preguntas!

¿Qué es la implementación continua?

La implementación continua en realidad sigue a la entrega continua. Es una extensión de Continuous Delivery. Lleva la entrega continua un paso más allá hasta una etapa en la que la implementación de la nueva versión de la versión en la producción se lleva a cabo automáticamente.

El único requisito para la implementación continua es que el proceso, las comprobaciones y las pruebas establecidas garanticen una experiencia sin bloqueos. Ahora, dado que es un sistema completamente automatizado, es imperativo que dediquen más tiempo a desarrollar casos de prueba muy estrictos porque aquí no tienen ninguna posibilidad de revisar manualmente su migración, ¡una vez que se ha ido, se ha ido!

Es por eso que la implementación continua no es factible para todas las empresas. La implementación continua debe tener las reglas más estrictas posibles antes de implementar el código debido a que el proceso es un sistema completamente automatizado sin intervención humana.

Al ser el último paso en la cadena de producción automatizada de tuberías, es imperativo que los controles y pruebas a este nivel sean los más estrictos y cualquier valor inferior al 100 % debe ser rechazado, sin ningún margen de maniobra.

A pesar de todos los beneficios que conlleva la Implementación continua, un equipo debe validar los requisitos y solo adoptar la Implementación continua si el entorno de desarrollo, la sensibilidad de la producción y el sistema de prueba permiten una adopción perfecta.

Tenga en cuenta que si los sistemas en el lugar no están lo suficientemente maduros, la implementación podría resultar catastrófica para cualquier equipo. Es por eso que la mayoría de los equipos optan solo por la entrega continua y eso no tiene nada de malo. Depende totalmente de lo que esté construyendo y cuán crítico sea eso, y no existe una regla estricta y rápida que en realidad deba usar la implementación continua.

¿Qué es GitLab CI/CD?

Gitlab tiene una excelente oferta de CI/CD para proyectos alojados en Gitlab, así como en otros proveedores de git. Usando GitLab CI/CD puede incorporar las tres etapas que discutimos, es decir, integración continua, entrega continua e implementación continua.

Lo que hace que GitLab CI/CD sea poderoso es el hecho de que le permite alojar su repositorio de Git en cualquiera de los otros proveedores de Git, como GitHub, y aún puede aprovechar su sistema de CI/CD. Ni siquiera tiene que cambiar su proveedor de Git para usar get Gitlab CI/CD. El único requisito para ejecutar CI/CD es la presencia de un archivo de configuración especial GitLab CI YAML. El archivo GitLab CI YAML contiene todas las instrucciones y datos necesarios para ejecutar diferentes canalizaciones de CI/CD.

Hay muchas opciones de personalización disponibles para dar forma a las tuberías de acuerdo con las necesidades personalizadas.

Otra cosa clave a tener en cuenta es que .gitlab-ci.yml está controlado por versión y se coloca en el repositorio. Esto permite que incluso las versiones anteriores de su repositorio se construyan con éxito, lo que facilita que su equipo adopte la práctica de IC. La razón es que, si GitLab CI YAML se coloca en el repositorio mismo, significa que ahora ha colocado la lógica de CI/CD en su repositorio. Liberarlo de las preocupaciones de que su sistema CI/CD pueda fallar y usted pueda perder sus datos. Ahora, dondequiera que viva un código, su CI/CD está presente allí, lo que facilita el cambio de un entorno de alojamiento a otro, siempre que suponga la misma canalización. De esa manera, su equipo puede utilizar fácilmente las sucursales de CI como diferentes canalizaciones y trabajos especiales y tiene una única fuente de verdad para todas las canalizaciones de CD de CI.

¿Qué son las variables de entorno GitLab CI/CD?

Las variables Env son valores con nombre dinámico que se pueden usar para hacer que las canalizaciones de CI/CD sean completamente dinámicas y parametrizadas. En general, siempre es la mejor práctica seguir eliminando valores codificados y usar variables de entorno para hacer que los trabajos sean portátiles e independientes del proveedor.

Específicamente, Gitlab tiene una enorme lista de variables predefinidas que pueden ayudar a construir canalizaciones de CI/CD sólidas y flexibles. El enlace se puede utilizar para ver la lista completa.

Las variables más utilizadas e importantes comprenden:

  • CI_COMMIT_REF_NOMBRE
  • CI_COMMIT_BRANCH
  • CI_COMMIT_TAG
  • CI_EXTERNAL_PULL_REQUEST_IID
  • incluyendo otros

Estas variables permiten dar forma a las canalizaciones de acuerdo con diferentes ramas de git y, en mi opinión, esto proporciona una gran flexibilidad para diferenciar trabajos según los entornos. Para saber más, puedes echar un vistazo a la documentación oficial de GitLab para variables de entorno .

Siempre es mejor usar tantas variables de entorno como sea posible para que sus trabajos sean personalizables y flexibles.

Este tutorial de GitLab para principiantes y profesionales lo ayudará a aprender a usar GitLab, una de las herramientas de CI/CD más populares que se usan en DevOps.

¿Qué son las dependencias en caché de GitLab?

Cada trabajo de CI/CD requiere algún tipo de fase de creación en la que el objetivo estimado se crea utilizando dependencias de terceros. Dependiendo de la pila, estas dependencias se recuperan mediante administradores de complementos, importadores de módulos, etc. El problema común al compilar con módulos de terceros en todos los lenguajes es que se necesita mucho tiempo para obtener dependencias de fuentes de terceros y compilarlas. . Imagínese hacer este proceso más de cien veces al día para múltiples proyectos y calcule el tiempo y el desperdicio de recursos en los que incurre. No es una imagen agradable, ¿verdad?

Si hubiera una manera de almacenar en caché estas dependencias construidas y usarlas para múltiples canalizaciones, haría que CI se compilara mucho más rápido y reduciría el desperdicio de ancho de banda y desatascaría las canalizaciones de CI para que la misma Infra se pueda usar para muchas más compilaciones.Caché de GitLab Las dependencias le permiten hacer exactamente esto directamente desde el archivo .gitlab-ci.yaml .

Es tan simple como configurar un diccionario de caché en el archivo yaml y el atributo clave. Solo asegúrese de usar la misma clave en todos los trabajos donde se requiere el directorio en caché. La práctica común para garantizar la caché entre sucursales es usar variables de entorno de bases de git como clave de caché. Por ejemplo, CI_COMMIT_BRANCH puede ayudarlo a utilizar la memoria caché cada vez que se ejecuta un trabajo para una sucursal.

Gitlab CI/CD proporciona poderosas primitivas para invalidar el caché. Esto se puede hacer a través de la interfaz de usuario o borrando la clave de caché.

Una extensión: opcionalmente, puede obtener dependencias y compilarlas solo con cambios en el archivo de manifiesto del paquete. Esto es superior a usar caché siempre. Por ejemplo, solo obtener dependencias de node js cada vez que cambia package.json.

¿Cómo activar una canalización de CI/CD?

GitLab CI/CD le permite activar su canalización de las siguientes maneras:

  1. Activadores basados ​​en Git
  2. Webhooks/crones
  3. Intervención manual

Activadores basados ​​en Git: la forma más sencilla de activar CI/CD es realizar cualquier operación basada en git, como insertar una rama, fusionar una solicitud de extracción o crear una etiqueta para la que se mencionen los manipuladores en el archivo gitlab.yaml. Este es el método más utilizado y más conveniente para activar CI/CD.

Los webhooks proporcionan un método conveniente para activar CI/CD a pedido al realizar una llamada posterior HTTP a direcciones URL especializadas. Esto es muy útil para la activación basada en eventos donde se puede llamar al webhook cada vez que ocurre un evento requerido.

  • Por ejemplo, puede configurar un cron para ejecutar compilaciones nocturnas en Gitlab simplemente presionando la solicitud curl en la URL del webhook en el intervalo deseado.
  • Se puede usar cualquier otro evento siempre que se pueda activar el webhook en respuesta al evento.

Gitlab tiene una disposición en la que se puede solicitar la intervención manual de usuarios autorizados para continuar con los siguientes pasos del trabajo. EN gitlab.yaml puede mencionar una parte de la canalización para que se ejecute solo después de que alguien con acceso en el equipo pueda reanudar el trabajo desde la interfaz de usuario.

  • Esta característica permite construir canalizaciones de entrega continua que ya hemos discutido. Todo, excepto la implementación, se puede automatizar y solo después de la intervención manual, se puede realizar la implementación.

Parámetros exclusivos para GitLab CI/CD: solo y excepto

Solo y Excepto son dos parámetros que establecen una política de trabajo para limitar cuándo se crean trabajos. Estas construcciones son la tuerca y el tornillo de la canalización de CI/CD de gitlab que permiten la personalización y la ejecución condicional de trabajos para darle forma de acuerdo con sus propias necesidades.

  1. 'Solo' especifica los nombres de las ramas y las etiquetas para las que se activará el trabajo.
  2. 'Excepto' especifica los nombres de las ramas y las etiquetas para las que no se activará el trabajo.

Solo y excepto son de naturaleza inclusiva y permiten el uso de expresiones regulares. Esta es una característica realmente interesante y hace posible cualquier tipo de personalización tocando sobre cuerdas.

Solo y Excepto permiten especificar una ruta de repositorio para filtrar trabajos para bifurcaciones. Algunos de los valores interesantes que sólo y excepto toman son:

  • sucursales
  • etiquetas
  • fusionar_solicitudes

Esto se deriva de la condición previa de que Gitlab CI/CD sea compatible con la aplicación basada en git. Si usa varias claves solo o excepto, las claves se evaluarán como una sola expresión conjunta. Eso es:

  • solamente: significa "incluir este trabajo si todas las condiciones coinciden".
  • excepto: significa "excluir este trabajo si alguna de las condiciones coincide".

Con solo, las claves individuales se unen lógicamente mediante un AND:

excepto se implementa como una negación de esta expresión completa:

Esto significa que las claves se tratan como si estuvieran unidas por un OR. Esta relación podría describirse como:

Hay una lista enorme de atributos que pueden ser utilizados por condiciones de solo y excepto. Realmente recomiendo que verifique esos valores.

Integre y automatice sus conjuntos de pruebas de Selenium con GitLab CI en LambdaTest .

Ejecución de secuencias de comandos de prueba de Selenium para GitLab CI/CD

Apliquemos lo aprendido aquí.! El proyecto que usaremos hoy para este tutorial de GitLab CI/CD es HourGlass 2018, que es una aplicación de pila MERN (Mongo Express React & Nodejs). Es una sencilla aplicación de gestión del tiempo que utiliza las mejores prácticas disponibles en ese momento. Desafortunadamente, en el mundo de JS, esas mejores prácticas cambian todos los meses. Es posible que algunas de ellas se hayan actualizado, pero la mayoría siguen siendo relevantes y este es un repositorio de desarrollo de estilo de producción y escala de producción completo, con todas las mejores prácticas disponibles.

Probando la URL de la aplicación web: hourglass.surge.sh

Clonar el repositorio de GitHub

Asegúrese de clonar el repositorio de HourGlass GitHub en su instancia de GitLab CI. Después de la clonación, diríjase a la rama maestra y verifique el archivo YAML de GitLab .


image: node:10.19.0

stages:
  - install_dependencies
  - build
  - test
  - deploy

install_dependencies:
  stage: install_dependencies
  cache:
    key: $CI_COMMIT_REF_SLUG-$CI_PROJECT_DIR
    paths:
      - node_modules/
  script:
    - yarn install
  only:
    changes:
      - yarn.lock

#continuous integration
unit-test:
  stage: test
  cache:
    key: $CI_COMMIT_REF_SLUG-$CI_PROJECT_DIR
    paths:
      - node_modules/
    policy: pull
  script:
    yarn test

# Only runs in case of continuous delivery
integration-test:
  stage: test
  cache:
    key: $CI_COMMIT_REF_SLUG-$CI_PROJECT_DIR
    paths:
      - node_modules/
    policy: pull
  services:
  - mongo
  script:
    - echo $MONGO_URI_TESTS
    - yarn test:integration
  only:
  - merge_requests
  - prod



lint:
  stage: test
  cache:
    key: $CI_COMMIT_REF_SLUG-$CI_PROJECT_DIR
    paths:
      - node_modules/
    policy: pull
  script: yarn lint


e2e-test:
  stage: test
  services:
  - mongo
  cache:
    key: $CI_COMMIT_REF_SLUG-$CI_PROJECT_DIR
    paths:
      - build/
    policy: pull
  script:
    - node node_modules/node-static/bin/cli.js build --port 5000 --spa &
    - yarn start-prod-server
    - node node_modules/pm2/bin/pm2 logs &
    - sleep 3
    - yarn run test:e2e
  dependencies:
    - Build-client

  only:
    refs:
      - tags
  except:
    - /^((?!release).)*$/


Build-client:
  stage: build
  cache:
    key: $CI_COMMIT_REF_SLUG-$CI_PROJECT_DIR
    paths:
      - node_modules/
      - build/
    policy: pull-push

  script: yarn build-client
  artifacts:
    paths:
    - build




Build-docs:
  stage: build
  script: yarn docs
  cache:
    key: $CI_COMMIT_REF_SLUG-$CI_PROJECT_DIR
    paths:
      - node_modules/
    policy: pull
  only:
  - merge_requests
  - prod

Build-storybook:
  stage: build
  script: yarn build-storybook
  cache:
    key: $CI_COMMIT_REF_SLUG-$CI_PROJECT_DIR
    paths:
      - node_modules/
    policy: pull
  only:
  - merge_requests
  - prod



deploy-backend:
  stage: deploy
  image: ruby:latest
  cache:
    key: $CI_COMMIT_REF_SLUG-$CI_PROJECT_DIR
    paths:
      - node_modules/
    policy: pull
  script:
    - apt-get update -qy
    - apt-get install -y ruby-dev
    - gem install dpl
    - dpl --provider=heroku --app=$HEROKU_APP_NAME --api-key=$HEROKU_API_KEY
  dependencies:
    - e2e-test
  when: manual
  allow_failure: false
  only:
    refs:
      - tags
  except:
    - /^((?!release).)*$/



deploy-frontend:
  stage: deploy
  cache:
    key: $CI_COMMIT_REF_SLUG-$CI_PROJECT_DIR
    paths:
      - node_modules/
    policy: pull
  variables:
    REACT_APP_API_HOST: $REACT_APP_API_HOST_PROD
  script:
    - yarn build-client
    - node ./node_modules/.bin/surge -p build/ --domain $SURGE_DOMAIN
  when: manual
  allow_failure: false
  dependencies:
    - e2e-test
  only:
    refs:
      - tags
  except:
    - /^((?!release).)*$/

ver raw gitlab-ci.yml alojado con ❤ por GitHub

Configuración de canalización de CI/CD en GitLab CI

Para activar nuestra canalización de CI/CD, necesitaremos editar el archivo README.md. Podemos realizar estos cambios directamente a través de Web IDE. Podemos seguir adelante y agregar un comentario de muestra y presionar el compromiso. Asegúrese de realizar el cambio en la rama principal.

Una vez que confirme el código, puede saltar a la sección CI/CD sobre GitLab y notar que el trabajo se ejecutó con éxito. Puede encontrar lo siguiente en estado de ejecución:

  • Cliente de compilación
  • pelusa
  • Prueba de unidad

archivo gitlab

Ahora, envíe una solicitud de extracción/fusión a la rama de producción. Para la demostración, mantuvimos la rama de producción como la rama principal del repositorio de Git y no como la principal. Ahora, necesitamos fusionar de maestro a prod.

pruebas-automatizadas-con-gitlab

Nota: De forma predeterminada, antes de enviar la solicitud de fusión, encontrará la casilla de verificación marcada para "eliminar la rama de origen cuando se acepte la solicitud de fusión". Anule la selección de esa casilla de verificación.

GitLab CI/CD no realizará una fusión a menos que la canalización tenga éxito. Lo que significa que no aprobará los cambios hasta que sus scripts de prueba terminen de ejecutarse. Esa es una gran característica para ayudarlo a pasar una versión estable. Además, no tiene que esperar a que se completen los scripts de prueba para poder realizar una combinación. Todo lo que necesita hacer es hacer clic en el botón "Fusionar cuando la canalización tenga éxito" y GitLab CI se encargará de la fusión posterior a la ejecución de su script de prueba.

muestra-extracción-solicitud

Todos los trabajos por defecto se ejecutarán en paralelo, a menos que especifiques lo contrario. Esto reduce en gran medida el tiempo total consumido por el proceso de CI. Puede ver qué compilaciones se están pasando y qué trabajos se están ejecutando después de presionar la solicitud de combinación.

gitlab-CICD-tubería

Ahora, puede notar que se ejecutaría una prueba de integración en la tubería separada, junto con los trabajos discutidos anteriormente en la tubería más reciente, es decir, Linting y pruebas unitarias.

gitlab-repo

Las pruebas de integración garantizarán que su back-end y front-end estén bien sincronizados y que sus API respondan bien.

Crear una etiqueta para un lanzamiento

Para crear un lanzamiento, primero necesitaremos generar una etiqueta a través de GitLab CI/CD.

gitlab-ci-cd-con-selenio

Las etiquetas Git son extremadamente útiles si desea marcar algunos cambios importantes. Ahora, cree una nueva versión desde la rama maestra. Puede agregar cualquier mensaje allí para ayudarlo a recordar qué contiene esta versión principal o tal vez también puede agregar algunos puntos de control de versión de compilación. Luego puedes crear la etiqueta:

pruebas-de-selenio-automatizadas-con-gitlab

Tan pronto como se cree la etiqueta, comenzará a ejecutarse un proceso. Ahora, puede ir directamente a ver CICD y notar la nueva canalización en la parte superior creada, en respuesta al evento de creación de etiquetas.

En este pipeline puedes notar que hay 4 etapas. El primero es asegurarse de que todas las dependencias estén instaladas. Esto es crucial ya que ahora está creando la compilación final y no desea que se ignoren confusiones, errores, advertencias.

canalización de gitlab

La siguiente etapa es donde se establece el cliente de compilación.

gitlab-CICD

En tercer lugar, puede notar tres tipos de pruebas que se ejecutarían, es decir, casos de prueba unitaria, pelusa y luego prueba de extremo a extremo. Las pruebas de extremo a extremo es donde incorporará sus scripts de prueba de Selenium para realizar pruebas de navegadores cruzados . Luego, esos scripts de prueba se ejecutarán en Selenium Grid en línea ofrecido por LambdaTest.

Por último, cuando se aprueben los scripts de prueba de Selenium y la canalización avance a la siguiente etapa, donde se llevará a cabo la implementación en la etapa de backend y frontend.

secuencia de comandos de prueba de selenio

Nota: Estas etapas se activan manualmente. Encontrará un botón de reproducción una vez que la canalización llegue a esa etapa.

git-etiqueta

Eso es..! Ahora, una vez que presione el botón de reproducción. Puede implementar los cambios en los entornos respectivos. Puede continuar y validar sus scripts de prueba de Selenium en el panel de automatización de LambdaTest .

panel de control lambdatest

Entonces, como puede ver en el video grabado de su prueba de Selenium. Esta es la misma aplicación HourGlass que hemos estado tratando de implementar. Tenga en cuenta que se podría acceder a la aplicación web a través del servidor local utilizando 127.0.0.1:5000. Este es el paso, donde está ejecutando un servidor estático para alojar su archivo frontend y un servidor backend separado. Más tarde, puede ejecutar una prueba de un extremo a otro con LambdaTest Tunnel.

túnel lambda

Pruebas continuas con LambdaTest Selenium Grid

Como habrá notado, ejecutamos nuestro script sobre una cuadrícula de Selenium en línea de LambdaTest. ¿Cuál era la necesidad? Bueno, hacerlo puede ayudarlo a validar de forma rápida y automática los cambios de su código en el entorno de ensayo donde se migran a través de su canalización de CI/CD. De esa manera, está integrando continuamente el código para nuevas funciones, implementándolas continuamente de un entorno de prueba a otro, y ahora también puede probar continuamente esos cambios en el código. Por lo tanto, cada vez que se asigna un código a una rama para la que tiene listos los scripts de prueba de Selenium, ese fragmento de código se validará para las pruebas de compatibilidad del navegador. Permitiéndole acelerar los ciclos de prueba con la ayuda de pruebas continuas.

¿Cómo implementar pruebas continuas en DevOps como un profesional?

Ahora, reflexionemos un poco sobre cómo ejecutamos las pruebas de Selenium en una aplicación web alojada localmente a través de LambdaTest. Aquí está el script de prueba de Selenium utilizado para que el marco Jest realice pruebas de navegador automatizadas.

const webdriver = require('selenium-webdriver');
const { until } = require('selenium-webdriver');
const { By } = require('selenium-webdriver');
const lambdaTunnel = require('@lambdatest/node-tunnel');

const username = process.env.LT_USERNAME || 'Your_LambdaTest_Username';
const accessKey =
  process.env.LT_ACCESS_KEY ||
  'Your_LambdaTest_Access_Key';

const capabilities = {
  build: 'jest-LambdaTest-Single',
  browserName: 'chrome',
  version: '72.0',
  platform: 'WIN10',
  video: true,
  network: true,
  console: true,
  visual: true,
  tunnel: true,
};

const tunnelInstance = new lambdaTunnel();

const tunnelArguments = {
  user: process.env.LT_USERNAME || Your_LambdaTest_Username',
  key:
    process.env.LT_ACCESS_KEY ||
    'Your_LambdaTest_Access_Key',
};

const getElementById = async (driver, id, timeout = 2000) => {
  const el = await driver.wait(until.elementLocated(By.id(id)), timeout);
  return await driver.wait(until.elementIsVisible(el), timeout);
};

const getElementByClassName = async (driver, className, timeout = 2000) => {
  const el = await driver.wait(
    until.elementLocated(By.className(className)),
    timeout
  );
  return await driver.wait(until.elementIsVisible(el), timeout);
};

const getElementByName = async (driver, name, timeout = 2000) => {
  const el = await driver.wait(until.elementLocated(By.name(name)), timeout);
  return await driver.wait(until.elementIsVisible(el), timeout);
};

const getElementByXpath = async (driver, xpath, timeout = 2000) => {
  const el = await driver.wait(until.elementLocated(By.xpath(xpath)), timeout);
  return await driver.wait(until.elementIsVisible(el), timeout);
};

function timeout(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

describe('webdriver', () => {
  let driver;

  beforeAll(async () => {
    const istunnelStarted = await tunnelInstance.start(tunnelArguments);
    driver = new webdriver.Builder()
      .usingServer(
        'https://' + username + ':' + accessKey + '@hub.lambdatest.com/wd/hub'
      )
      .withCapabilities(capabilities)
      .build();
    // eslint-disable-next-line no-undef
    await driver.get(`http://127.0.0.1:5000/signup`); // https://hourglass.surge.sh/signup
  }, 20000);

  afterAll(async () => {
    await driver.quit();
    await tunnelInstance.stop();
  }, 15000);

  test(
    'Signup test',
    async () => {
      const nameInput = await getElementById(driver, 'name');
      await nameInput.clear();
      await nameInput.sendKeys('Mayank');

      const emailInput = await getElementById(driver, 'email');
      await emailInput.clear();
      await emailInput.sendKeys('mybach8@gmail.com');

      const passwordInput = await getElementById(driver, 'password');
      await passwordInput.clear();
      await passwordInput.sendKeys('password');

      const cnfPassInput = await getElementById(driver, 'confirmPassword');
      await cnfPassInput.clear();
      await cnfPassInput.sendKeys('password');

      const prefWorkingHours = await getElementById(
        driver,
        'preferredWorkingHours'
      );
      await prefWorkingHours.clear();
      await prefWorkingHours.sendKeys('10.0');

      const btn = await getElementByClassName(
        driver,
        'LoaderButton  btn btn-lg btn-default btn-block'
      );
      await btn.click();

      await timeout(2000);
      const successText = await getElementByClassName(
        driver,
        'registerSuccess'
      );
      const successTextValue = await successText.getText();
      console.log(successTextValue);
      return expect(successTextValue).toContain('Congratulations');
    },
    20000
  );

  test(
    'Login test',
    async () => {
      await driver.get(`http://127.0.0.1:5000/login`); // https://hourglass.surge.sh/signup
      // const lnk = await getElementByName(driver, 'li1');
      // await lnk.click();

      // const lnk1 = await getElementByName(driver, 'li2');
      // await lnk1.click();

      const emailInput = await getElementById(driver, 'email');
      await emailInput.clear();
      await emailInput.sendKeys('mybach8@gmail.com');

      const passwordInput = await getElementById(driver, 'password');
      await passwordInput.clear();
      await passwordInput.sendKeys('password');

      const btn = await getElementByClassName(
        driver,
        'btn btn-lg btn-default btn-block'
      );
      await btn.click();

      await timeout(2000);
      const successText = await getElementByClassName(
        driver,
        'btn btn-primary'
      );
      const successTextValue = await successText.getText();
      console.log(successTextValue);
      expect(successTextValue).toContain('Manage Time tracks');
    },
    20000
  );
});

ver raw selenium_testing_script.java alojado con ❤ por GitHub

 

Tutorial de código

Hay algunos argumentos de túnel que estamos usando aquí para trabajar en el túnel LambdaTest. LambdaTest lanza un paquete npm para configurar el túnel automáticamente.

const lambdaTunnel = require('@lambdatest/node-tunnel');

Lo que hemos hecho aquí es que antes de cada prueba estamos configurando un nuevo WebDriver y este controlador está dirigido a la URL pública de LambdaTest Selenium Grid Hub. Estamos utilizando el nombre de usuario y la clave de acceso proporcionados por la cuenta de LambdaTest.

const tunnelArguments = {
  user: process.env.LT_USERNAME || Your_LambdaTest_Username',
  key:
    process.env.LT_ACCESS_KEY ||
    'Your_LambdaTest_Access_Key',
};

Luego, proporciona todas las capacidades, como si desea usar LambdaTest Tunnel en un navegador específico, versión del navegador, sistema operativo, con grabación de video, etc.


const capabilities = {
  build: 'jest-LambdaTest-Single',
  browserName: 'chrome',
  version: '72.0',
  platform: 'WIN10',
  video: true,
  network: true,
  console: true,
  visual: true,
  tunnel: true,
};

ver raw lambda-tunnel.java alojado con ❤ por GitHub

Estamos construyendo la URL utilizando las variables de entorno, es decir, su nombre de usuario y clave de acceso de LambdaTest.



.usingServer(
        'https://' + username + ':' + accessKey + '@hub.lambdatest.com/wd/hub'
      )

Una vez que se configura el WebDriver remoto para Selenium Grid en línea, estamos esperando que se cargue la página de registro.

await driver.get(`http://127.0.0.1:5000/signup`); // https://hourglass.surge.sh/signup
  }, 20000);

El siguiente fragmento de código garantizará que las instancias de túnel se inicien primero y solo después de eso se ejecutará su secuencia de comandos de prueba de Selenium.

const istunnelStarted = await tunnelInstance.start(tunnelArguments);

Práctica recomendada: una vez que haya terminado con todos los casos de prueba, asegúrese de eliminar la instancia del túnel. Esto ayudará a salvar su límite de concurrencia disponible en LambdaTest Selenium Grid. Existe una cantidad limitada de túneles que puede ejecutar por conteo, según el precio de LambdaTest que elija y si deja un túnel en estado de ejecución, incluso después de ejecutar las pruebas. No le permitirá usar el túnel en otros casos de prueba, por lo que es una buena práctica cerrar un túnel después de que se hayan completado las pruebas.

afterAll(async () => {
    await driver.quit();
    await tunnelInstance.stop();
  }, 15000);

Registros de monitoreo

LambdaTest le proporciona una interfaz intuitiva para analizar los resultados de los scripts de prueba de Selenium. Puede obtener una variedad de registros, como registros de red, registros de comandos, registros de Selenium sin procesar, metadatos. También puede grabar un video de la ejecución completa del script, junto con capturas de pantalla comando por comando. Puede notar que la prueba se ha activado con éxito en Selenium Grid de LambdaTest en línea.

monitorear-registros

Puede visitar diferentes tipos de pestañas en el panel de automatización para descubrir qué salió mal al depurar sus scripts. Así es como se proporcionan los registros.

Registros de selenio

registros de automatización

Registros de comandos

registros de automatización

Registros de la consola

lambdatest-automatización-registros

Eventualmente, GitLab CI implementará el backend en Heroku y el front-end en Surge. Entonces, después de abrir la URL, puede ver que el frontend se implementa en Serge y mi backend se implementa en Heroku y esto lo hace automáticamente la canalización GitLab CI/CD.

Ahora, anotemos rápidamente algunas de las mejores prácticas que debe tener en cuenta para CI/CD antes de terminar este tutorial de GitLab CI/CD.

Mejores prácticas para CI/CD

Ahora que ha tenido una buena cantidad de conocimiento sobre cómo aprovechar las canalizaciones de CI de GitLab para las pruebas de Selenium. Le sugiero que tome notas de estas mejores prácticas para CI/CD para crear mejores aplicaciones web, más rápido.

Cree rápido y pruebe más rápido
 

El éxito de los sistemas CI/CD depende de la velocidad de ejecución. Si los ciclos de CI toman una gran cantidad de tiempo para cada confirmación, los desarrolladores encontrarán omisiones alternativas y más rápidas para integrar su código rápidamente. Esto a menudo implica vías que se saltan las pruebas en favor de actualizaciones optimistas. Esto puede causar estragos en la producción. Creo que ni siquiera necesito mencionar las consecuencias de integrar código no probado.

Los entornos de CI/CD deben estar protegidos

A menudo se ignora, pero es muy importante proteger su entorno de CI/CD. Es una de las piezas de infraestructura más sensibles para proteger, ya que contiene acceso a su base de código, datos altamente confidenciales y varios entornos. Además, es uno de los sistemas más utilizados en un equipo de desarrollo grande y de alta frecuencia. Cualquier interrupción en CI/CD puede causar una enorme pérdida de productividad y pérdidas financieras en el peor de los casos.

CI/CD debería ser la única forma de implementar en la producción

Las canalizaciones de CI/CD son tan exitosas como la última persona que las usó. Todo el esfuerzo de desarrollar CI/CD falla si no es adoptado por el equipo. CI/CD debería ser estrictamente la única forma de implementar en el prod. De hecho, las reversiones deben implementarse a través de la misma canalización.

Mantenga siempre las opciones de reversión en las canalizaciones de CI/CD

La capacidad de revertir un cambio no debería implicar procedimientos complejos. Debería ser lo más simple posible deshacer un cambio. Siempre es mejor deshacer los cambios a las 3 AM en lugar de depurarlos en producción.

fallar temprano

Debe ejecutar su prueba más rápida al principio de la canalización. La idea es rechazar la compilación si falla alguna prueba. Rechazar temprano ahorra mucho tiempo y hace que el tiempo de respuesta sea realmente pequeño.

Ejecute pruebas localmente antes de comprometerse con la canalización de CI/CD

CI comienza en su sistema de desarrollo local. Todas las pruebas básicas de CI deben ejecutarse primero en su sistema local, ya que es rápido, ahorra tiempo y conserva la infraestructura de CI/CD en la plataforma para canalizaciones más críticas y en etapas posteriores.

Las pruebas deben ejecutarse en un entorno efímero

Para proporcionar resultados consistentes para las canalizaciones de CI/CD, es importante que las pruebas se ejecuten en un estado nuevo cada vez. Los entornos efímeros son una necesidad para hacer que las pruebas sean idempotentes. Los contenedores son un entorno adecuado, ya que facilitan la creación de un entorno fresco.

Desacoplar la implementación y el lanzamiento

Como se mencionó en la introducción de la entrega continua, desvincular la implementación del proceso de lanzamiento hace que el proceso de lanzamiento sea una decisión puramente del equipo de marketing y estrategia. Esto tiene enormes beneficios en términos de flexibilidad y velocidad.

Terminando

¡¡Prestigio!! Ahora ha ejecutado con éxito las pruebas de Selenium para realizar todo tipo de comprobaciones antes de que se implemente la versión. GitLab CI preparó el proceso de lanzamiento para usted y eliminó todas las molestias de hacer esos controles de última hora, al permitirle integrarse con Selenium Grid en línea de más de 3000 navegadores reales, lo que garantiza una interfaz de usuario perfecta para su aplicación web.

Así es como podemos construir una canalización sólida de CI/CD para su empresa o equipo allí. 

Si aún tiene alguna pregunta, no dude en publicarla en la sección de comentarios a continuación. ¡Feliz prueba! 🙂 

Esta historia se publicó originalmente en https://www.lambdatest.com/blog/automated-testing-pipeline-with-gitlab-ci-cd-and-selenium/

#gitlab #testing #cicd #selenium 

Canalización De Prueba Automatizada Con GitLab CI/CD Y Selenium Grid
坂本  健一

坂本 健一

1654925100

GitLab CI/CDとSeleniumグリッドを使用して自動テストパイプラインを構築する

CI / CDは多くの注目を集めており、おそらくDevOpsの初心者にとって最も話題になっているトピックの1つです。市場で入手可能なCI/CDツールが利用できるようになったため、CI / CDパイプラインの構成と運用は、5〜6年前よりもはるかに簡単になりました。当時、コンテナはなく、球体を支配したCI/CDツールはJenkinsだけでした。Jenkinsはタスクランナーを提供したので、順次または並行して実行するジョブを定義できます。

今日、シナリオは異なります。市場には多数のCI/CDツールがあり、Jenkinsと比較して追加の機能を提供しています。そのような有名なCI/CDツールの1つがGitLabCIであり、これがまさにこの記事で取り上げる内容です。

この記事では、GitLab CI/CDを使用してCI/CDパイプラインを構成し、3000以上の実際のブラウザーのオンラインSeleniumグリッドであるLambdaTestを介してSeleniumテストを実行します。

SeleniumテストスイートをLambdaTestのGitLabCIと統合して自動化します。

CI/CDの基本

CI / CDは、一貫性のある信頼性の高い方法でWebアプリケーションに製品の更新を確実に配信するために従うベストプラクティスのコレクションです。Webアプリケーションは、新しいリリースサイクルに取り入れられるすべてのスプリントで成長するはずです。最初は、Webアプリケーションのコード変更を担当する小さなチームがいる場合があります。このような場合は、すべてを直接実行してもかまいません。コードをビルドし、自分でテストして、本番環境にデプロイします。

ただし、チームが成長するにつれて、多くの相互作用ポイントが存在し、あるステージング環境から別のステージング環境にすべてのコード変更を移行しようとすると、エラーが発生する可能性が高くなります。ここで、CI/CDパイプラインが極めて重要な役割を果たします。

オンラインで成功するビジネスは、CI/CDパイプラインの構成方法に大きく依存します。Uberの成長とスケーラビリティを説明した記事の1つで、次のように述べています。

Uberは現在400の都市と70か国にあります。彼らには6000人以上の従業員がいて、そのうち2000人はエンジニアです。わずか1年半前には200人のエンジニアしかいませんでした。これらのエンジニアは、8000を超えるgitリポジトリに保存されている1000を超えるマイクロサービスを作成しました。

ビジネスの成長速度を観察すると、CI / CDパイプラインが組み込まれていなかった場合、Uberが10人のエンジニアと調整するためにわずか1年半で直面する可能性のある課題を想像できます。今日の世界では、CI / CDのベストプラクティスに従わずに、速度と一貫性の点でスケーラブルなWebアプリケーションを想像するのは非常に困難です。さて、CIとCDとは何ですか?CIは継続的インテグレーションを指し、CDは継続的デリバリーを意味します。両方を組み合わせると、継続的展開を実現できます。それらが実際に何を意味するのか見てみましょう。

継続的インテグレーションとは何ですか?

従来のSDLCモデルでは、開発者は新しい機能を1つずつ環境に個別に移行していました。これにより、複数の開発者が複数の機能を操作している場合に問題が発生しました。継続的インテグレーションは、開発者が共有リポジトリを介して、体系的な方法でWebアプリケーションのメインブランチに多数の変更をコミットできるようにする手法です。継続的インテグレーションの手法を活用することで、開発者は、修正プログラムや製品の機能強化などに関するコードを1日に複数回共有リポジトリに統合できます。そうすることで、市場投入全体の立ち上げを加速し、アジャイルを実現できます。

チーム内の開発者にGitHubリポジトリの編集アクセス権を付与した場合は、開発者がベストプラクティス、コードスタイル、そして最も重要なテストケースが失敗していないことを確認するだけで済みます。これらの要件が満たされている限り、誰もがコードをチェックインすることを禁止しないでください。これは、会社が継続的に拡張するのに役立ちます。

継続的デリバリーとは何ですか?

継続的デリバリーになると、CIが実行された後にのみ発生します。名前が示すように、継続的デリバリーを実践することで、あるステージング環境から別のステージング環境にコード変更をデプロイするように自動パイプラインを構成できます。

継続的デリバリーには、ソフトウェアをデプロイ可能にするために必要なすべてのステップが含まれています。これには、包括的なテストの実行、テストツールを使用した品質保証、ビルドの実行、コード署名、ドキュメント化、および製品前またはユーザー受け入れ環境への展開が含まれます。

継続的デリバリーと継続的デプロイを混同しないでください!!

継続的デリバリーは、デプロイ以外のすべてのものと考えてください。デプロイメントを準備しますが、実際には実稼働サーバーにデプロイしません。いつどこに展開するかを実際に保証する人間の介入手順に任せます。継続的デリバリーは、継続的デプロイが不要なチームに適しています。ただし、継続的展開は、明確に定義された移行システムが設定されている場合にのみ実装できる手法であり、これにより、参加している従業員が少ない組織では実行不可能になります。次の質問に移ります。

継続的展開とは何ですか?

継続的デプロイは、実際には継続的デリバリーでフォローアップします。これは、継続的デリバリーの拡張です。継続的デリバリーは、本番環境でのバージョンの新しいリリースのデプロイが自動的に実行される段階にさらに一歩進みます。

継続的な展開の唯一の要件は、プロセス、チェック、およびテストのセットアップにより、クラッシュのないエクスペリエンスが保証されることです。さて、これは完全に自動化されたシステムであるため、移行を手動で確認する機会がないため、非常に厳密なテストケースの開発により多くの時間を費やすことが不可欠です。移行が終了すると、移行は終了します。

そのため、すべての企業が継続的展開を実行できるわけではありません。プロセスは人間の介入なしに完全に自動化されたシステムであるため、継続的デプロイでは、コードをデプロイする前に可能な限り厳格なルールを設定する必要があります。

自動パイプライン生産のチェーンの最後のステップであるため、このレベルでのチェックとテストは最も厳格であり、100%未満のものは余裕を持たずに拒否する必要があります。

継続的展開にはすべてのメリットがありますが、チームは要件を検証し、開発環境、本番環境の感度、およびテストシステムでシームレスな採用が可能な場合にのみ継続的展開を採用する必要があります。

その場所のシステムが十分に成熟していない場合、展開はどのチームにとっても壊滅的なものになる可能性があることに注意してください。そのため、ほとんどのチームは継続的デリバリーのみを採用しており、害はありません。それは、何を構築しているか、そしてそれがどれほど重要であるかに完全に依存します。実際に継続的デプロイを使用する必要があるという厳格なルールはありません。

GitLab CI / CDとは何ですか?

Gitlabには、Gitlabや他のgitプロバイダーでホストされているプロジェクト向けの優れたCI/CDオファリングがあります。GitLab CI / CDを使用すると、継続的インテグレーション、継続的デリバリー、継続的デプロイという、これまでに説明した3つのステージすべてを組み込むことができます。

GitLab CI / CDを強力なものにしているのは、GitリポジトリをGitHubなどの他のGitプロバイダーのいずれかにホストでき、それでもCI/CDシステムを利用できるという事実です。get Gitlab CI / CDを使用するために、Gitプロバイダーを変更する必要はありません。CI / CDを実行するための唯一の要件は、特別なGitLabCIYAML構成ファイルの存在です。GitLab CI YAMLファイルには、さまざまなCI/CDパイプラインを実行するために必要なすべての命令とデータが含まれています。

カスタムニーズに応じてパイプラインを形成するために利用できるカスタマイズオプションはたくさんあります。

注意すべきもう1つの重要な点は、.gitlab-ci.ymlがバージョン管理され、リポジトリに配置されていることです。これにより、古いバージョンのリポジトリでも正常にビルドできるようになり、チームがCIプラクティスを採用しやすくなります。理由は、GitLab CI YAMLがリポジトリ自体に配置されている場合、CI/CDのロジックをリポジトリに配置したことを意味します。CI / CDシステムに障害が発生し、データが失われる可能性があるという心配から解放されます。これで、コードが存在する場所にCI / CDが存在するため、同じパイプラインを想定している限り、あるホスティング環境から別のホスティング環境への移行が簡単になります。これにより、チームはCIブランチを次のように簡単に利用できます。特別な異なるパイプラインとジョブがあり、すべてのCICDパイプラインの信頼できる唯一の情報源があります。

GitLab CI / CD環境変数とは何ですか?

環境変数は動的な名前の値であり、CI/CDパイプラインを完全に動的にしてパラメーター化するために使用できます。一般に、ハードコードされた値を削除し続け、環境変数を使用してジョブを移植可能にし、プロバイダーに依存しないようにすることが常にベストプラクティスです。

具体的には、Gitlabには、堅牢で柔軟なCI/CDパイプラインの構築に役立つ事前定義された変数の膨大なリストがあります。リンクを使用して、完全なリストを表示できます。

最も一般的に使用される重要な変数は、次のもので構成されます。

  • CI_COMMIT_REF_NAME
  • CI_COMMIT_BRANCH
  • CI_COMMIT_TAG
  • CI_EXTERNAL_PULL_REQUEST_IID
  • 他の人を含む

これらの変数を使用すると、さまざまなgitブランチとIMOに従ってパイプラインを形成できます。これにより、環境に基づいてジョブを区別する際の柔軟性が大幅に向上します。詳細については、環境変数に関するGitLabの公式ドキュメントをご覧ください。

ジョブをカスタマイズ可能で柔軟にするために、できるだけ多くの環境変数を使用することをお勧めします。

初心者と専門家向けのこのGitLabチュートリアルは、DevOpsで使用される最も人気のあるCI/CDツールの1つであるGitLabの使用方法を学ぶのに役立ちます。

GitLabのキャッシュされた依存関係とは何ですか?

すべてのCI/CDジョブには、サードパーティの依存関係を使用してestターゲットを構築する何らかの構築フェーズが必要です。スタックに応じて、これらの依存関係はプラグインマネージャー、モジュールインポーターなどを使用したフェッチです。すべての言語でサードパーティモジュールを使用して構築する場合の一般的な問題点は、サードパーティソースから依存関係をフェッチしてコンパイルするのに時間がかかることです。 。複数のプロジェクトでこのプロセスを1日に100回以上実行し、発生する時間とリソースの浪費を計算することを想像してみてください。楽しい絵ではありませんよね?

これらのビルドされた依存関係をキャッシュし、これらのキャッシュされた依存関係を複数のパイプラインに使用する方法があれば、CIビルドがはるかに高速になり、帯域幅の浪費が減り、CIパイプラインの目詰まりが解消されるため、同じインフラストラクチャをはるかに多くのビルドに使用できます。GitLabのキャッシュ依存関係により、これを.gitlab-ci.yamlファイルから直接実行できます。

yamlファイルとキー属性にキャッシュディクショナリを設定するのと同じくらい簡単です。キャッシュされたディレクトリが必要なすべてのジョブで同じキーを使用するようにしてください。ブランチ間のキャッシュを確保するための一般的な方法は、キャッシュキーとしてgitbases環境変数を使用することです。たとえば、CI_COMMIT_BRANCHは、ブランチに対してジョブが実行されるたびにキャッシュを利用するのに役立ちます。

Gitlab CI / CDは、キャッシュを無効にする強力なプリミティブを提供します。これは、UIを介して、またはキャッシュキーをクリアすることによって実行できます。

拡張機能:オプションで依存関係をフェッチし、マニフェストファイルの変更のみをパッケージ化してビルドできます。これは、常にキャッシュを使用するよりも優れています。たとえば、package.jsonが変更されるたびに、ノードjsの依存関係のみをフェッチします。

CI / CDパイプラインをトリガーする方法は?

GitLab CI / CDを使用すると、次の方法を使用してパイプラインをトリガーできます。

  1. Gitベースのトリガー
  2. Webhook /crons
  3. 手動介入

Gitベースのトリガー– CI / CDをトリガーする最も簡単な方法は、ブランチのプッシュ、プルリクエストのマージ、gitlab.yamlファイルにハンドラーが記載されているタグの作成などのgitベースの操作を実行することです。これは、CI/CDをトリガーするために最も頻繁に使用される最も便利な方法です。

Webhookは、特殊なURLへのHTTP POST呼び出しを行うことにより、オンデマンドでCI/CDをトリガーする便利な方法を提供します。これは、必要なイベントが発生するたびにWebhookを呼び出すことができるイベントベースのトリガーに非常に役立ちます

  • たとえば、必要な間隔でWebhook URLのcurlリクエストを押すだけで、Gitlabでナイトリービルドを実行するようにcronを設定できます。
  • イベントに応答してWebhookをヒットできる限り、他のイベントを使用できます。

Gitlabには、許可されたユーザーによる手動介入を要求して、ジョブの次のステップを続行できるようにする規定があります。gitlab.yamlで、チーム内のアクセス権を持つ誰かがUIからジョブを再開できるようになった後にのみ実行するパイプラインの一部について言及できます。

  • この機能により、すでに説明した継続的デリバリーパイプラインを構築できます。展開以外はすべて自動化でき、手動で介入した後にのみ展開を実行できます。

GitLab CI / CDの排他的パラメーター:のみおよび例外

OnlyとExceptは、ジョブの作成時に制限するジョブポリシーを設定する2つのパラメーターです。これらの構成要素は、gitlab CI / CDパイプラインの要であり、ジョブのカスタマイズと条件付き実行により、独自のニーズに応じてジョブを形成できます。

  1. 「のみ」は、ジョブがトリガーされるブランチとタグの名前を指定します。
  2. 「Except」は、ジョブがトリガーされないブランチとタグの名前を指定します。

のみとを除いて、本質的に包括的であり、正規表現の使用を許可します。これは非常に興味深い機能であり、弦を弾くことであらゆる種類のカスタマイズが可能になります。

OnlyとExceptでは、フォークのジョブをフィルタリングするためのリポジトリパスを指定できます。取るだけで、それ以外の興味深い値のいくつかは次のとおりです。

  • タグ
  • merge_requests

これは、Gitlab CI / CDがgitベースのアプリケーションでサポートされているという前提条件に基づいています。複数のキーを使用する場合、またはそれ以外の場合、キーは単一の結合された式として評価されます。あれは:

  • only:「すべての条件が一致する場合にこのジョブを含める」ことを意味します。
  • ただし、「条件のいずれかが一致した場合、このジョブを除外する」ことを意味します。

のみの場合、個々のキーは論理的にANDで結合されます。

ただし、この完全な式の否定として実装されます。

これは、キーがORで結合されているかのように扱われることを意味します。この関係は次のように説明できます。

条件のみで使用できる属性の膨大なリストがあります。これらの値を確認することを強くお勧めします。

SeleniumテストスイートをLambdaTestのGitLabCIと統合して自動化します。

GitLab CI/CDのSeleniumテストスクリプトの実行

ここで学んだことを応用してみましょう。このGitLabCI/ CDチュートリアルで今日使用するプロジェクトは、 MERN(Mongo Express React&Nodejs)スタックアプリケーションであるHourGlass2018です。これは、当時利用可能なベストプラクティスを使用したシンプルな時間管理アプリケーションです。残念ながら、JSの世界では、これらのベストプラクティスは毎月変更されます。これらの一部は更新されている可能性がありますが、これらのほとんどは依然として関連性があり、これは完全な本番スケールおよび本番スタイルの開発リポジトリであり、すべてのベストプラクティスが利用可能です。

WebアプリケーションのURLをテストしています:hourglass.surge.sh

GitHubリポジトリのクローンを作成する

HourGlassGitHubリポジトリをGitLabCIインスタンスに複製してください。クローン作成後、マスターブランチにルーティングし、GitLabYAMLファイルを確認します。


image: node:10.19.0

stages:
  - install_dependencies
  - build
  - test
  - deploy

install_dependencies:
  stage: install_dependencies
  cache:
    key: $CI_COMMIT_REF_SLUG-$CI_PROJECT_DIR
    paths:
      - node_modules/
  script:
    - yarn install
  only:
    changes:
      - yarn.lock

#continuous integration
unit-test:
  stage: test
  cache:
    key: $CI_COMMIT_REF_SLUG-$CI_PROJECT_DIR
    paths:
      - node_modules/
    policy: pull
  script:
    yarn test

# Only runs in case of continuous delivery
integration-test:
  stage: test
  cache:
    key: $CI_COMMIT_REF_SLUG-$CI_PROJECT_DIR
    paths:
      - node_modules/
    policy: pull
  services:
  - mongo
  script:
    - echo $MONGO_URI_TESTS
    - yarn test:integration
  only:
  - merge_requests
  - prod



lint:
  stage: test
  cache:
    key: $CI_COMMIT_REF_SLUG-$CI_PROJECT_DIR
    paths:
      - node_modules/
    policy: pull
  script: yarn lint


e2e-test:
  stage: test
  services:
  - mongo
  cache:
    key: $CI_COMMIT_REF_SLUG-$CI_PROJECT_DIR
    paths:
      - build/
    policy: pull
  script:
    - node node_modules/node-static/bin/cli.js build --port 5000 --spa &
    - yarn start-prod-server
    - node node_modules/pm2/bin/pm2 logs &
    - sleep 3
    - yarn run test:e2e
  dependencies:
    - Build-client

  only:
    refs:
      - tags
  except:
    - /^((?!release).)*$/


Build-client:
  stage: build
  cache:
    key: $CI_COMMIT_REF_SLUG-$CI_PROJECT_DIR
    paths:
      - node_modules/
      - build/
    policy: pull-push

  script: yarn build-client
  artifacts:
    paths:
    - build




Build-docs:
  stage: build
  script: yarn docs
  cache:
    key: $CI_COMMIT_REF_SLUG-$CI_PROJECT_DIR
    paths:
      - node_modules/
    policy: pull
  only:
  - merge_requests
  - prod

Build-storybook:
  stage: build
  script: yarn build-storybook
  cache:
    key: $CI_COMMIT_REF_SLUG-$CI_PROJECT_DIR
    paths:
      - node_modules/
    policy: pull
  only:
  - merge_requests
  - prod



deploy-backend:
  stage: deploy
  image: ruby:latest
  cache:
    key: $CI_COMMIT_REF_SLUG-$CI_PROJECT_DIR
    paths:
      - node_modules/
    policy: pull
  script:
    - apt-get update -qy
    - apt-get install -y ruby-dev
    - gem install dpl
    - dpl --provider=heroku --app=$HEROKU_APP_NAME --api-key=$HEROKU_API_KEY
  dependencies:
    - e2e-test
  when: manual
  allow_failure: false
  only:
    refs:
      - tags
  except:
    - /^((?!release).)*$/



deploy-frontend:
  stage: deploy
  cache:
    key: $CI_COMMIT_REF_SLUG-$CI_PROJECT_DIR
    paths:
      - node_modules/
    policy: pull
  variables:
    REACT_APP_API_HOST: $REACT_APP_API_HOST_PROD
  script:
    - yarn build-client
    - node ./node_modules/.bin/surge -p build/ --domain $SURGE_DOMAIN
  when: manual
  allow_failure: false
  dependencies:
    - e2e-test
  only:
    refs:
      - tags
  except:
    - /^((?!release).)*$/

GitHubによって❤でホストされている生のgitlab-ci.ymlを表示する

GitLabCIでのCI/CDパイプラインの構成

CI / CDパイプラインをトリガーするには、README.mdファイルを編集する必要があります。これらの変更は、WebIDEを介して直接行うことができます。先に進んでサンプルコメントを追加し、コミットをヒットすることができます。必ずマスターブランチで変更を行ってください。

コードをコミットすると、GitLabのCI / CDセクションにジャンプして、ジョブが正常に実行されたことを確認できます。実行状態では、次のものを見つけることができます。

  • ビルドクライアント
  • リンティング
  • 単体テスト

gitlab-ファイル

次に、本番ブランチにプル/マージリクエストを送信します。デモでは、本番ブランチをマスターではなくGitリポジトリのメインブランチとして保持しました。ここで、マスターから製品にマージする必要があります。

gitlabによる自動テスト

注:デフォルトでは、マージリクエストを送信する前に、[マージリクエストが受け入れられたらソースブランチを削除する]チェックボックスがオンになっています。そのチェックボックスの選択を解除します。

パイプラインが成功しない限り、GitLab CI/CDはマージを実行しません。つまり、テストスクリプトが実行されるまで、変更は渡されません。これは、安定したリリースに合格するのに役立つ優れた機能です。また、マージを実行できるように、テストスクリプトが完了するのを待つ必要はありません。「パイプラインが成功したときにマージする」ボタンをクリックするだけで、GitLabCIがテストスクリプトの実行後にマージを処理します。

サンプルプルリクエスト

特に指定しない限り、デフォルトではすべてのジョブが並行して実行されます。これにより、CIプロセスで消費される全体的な時間が大幅に短縮されます。マージリクエストをヒットした後、どのビルドが渡され、どのジョブが実行されているかを確認できます。

gitlab-CICD-パイプライン

これで、統合テストがデタッチされたパイプラインで実行され、最新のパイプラインで前述したジョブ、つまりリンティングと単体テストが実行されることに気付くかもしれません。

gitlab-repo

統合テストにより、バックエンドとフロントエンドが適切に同期し、APIが適切に応答していることが確認されます。

リリース用のタグの作成

リリースを作成するには、最初にGitLab CI/CDを介してタグを生成する必要があります。

gitlab-ci-cd-with-selenium

Gitタグは、重要な変更をブックマークする場合に非常に便利です。次に、マスターブランチから新しいリリースを作成します。このメインリリースに何が含まれているかを思い出すのに役立つメッセージをそこに追加したり、ビルドリリースのチェックポイントを追加したりすることもできます。次に、タグを作成できます。

gitlabを使用した自動セレンテスト

タグが作成されるとすぐに、プロセスの実行が開始されます。これで、CICDを簡単に確認して、タグ作成イベントに応答して、上部に作成された新しいパイプラインに気付くことができます。

このパイプラインでは、4つの段階があることに気付くことができます。1つ目は、すべての依存関係がインストールされていることを確認することです。これは、現在最終ビルドを作成していて、混乱、バグ、警告を無視したくないため、非常に重要です。

gitlab-パイプライン

次の段階では、ビルドクライアントが確立されます。

gitlab-CICD

第3に、実行される3種類のテスト、つまり単体テストケース、リンティング、およびエンドツーエンドテストに気付くことができます。エンドツーエンドのテストでは、Seleniumテストスクリプトを組み込んでクロスブラウザーテストを実行します。次に、LambdaTestが提供するオンラインのSeleniumグリッド上でこれらのテストスクリプトを実行します。

最後に、Seleniumテストスクリプトに合格すると、パイプラインは次のステージに移動し、バックエンドとフロントエンドのステージでの展開が行われます。

セレンテストスクリプト

注:これらのステージは手動でトリガーされます。パイプラインがそのステージに進むと、再生ボタンが表示されます。

git-tag

それだ..!さて、再生ボタンを押すと。変更をそれぞれの環境にデプロイできます。LambdaTest Automation Dashboardを使用して、Seleniumテストスクリプトを検証できます。

ラムダテスト-ダッシュボード

Seleniumテストの録画ビデオでわかるように。これは、デプロイしようとしているのと同じHourGlassアプリケーションです。Webアプリケーションは、127.0.0.1:5000を使用してローカルホスト経由でアクセスできることに注意してください。これは、静的サーバーを実行してフロントエンドファイルをホストし、バックエンドサーバーを分離するステップです。後で、LambdaTestトンネルを使用してエンドツーエンドのテストを実行できます。

ラムダトンネル

LambdaTestSeleniumグリッドを使用した継続的テスト

お気づきのとおり、LambdaTestのオンラインSeleniumグリッド上でスクリプトを実行しました。何が必要でしたか?そうすることで、コードの変更をCI/CDパイプラインを介して移行されるステージング環境にすばやく自動的に検証することができます。このようにして、新しい機能のコードを継続的に統合し、あるステージング環境から別のステージング環境に継続的にデプロイします。これで、これらのコードの変更も継続的にテストできます。したがって、Seleniumテストスクリプトの準備ができているブランチにコードがコミットされるたびに、そのコードはブラウザーの互換性テストのために検証されます。継続的テストの助けを借りて、テストサイクルを加速することができます。

プロのようにDevOpsで継続的テストを実装する方法は?

それでは、LambdaTestを介してローカルでホストされているWebアプリケーションでSeleniumテストを実行した方法について少し考えてみましょう。これは、自動ブラウザテストを実行するためにJestフレームワークに使用されるSeleniumテストスクリプトです。

const webdriver = require('selenium-webdriver');
const { until } = require('selenium-webdriver');
const { By } = require('selenium-webdriver');
const lambdaTunnel = require('@lambdatest/node-tunnel');

const username = process.env.LT_USERNAME || 'Your_LambdaTest_Username';
const accessKey =
  process.env.LT_ACCESS_KEY ||
  'Your_LambdaTest_Access_Key';

const capabilities = {
  build: 'jest-LambdaTest-Single',
  browserName: 'chrome',
  version: '72.0',
  platform: 'WIN10',
  video: true,
  network: true,
  console: true,
  visual: true,
  tunnel: true,
};

const tunnelInstance = new lambdaTunnel();

const tunnelArguments = {
  user: process.env.LT_USERNAME || Your_LambdaTest_Username',
  key:
    process.env.LT_ACCESS_KEY ||
    'Your_LambdaTest_Access_Key',
};

const getElementById = async (driver, id, timeout = 2000) => {
  const el = await driver.wait(until.elementLocated(By.id(id)), timeout);
  return await driver.wait(until.elementIsVisible(el), timeout);
};

const getElementByClassName = async (driver, className, timeout = 2000) => {
  const el = await driver.wait(
    until.elementLocated(By.className(className)),
    timeout
  );
  return await driver.wait(until.elementIsVisible(el), timeout);
};

const getElementByName = async (driver, name, timeout = 2000) => {
  const el = await driver.wait(until.elementLocated(By.name(name)), timeout);
  return await driver.wait(until.elementIsVisible(el), timeout);
};

const getElementByXpath = async (driver, xpath, timeout = 2000) => {
  const el = await driver.wait(until.elementLocated(By.xpath(xpath)), timeout);
  return await driver.wait(until.elementIsVisible(el), timeout);
};

function timeout(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

describe('webdriver', () => {
  let driver;

  beforeAll(async () => {
    const istunnelStarted = await tunnelInstance.start(tunnelArguments);
    driver = new webdriver.Builder()
      .usingServer(
        'https://' + username + ':' + accessKey + '@hub.lambdatest.com/wd/hub'
      )
      .withCapabilities(capabilities)
      .build();
    // eslint-disable-next-line no-undef
    await driver.get(`http://127.0.0.1:5000/signup`); // https://hourglass.surge.sh/signup
  }, 20000);

  afterAll(async () => {
    await driver.quit();
    await tunnelInstance.stop();
  }, 15000);

  test(
    'Signup test',
    async () => {
      const nameInput = await getElementById(driver, 'name');
      await nameInput.clear();
      await nameInput.sendKeys('Mayank');

      const emailInput = await getElementById(driver, 'email');
      await emailInput.clear();
      await emailInput.sendKeys('mybach8@gmail.com');

      const passwordInput = await getElementById(driver, 'password');
      await passwordInput.clear();
      await passwordInput.sendKeys('password');

      const cnfPassInput = await getElementById(driver, 'confirmPassword');
      await cnfPassInput.clear();
      await cnfPassInput.sendKeys('password');

      const prefWorkingHours = await getElementById(
        driver,
        'preferredWorkingHours'
      );
      await prefWorkingHours.clear();
      await prefWorkingHours.sendKeys('10.0');

      const btn = await getElementByClassName(
        driver,
        'LoaderButton  btn btn-lg btn-default btn-block'
      );
      await btn.click();

      await timeout(2000);
      const successText = await getElementByClassName(
        driver,
        'registerSuccess'
      );
      const successTextValue = await successText.getText();
      console.log(successTextValue);
      return expect(successTextValue).toContain('Congratulations');
    },
    20000
  );

  test(
    'Login test',
    async () => {
      await driver.get(`http://127.0.0.1:5000/login`); // https://hourglass.surge.sh/signup
      // const lnk = await getElementByName(driver, 'li1');
      // await lnk.click();

      // const lnk1 = await getElementByName(driver, 'li2');
      // await lnk1.click();

      const emailInput = await getElementById(driver, 'email');
      await emailInput.clear();
      await emailInput.sendKeys('mybach8@gmail.com');

      const passwordInput = await getElementById(driver, 'password');
      await passwordInput.clear();
      await passwordInput.sendKeys('password');

      const btn = await getElementByClassName(
        driver,
        'btn btn-lg btn-default btn-block'
      );
      await btn.click();

      await timeout(2000);
      const successText = await getElementByClassName(
        driver,
        'btn btn-primary'
      );
      const successTextValue = await successText.getText();
      console.log(successTextValue);
      expect(successTextValue).toContain('Manage Time tracks');
    },
    20000
  );
});

GitHubによって❤でホストされている生のselenium_testing_script.javaを表示する

 

コードウォークスルー

ここでは、LambdaTestトンネルを機能させるために使用しているトンネル引数がいくつかあります。トンネルを自動的にセットアップするためにLambdaTestによってリリースされたnpmパッケージがあります。

const lambdaTunnel = require('@lambdatest/node-tunnel');

ここで行ったことは、すべてのテストの前に新しいWebDriverをセットアップすることであり、このドライバーはLambdaTest SeleniumGridHubのパブリックURLを対象としています。LambdaTestアカウントから提供されたユーザー名とアクセスキーを使用しています。

const tunnelArguments = {
  user: process.env.LT_USERNAME || Your_LambdaTest_Username',
  key:
    process.env.LT_ACCESS_KEY ||
    'Your_LambdaTest_Access_Key',
};

次に、特定のブラウザ、ブラウザバージョン、オペレーティングシステム、ビデオ録画などでLambdaTestトンネルを使用するなどのすべての機能を提供します。


const capabilities = {
  build: 'jest-LambdaTest-Single',
  browserName: 'chrome',
  version: '72.0',
  platform: 'WIN10',
  video: true,
  network: true,
  console: true,
  visual: true,
  tunnel: true,
};

GitHubによって❤でホストされている生のlambda-tunnel.javaを表示する

環境変数、つまりLambdaTestユーザー名とアクセスキーを使用してURLを作成しています。



.usingServer(
        'https://' + username + ':' + accessKey + '@hub.lambdatest.com/wd/hub'
      )

オンラインSeleniumGrid用のリモートWebDriverがセットアップされると、サインアップページがロードされるのを待っています。

await driver.get(`http://127.0.0.1:5000/signup`); // https://hourglass.surge.sh/signup
  }, 20000);

以下のコードは、トンネルインスタンスが最初に開始され、その後にのみSeleniumテストスクリプトが実行されることを保証します。

const istunnelStarted = await tunnelInstance.start(tunnelArguments);

ベストプラクティス:すべてのテストケースが完了したら、トンネルインスタンスを必ず削除してください。これにより、LambdaTestSeleniumグリッドで利用可能な同時実行制限を節約できます。選択したLambdaTestの料金に応じて、またテストを実行した後でもトンネルを実行状態のままにしておくと、カウントごとに実行できるトンネルの数には制限があります。他のテストケースではトンネルを使用できないため、テストの完了後にトンネルを閉じることをお勧めします。

afterAll(async () => {
    await driver.quit();
    await tunnelInstance.stop();
  }, 15000);

監視ログ

LambdaTestは、Seleniumテストスクリプトの結果を分析するための直感的なインターフェイスを提供します。ネットワークログ、コマンドログ、生のSeleniumログ、メタデータなど、さまざまなログを取得できます。コマンドごとのスクリーンショットとともに、スクリプト実行全体のビデオを録画することもできます。LambdaTestのオンラインSeleniumGridでテストが正常にトリガーされたことに気付くかもしれません。

モニターログ

自動化ダッシュボードのさまざまなタイプのタブにアクセスして、スクリプトのデバッグ中に何が問題になったかを把握できます。ログの提供方法は次のとおりです。

セレンログ

自動化ログ

コマンドログ

Automationlogs

コンソールログ

lambdatest-automation-logs

最終的に、GitLab CIがバックエンドをHerokuにデプロイし、フロントエンドをSurgeにデプロイする予定です。したがって、URLを開くと、フロントエンドがSergeにデプロイされ、バックエンドがHerokuにデプロイされていることがわかります。これは、GitLab CI/CDパイプラインによって自動的に実行されます。

ここで、このGitLab CI / CDチュートリアルをラップする前に、CI/CDについて覚えておく必要のあるいくつかのベストプラクティスを簡単に書き留めておきましょう。

CI/CDのベストプラクティス

これで、SeleniumテストにGitLabCIパイプラインを活用することに関する知識がかなり共有されました。CI / CDのこれらのベストプラクティスをメモして、より優れたWebアプリケーションをより高速に構築することをお勧めします。

ビルドを高速化し、テストを高速化
 

CI / CDシステムの成功は、実行速度に依存します。CIサイクルがコミットごとに膨大な時間を要する場合、開発者はコードを迅速に統合するための代替のより高速なバイパスを見つけるでしょう。これには、楽観的な更新を優先してテストをスキップする経路が含まれることがよくあります。これは、生産に大混乱を引き起こす可能性があります。テストされていないコードを統合した場合の結果についても言及する必要はないと思います。

CI/CD環境を保護する必要があります

多くの場合無視されますが、CI/CD環境を保護することは非常に重要です。これは、コードベース、機密性の高いデータ、およびさまざまな環境へのアクセスが含まれているため、保護するのに最も機密性の高いインフラストラクチャの1つです。さらに、これは大規模で高周波の開発チームで最も使用されているシステムの1つです。CI / CDの停止は、最悪の場合、生産性の大幅な低下と経済的損失を引き起こす可能性があります。

CI/CDは本番環境に展開する唯一の方法である必要があります

CI / CDパイプラインは、最後に使用した人と同じくらい成功しています。チームに採用されない場合、CI/CDの開発におけるすべての努力は失敗します。CI / CDは、製品にデプロイするための厳密に唯一の方法である必要があります。実際、ロールバックは同じパイプラインを介してデプロイする必要があります。

CI/CDパイプラインで常にロールバックオプションを維持する

変更をロールバックする機能には、複雑な手順が含まれるべきではありません。変更をロールバックするのは可能な限り簡単にする必要があります。本番環境で変更をデバッグするよりも、午前3時に変更をロールバックすることをお勧めします。

早く失敗する

パイプラインの早い段階で最速のテストを実行する必要があります。テストに失敗した場合、ビルドを拒否するという考え方です。早期に拒否することで多くの時間を節約でき、所要時間が非常に短くなります。

CI/CDパイプラインにコミットする前にローカルでテストを実行する

CIはローカル開発システムで開始されます。すべての基本的なCIテストは、ローカルシステムで最初に実行する必要があります。これは、高速で時間を節約し、プラットフォーム上のCI / CDインフラストラクチャを節約して、より重要で後の段階のパイプラインを実現するためです。

テストは一時的な環境で実行する必要があります

CI / CDパイプラインに一貫した結果を提供するには、テストを毎回新しい状態で実行することが重要です。テストをべき等にするためには、一時的な環境が必要です。コンテナは、新鮮な環境を簡単に提供できるため、適切な環境です。

展開とリリースを切り離す

継続的デリバリーの概要で述べたように、リリースプロセスから展開を切り離すことで、リリースプロセスは純粋にマーケティングおよび戦略チームの決定になります。これには、柔軟性と速度の点で大きなメリットがあります。

まとめ

称賛!! これで、リリースがデプロイされる前に、すべての種類のチェックを実行するためのSeleniumテストが正常に実行されました。GitLab CIはリリースプロセスを準備し、3000以上の実際のブラウザーのオンラインSelenium Gridと統合できるようにすることで、これらの直前のチェックを行う手間をすべて取り除き、WebアプリケーションのシームレスなUIを保証します。

これが、企業やチームのために堅牢なCI/CDパイプラインを実際に構築する方法です。 

それでも質問がある場合は、下のコメントセクションに投稿してください。ハッピーテスト!🙂 

このストーリーは、もともとhttps://www.lambdatest.com/blog/automated-testing-pipeline-with-gitlab-ci-cd-and-selenium/で公開されました

#gitlab #testing #cicd #selenium 

GitLab CI/CDとSeleniumグリッドを使用して自動テストパイプラインを構築する

¿Cómo Ejecutar Pruebas E2E En Nuestra Canalización De CI/CD?

Esta es una pregunta a la que me enfrento a menudo. La verdad es que si alguien ha escuchado alguna vez sobre la pirámide de prueba, el caso es que podría descartar la idea de ejecutar pruebas de extremo a extremo.

Debe tener en cuenta que estas pruebas requieren mucho más tiempo de escritura en comparación con las pruebas unitarias, pero los beneficios también pueden valer la pena. Esto no será una discusión sobre si debe o no un tipo de prueba sobre otro, así que comencemos.

Por un momento imagina: que has decidido, que quieres dedicar tiempo a crear tu primera prueba E2E.

Primero, debe pensar en lo que está probando y crear una idea aproximada de cómo podría ser una prueba E2E sólida.

Ejemplo

En este ejemplo, tenemos una biblioteca que nuestro cliente incluye en la sección principal de su sitio web y luego nuestro script se ejecuta en tiempo de ejecución.

Esto significa que nuestro producto está diseñado para ejecutarse en el navegador.

Por lo tanto, configuraremos una prueba que haga exactamente eso.

Queremos emular exactamente cómo se usa nuestro script en la naturaleza.

Descripción general básica de CI/CD

Entonces la idea es:

  1. Activar un servidor web en Gitlab
  2. Cree algunos ejemplos "cercanos" de sitios web (HTML básico) para simular el uso en el mundo real. En estas páginas HTML ficticias, incluimos nuestro script de compilación
  3. Afirmar que el comportamiento es el esperado

Para que esto funcione, necesitamos que algunas piezas jueguen juntas.

Paso de compilación

Este paso dependerá en gran medida de su aplicación. Lo más probable es que ya tenga un proceso de compilación implementado.

Este comando compila todos nuestros módulos de JavaScript en un solo paquete

"build": "esbuild src/index.js --bundle --outfile=lib/out.js --minify"

Esto es lo primero que le indicamos a Gitlab que haga, ya que el archivo de salida es en el que queremos realizar las pruebas.

Servidor web

Para este paso utilizo un servidor Express estándar, para servir archivos estáticos. Una plantilla para el servidor web podría verse así.


import express from "express";
import path from "path";
import cookieParser from "cookie-parser";

const cors = require('cors');
let app = express();
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, "../public")));

app.use("/our_script", (req, res, next) =>
  res.sendFile(path.join(__dirname, "../lib/out.js"), { maxAge: 300000 })
);

app.use(express.static(path.join(__dirname, "public")));
export default app;

Este es un servidor express simple, que sirve el archivo producido por el paso de compilación (que es el mismo archivo que distribuimos a nuestros clientes) y cualquier otro archivo ubicado en la carpeta pública.

Broma / Titiritero

Dado que nuestro paquete de JavaScript de salida funciona con el DOM, estamos usando Puppeteer para orquestar un navegador Chromium sin cabeza para emular cómo un usuario real podría ver el sitio.

/**
 * @jest-environment jsdom
 */
import app from "../server/app";
import puppeteer from "puppeteer";
import { opts } from "./helpers/util";
const PORT = 3032;
jest.setTimeout(60000);
let browser = null;
let instance = null

describe("Test container", function () {
    beforeAll(async () => {
        instance = app.listen(PORT);
        browser = await puppeteer.launch(opts);
    });

    afterAll(async () => {
        await browser.close();
        instance.close(() => { })
    });
  
    describe("E2E test", function () {
        it("Output script is being loaded and setting some_global_variable to 4",
            async function () {
                //  Arrange
                const page = await browser.newPage();
                let pageToLoad = `http://localhost:${PORT}/yourpage.html`              
                //   Act
                await page.goto(pageToLoad, { waitUntil: "networkidle0" });
                await page.waitForTimeout(2000);
                await scroll(page);
                await page.waitForTimeout(5000);
                let pageContextVariable = await page.evaluate(() => globalThis.some_global_variable);
                //  Assert
                expect(pageContextVariable).toBe(4);
                await page.close();
            });
    });

})

async function scroll(page) {
    await page.evaluate(() => {
        return new Promise((resolve, reject) => {
            var totalHeight = parseInt(0);
            var timer = setInterval(() => {
                let distance = 500
                var scrollHeight = document.body.scrollHeight;
                window.scrollBy(parseInt(0), distance);
                totalHeight += distance;
                if (totalHeight >= scrollHeight) {
                    clearInterval(timer);
                    resolve();
                }
            }, 200);
        });
    });
}

Ejemplo de Jest & Puppeteer de una prueba E2E

Pensamientos finales

En mi proyecto, vi que el hecho de que esta tubería se introdujo desde el principio, y significó el mundo. Podría crear fácilmente páginas HTML que simulen las de nuestro cliente y hacer una prueba con ellas.

Vale la pena notar que Puppeteer es bastante lento en una canalización de CI/CD, por lo que debe tener cuidado al diseñar sus pruebas para evitar que su ciclo de retroalimentación sea demasiado lento.

También debe asegurarse de ejecutar cualquier prueba unitaria antes de la prueba E2E para fallar más rápido si algo crucial falla.

¡Mantente a prueba!

Esta historia se publicó originalmente en https://betterprogramming.pub/how-to-run-e2e-tests-on-gitlab-381f79e90f57

#testing #e2e #gitlab #cicd 

¿Cómo Ejecutar Pruebas E2E En Nuestra Canalización De CI/CD?
伊藤  直子

伊藤 直子

1654880400

CI / CDパイプラインでE2Eテストを実行する方法は?

これは私がよく直面する質問です。真実は、誰かがテストピラミッドについて聞いたことがある場合、エンド2エンドテストを実行するという考えをまったく破棄する可能性があるということです。

これらのテストは、単体テストと比較して作成にはるかに時間がかかることを覚えておく必要がありますが、利点もそれだけの価値があるかもしれません。これは、ある種類のテストを別の種類のテストで行う必要があるかどうかについての議論ではないので、始めましょう。

少し想像してみてください。あなたが最初のE2Eテストを作成するために時間を費やしたいと思ったことを想像してみてください。

まず、テストしているものについて考え、堅実なE2Eテストがどのように見えるかについて大まかなアイデアを作成する必要があります。

この例では、クライアントがWebサイトのヘッドセクションに含めるライブラリがあり、スクリプトは実行時に実行されます。

これは、当社の製品がブラウザで実行するように構築されていることを意味します。

したがって、まさにそれを行うテストを設定します。

スクリプトが実際にどのように使用されているかを正確にエミュレートしたいと思います。

基本的なCI/CDの概要

したがって、アイデアは次のとおりです。

  1. GitlabでWebサーバーを起動します
  2. Webサイト(基本的なHTML)の「近い」例をいくつか作成して、実際の使用をシミュレートします。これらのダミーのHTMLページには、ビルドスクリプトが含まれています
  3. 動作が期待どおりであることを表明します

これを機能させるには、一緒にプレイするためのいくつかのピースが必要です。

ビルドステップ

この手順は、アプリケーションによって大きく異なります。ほとんどの場合、ビルドプロセスはすでに実施されています。

このコマンドは、すべてのJavaScriptモジュールを1つのバンドルにビルドします

"build": "esbuild src/index.js --bundle --outfile=lib/out.js --minify"

出力ファイルはテストを実行するファイルであるため、これがGitlabに最初に指示することです。

Webサーバー

このステップでは、標準のExpressサーバーを使用して、静的ファイルを提供します。Webサーバーのテンプレートは次のようになります。


import express from "express";
import path from "path";
import cookieParser from "cookie-parser";

const cors = require('cors');
let app = express();
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, "../public")));

app.use("/our_script", (req, res, next) =>
  res.sendFile(path.join(__dirname, "../lib/out.js"), { maxAge: 300000 })
);

app.use(express.static(path.join(__dirname, "public")));
export default app;

これは単純なエクスプレスサーバーであり、ビルドステップで生成されたファイル(クライアントに配布するのと同じファイル)と、パブリックフォルダーに配置されたその他のファイルを提供します。

/パペッティアです

出力JavaScriptバンドルはDOMで機能するため、Puppeteerを使用してヘッドレスChromiumブラウザーを調整し、実際のユーザーがサイトをどのように使用するかをエミュレートしています。

/**
 * @jest-environment jsdom
 */
import app from "../server/app";
import puppeteer from "puppeteer";
import { opts } from "./helpers/util";
const PORT = 3032;
jest.setTimeout(60000);
let browser = null;
let instance = null

describe("Test container", function () {
    beforeAll(async () => {
        instance = app.listen(PORT);
        browser = await puppeteer.launch(opts);
    });

    afterAll(async () => {
        await browser.close();
        instance.close(() => { })
    });
  
    describe("E2E test", function () {
        it("Output script is being loaded and setting some_global_variable to 4",
            async function () {
                //  Arrange
                const page = await browser.newPage();
                let pageToLoad = `http://localhost:${PORT}/yourpage.html`              
                //   Act
                await page.goto(pageToLoad, { waitUntil: "networkidle0" });
                await page.waitForTimeout(2000);
                await scroll(page);
                await page.waitForTimeout(5000);
                let pageContextVariable = await page.evaluate(() => globalThis.some_global_variable);
                //  Assert
                expect(pageContextVariable).toBe(4);
                await page.close();
            });
    });

})

async function scroll(page) {
    await page.evaluate(() => {
        return new Promise((resolve, reject) => {
            var totalHeight = parseInt(0);
            var timer = setInterval(() => {
                let distance = 500
                var scrollHeight = document.body.scrollHeight;
                window.scrollBy(parseInt(0), distance);
                totalHeight += distance;
                if (totalHeight >= scrollHeight) {
                    clearInterval(timer);
                    resolve();
                }
            }, 200);
        });
    });
}

E2EテストのJest&Puppeteerの例

最終的な考え

私のプロジェクトでは、このパイプラインが早い段階で導入されたという事実、そしてそれが世界を意味していることを知りました。クライアントのページをシミュレートするHTMLページを簡単に作成し、それらをテストすることができました。

PuppeteerはCI/CDパイプラインではかなり遅いため、フィードバックループが遅くなりすぎないように、テストを設計する際には注意が必要です。

また、重大な問題が発生した場合に迅速に失敗するように、E2Eテストの前に単体テストを実行する必要があります。

テストを続けてください!

このストーリーは、もともとhttps://betterprogramming.pub/how-to-run-e2e-tests-on-gitlab-381f79e90f57で公開されました

#testing #e2e #gitlab #cicd 

CI / CDパイプラインでE2Eテストを実行する方法は?
Bits Lover's

Bits Lover's

1654302745

Protect Passwords in Cloud

Protect Passwords in Cloud

Let's go through a real project where we need to remove hardcoded passwords from several applications and make them more secure in the Cloud.

Some topics from this article: Protect Passwords in Cloud

  • How to protect passwords for your application
  • How to build a scalable solution in the Cloud.
  • AWS Secret Manager
  • Terraform Module for Secret Manager
  • Build a Pipeline that deploys all Secrets for us and protects them at the same time.
  • How to use OpenSSL to project our secrets file in our Git Repository.

Enjoy the reading!

 

#devops #security #terraform #aws #cicd #gitlab 

Protect Passwords in Cloud
藤本  結衣

藤本 結衣

1654148340

Android CI / CD —GitタグとGitLabCIによる自動タグ付け

私たちの目標は、プロジェクトで新しいバージョンをリリースするときに、そのtagためのを自動的に作成することです(これは別のプロジェクトにある可能性があります。プロジェクトを通じて例を示します)。そして、コードが特定のブランチにプッシュされたときにのみこれを実行したいとします。GitLabandroidandroid

それでは、少し学び、git tagsこの手順を段階的に実行する方法を見てみましょう。

Gitタグとは何ですか?

Gitタグは、Git履歴の特定の参照ポイントです。Gitタグは、リリースされたバージョンを指すためにさらに使用される履歴内の特定のポイントをキャプチャするために使用されます。タグはブランチのように変化しません。作成された後、コミットの履歴はありません。

簡単に言うと、Gitタグは、gitプロジェクトリポジトリ内の特定の名前に意味のある名前を付けるために使用されます。2人のユーザーが、後でアクセスできるようにプロジェクトコードにタグを付けることにしたとします。

タグ付けのためのシンプルなGitコマンド

gitタグに対してこれらの3つの簡単な操作を実行する方法を見てみましょう。これらは、作成、削除、リストです。

タグを作成する

$git tag -a "v1" -m "version 1"  // create a tag
$git push --tags                 // push the created tag

-a→注釈
-m→メッセージ

タグを削除

$git push origin -- delete < tagname>
$git push origin -- delete v1

リストタグ

$git tag   //lists the existing tags

出力例

v1
v2
v3

$git show v1→このコマンドを使用して、タグ付けされたコミットとともにタグデータを表示できます。

の基本的なコマンドを学びましたgit tagsそれでは、自動タグ付けを行う方法を見てみましょう。Gitlab-CI

GitLabランナーを作成する

GitLab Runnerとは何ですか?

GitLab Runnerは、GitLab CI / CDと連携して、パイプラインでジョブを実行するアプリケーションです。

それはどのように機能しますか?

コードをプッシュするとしましょう。作成するファイルのおかげ.gitlab-ci.ymlで、GitLabパイプラインがトリガーされ、パイプラインは保留状態になります。Pipelineは保留中のジョブを引き継ぎ、RunnerAPIを介してトランザクションを実行します。完了後、RunnerAPIを介して出力をGitLabサーバーに再度送信します。

GitLabRunnerをインストールします

ご使用のオペレーティングシステムに適したドキュメントに従って、このリンクからGitLabランナーをインストールできます。macOSを使用している場合は、私に従ってください。

$brew install gitlab-runner
$gitlab-runner --version

GitLabRunnerを登録する

GitLabランナーを登録するには、このリンクからオペレーティングシステムに適したドキュメントに従ってインストールできます。macOSを使用している場合は、私に従ってください。

$gitlab-runner register

  1. GitLabインスタンスのURLを入力するように求められます。これを入力してください。
    例:https ://gitlab.com
  2. GitLabから取得したトークンを入力します。トークンの例を次の図に示します。

  1. ランナーの説明を入力します。例えば:my-runner
  2. ランナーのタグを入力します。例:sshci
  3. ランナーエグゼキュータを選択します。例:shell

GitLabRunnerを起動します

Runnerを起動するための関連コマンドは、こちらのリンクから見つけることができます。Macを使用していて、私をフォローしている場合は、このコマンドでGitLabRunnerを実行できます。

$brew services start gitlab-runner

後でランナーを閉じたい場合は、このコマンドを使用できます。

$brew services stop gitlab-runner

YMLファイルを作成する

Androidでは.gitlab-ci.yml、プロジェクトディレクトリに名前の付いたファイルを作成します。

.ymlファイルとキーワードに関する情報をいくつか教えてください。

  • 変数:変数は環境変数の一種です。
  • ステージ:ステージを使用して、ジョブが実行されるステージを定義します。たとえば、テスト、ビルド、デプロイ
  • スクリプト:scriptランナーが実行するコマンドを指定するために使用します。
  • ルール:ルールを使用して、パイプラインにジョブを含めたり除外したりします。ジョブの選択された属性を評価および決定するための条件のリスト、およびジョブが作成されたかどうか。
  • !reference!referenceカスタムYAMLタグを使用して、他のジョブセクションからキーワード構成を選択し、現在のセクションで再利用します。あなたはそれをあなたが呼び出すことができる関数として考えることができます。

次に、以下のコードブロックを独自の.gitlab-ci.ymlファイルにコピーして、 GITLAB_PROJECT_URL:を変更します。

variables:
  GITLAB_PROJECT_URL: "https://gitlab.xxxxx.com/yyyzzz.git"

tag-release: #Our job name
  stage: deploy #Stage type
  script: #Our reference tags will be called sequentially and the scripts in them will run.
    - !reference [.check-git, script]
    - !reference [.clone-project, script]
    - !reference [.generate-tag, script]
  rules: #With the following if condition specified that this pipeline will run only when we push to master branch
    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "main"'

.check-git: #This section will check the git information. (This is not mandatory. Just a curiosity)
  script:
    - git --version
    - git config --global user.email
    - git config --global user.name

.clone-project: #This section will clone the project from gitlab and change the current directory.
  script:
    - git clone $GITLAB_PROJECT_URL
    - cd library-rnd

.generate-tag: #In this section we will obtain some information and generate and publish a tag
  script:
    # Read Version Name from Gradle File (app/build.gradle)
    - export GRADLE_VERSION_NAME=$(grep -E "versionName" app/build.gradle | cut -d "\"" -f2)
    # Get last tag's name from Gitlab
    - export CURRENT_TAG_NAME=$(git tag --list | sort -V | tail -n1)
    - echo "Tag name -> $CURRENT_TAG_NAME" # Write tag name on the screen
    - echo "Gradle version name -> v$GRADLE_VERSION_NAME" # Write version name on the screen
    - !reference [.delete-tag, script] # Call the delete-tag script
    - !reference [.create-tag, script] # Call the create-tag script

.delete-tag: #if the version name of the most recently published tag in gitlab and the current version of the app are the same,
  # delete the tag here in order to update the tag on the server.
  script:
    - if [ "$CURRENT_TAG_NAME" == "v$GRADLE_VERSION_NAME" ]; then git tag -d $CURRENT_TAG_NAME; fi
    - if [ "$CURRENT_TAG_NAME" == "v$GRADLE_VERSION_NAME" ]; then git push origin --delete $CURRENT_TAG_NAME; fi

.create-tag: # publish a new tag with the version name I read from gradle
  script:
    - git tag -a "v$GRADLE_VERSION_NAME" -m "New Version"
    - git push --tags $GITLAB_PROJECT_URL

パイプラインをプッシュしてトリガーする

プロジェクトのメインブランチでプッシュを実行すると、パイプラインが自動的にトリガーされます。下の写真でこれを見ることができます。

注:.gitlab.ci-ymlファイルで、パイプラインをメインブランチでトリガーするように指定しました。(11行目を確認してください)

GitLabのパイプライン

コードをプッシュするときにGitLabのパイプラインタブを確認すると、パイプラインを確認できます。

GitLabのパイプライン

GitLabでの私たちの仕事の成果

gitlab.ci.yml関連するジョブを実行することで、ファイル内のコマンドの実行とその出力を確認できます。

GitLabでの仕事

ご覧のとおり、すでに共有されているアプリのバージョンと同じ名前のタグ(v1.2)がGitLabから削除されています。次に、同じバージョン名で新しいタグが作成され、GitLabで公開されました。

GitLabのタグ

そして、ここで私たちが共有したタグを見ることができます。

公開されたタグ

結論

したがって、次のことを行いました。

  • コードが指定されたブランチにプッシュされると、パイプラインが自動的にトリガーされました。
  • app / gradle内のアプリのバージョンが変更され、メインブランチにプッシュされるたびに、タグが自動的に公開されます。
  • タグが以前に公開されていない場合は、gradleからアプリのバージョン名を取得して、新しいタグを公開できます。
  • 同じ名前のタグが以前に公開されている場合は、そのタグを削除して、同じ名前のタグを再度公開できます。

ソース

 このストーリーは、もともとhttps://betterprogramming.pub/android-ci-cd-git-tags-and-automatic-tagging-with-gitlab-ci-9ee1045822e1で公開されました

#android #cicd #git #gitlab 

Android CI / CD —GitタグとGitLabCIによる自動タグ付け

Android CI/CD: Etiquetas Git Y Etiquetado Automático Con GitLab CI

Nuestro objetivo es crear automáticamente un tagfor it GitLabcuando lanzamos una nueva versión en nuestro androidproyecto (Esto puede estar en otro proyecto, haré mi ejemplo a través del androidproyecto). Y digamos que solo queremos hacer esto cuando el código se envía a una rama específica.

Ahora, aprendamos un poco git tagsy luego veamos cómo podemos hacer esto paso a paso.

¿Qué son las etiquetas Git?

Las etiquetas de Git son puntos de referencia específicos en el historial de Git. Las etiquetas de Git se usan para capturar el punto específico en el historial que luego se usa para apuntar a una versión publicada. Una etiqueta no cambia como una rama. No tienen más historial de confirmaciones después de su creación.

En palabras simples, las etiquetas Git se utilizan para dar un nombre significativo a un particular en el repositorio del proyecto Git. Supongamos que dos usuarios deciden etiquetar su código de proyecto para acceder más tarde.

Comandos simples de Git para etiquetar

Veamos cómo podemos hacer estas tres operaciones simples para las etiquetas de git. Estos son: Crear, Eliminar, Listar

Crear una etiqueta

$git tag -a "v1" -m "version 1"  // create a tag
$git push --tags                 // push the created tag

-a→ anotar
-m→ mensaje

Eliminar etiqueta

$git push origin -- delete < tagname>
$git push origin -- delete v1

Etiqueta de listas

$git tag   //lists the existing tags

Salida de ejemplo

v1
v2
v3

$git show v1→ Puede ver los datos de la etiqueta junto con la confirmación que se etiquetó con este comando.

Aprendimos los comandos básicos para git tags. Ahora, echemos un vistazo a cómo hacer el etiquetado automático conGitlab-CI

Crear un ejecutor de GitLab

¿Qué es GitLab Runner?

GitLab Runner es una aplicación que funciona con GitLab CI/CD para ejecutar trabajos en una canalización.

¿Como funciona?

Digamos que empujamos nuestro código. Gracias al .gitlab-ci.ymlarchivo que crearemos, la canalización de GitLab se activará y la canalización pasará a estado pendiente. Pipeline se hará cargo del trabajo pendiente y realizará las transacciones a través de la API de Runner. Una vez hecho esto, transmite los resultados al servidor de GitLab nuevamente a través de la API de Runner.

Instalar GitLab Runner

Puede instalar GitLab runner desde este enlace siguiendo la documentación adecuada para su sistema operativo. Si estás usando macOS, sígueme.

$brew install gitlab-runner
$gitlab-runner --version

Registrar GitLab Runner

Para registrar GitLab runner, puede instalarlo siguiendo los documentos adecuados para su sistema operativo desde este enlace . Si estás usando macOS, sígueme.

$gitlab-runner register

  1. Se le pedirá que ingrese la URL de su instancia de GitLab. Por favor ingrese esto.
    Por ejemplo: https://gitlab.com
  2. Ingrese el token que obtuvo de GitLab. Un token de ejemplo se muestra en la siguiente imagen:

  1. Introduce tu descripción de corredor. Por ejemplo:my-runner
  2. Introduzca etiquetas para el corredor. Por ejemplo: ssh,ci
  3. Seleccione el ejecutor del corredor: Por ejemplo:shell

Inicie GitLab Runner

Puede encontrar el comando relevante para iniciar Runner desde el enlace aquí . Si está usando una Mac y me ha seguido, puede ejecutar GitLab Runner con este comando.

$brew services start gitlab-runner

Si desea cerrar el corredor más tarde, puede usar este comando.

$brew services stop gitlab-runner

Crear un archivo YML

En Android, cree un archivo con el nombre .gitlab-ci.ymlen el directorio del proyecto.

Permítanme darles información sobre el archivo .yml y las palabras clave:

  • variables: las variables son un tipo de variable de entorno.
  • etapa: use la etapa para definir en qué etapa se ejecuta un trabajo. Por ejemplo, prueba, compilación, implementación
  • script: se usa scriptpara especificar comandos para que los ejecute el corredor.
  • reglas: use reglas para incluir o excluir trabajos en canalizaciones. Lista de condiciones para evaluar y determinar los atributos seleccionados de un trabajo, y si se crea o no.
  • !reference: use la !referenceetiqueta YAML personalizada para seleccionar la configuración de palabras clave de otras secciones de trabajo y reutilícela en la sección actual. Puede pensar en ello como una función a la que solo puede llamar.

Ahora, copie el bloque de código a continuación en su propio .gitlab-ci.ymlarchivo y cambie su GITLAB_PROJECT_URL:

variables:
  GITLAB_PROJECT_URL: "https://gitlab.xxxxx.com/yyyzzz.git"

tag-release: #Our job name
  stage: deploy #Stage type
  script: #Our reference tags will be called sequentially and the scripts in them will run.
    - !reference [.check-git, script]
    - !reference [.clone-project, script]
    - !reference [.generate-tag, script]
  rules: #With the following if condition specified that this pipeline will run only when we push to master branch
    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "main"'

.check-git: #This section will check the git information. (This is not mandatory. Just a curiosity)
  script:
    - git --version
    - git config --global user.email
    - git config --global user.name

.clone-project: #This section will clone the project from gitlab and change the current directory.
  script:
    - git clone $GITLAB_PROJECT_URL
    - cd library-rnd

.generate-tag: #In this section we will obtain some information and generate and publish a tag
  script:
    # Read Version Name from Gradle File (app/build.gradle)
    - export GRADLE_VERSION_NAME=$(grep -E "versionName" app/build.gradle | cut -d "\"" -f2)
    # Get last tag's name from Gitlab
    - export CURRENT_TAG_NAME=$(git tag --list | sort -V | tail -n1)
    - echo "Tag name -> $CURRENT_TAG_NAME" # Write tag name on the screen
    - echo "Gradle version name -> v$GRADLE_VERSION_NAME" # Write version name on the screen
    - !reference [.delete-tag, script] # Call the delete-tag script
    - !reference [.create-tag, script] # Call the create-tag script

.delete-tag: #if the version name of the most recently published tag in gitlab and the current version of the app are the same,
  # delete the tag here in order to update the tag on the server.
  script:
    - if [ "$CURRENT_TAG_NAME" == "v$GRADLE_VERSION_NAME" ]; then git tag -d $CURRENT_TAG_NAME; fi
    - if [ "$CURRENT_TAG_NAME" == "v$GRADLE_VERSION_NAME" ]; then git push origin --delete $CURRENT_TAG_NAME; fi

.create-tag: # publish a new tag with the version name I read from gradle
  script:
    - git tag -a "v$GRADLE_VERSION_NAME" -m "New Version"
    - git push --tags $GITLAB_PROJECT_URL

Empuje y active la canalización

La canalización se activará automáticamente cuando hagamos un empuje mientras estamos en la rama principal del proyecto. Esto lo podemos ver en la foto de abajo.

Nota: hemos especificado en nuestro .gitlab.ci-ymlarchivo que la canalización debe activarse en la rama principal. (Marque Línea 11)

Canalización en GitLab

Podemos ver la tubería si revisamos las pestañas de la tubería en GitLab cuando insertamos los códigos.

Canalización en GitLab

Salida de nuestro trabajo en GitLab

Podemos ver la ejecución de los comandos en nuestro gitlab.ci.ymlarchivo y cuál es su salida siguiendo el trabajo correspondiente.

Trabajo en GitLab

Como puede ver, la etiqueta (v1.2) con el mismo nombre que la versión de la aplicación ya compartida se eliminó de GitLab. Luego se creó una nueva etiqueta con el mismo nombre de versión y se publicó en GitLab.

Etiquetas en GitLab

Y aquí podemos ver la etiqueta que compartimos.

Etiquetas publicadas

Conclusión

Entonces, hemos hecho lo siguiente:

  • Activamos la canalización automáticamente cuando se envía un código a una rama específica.
  • Las etiquetas se publican automáticamente cada vez que se cambia la versión de la aplicación en app/gradle y se envía a la rama principal.
  • Si una etiqueta no se ha publicado antes, podemos obtener el nombre de la versión de la aplicación de gradle y publicar una nueva etiqueta.
  • Si anteriormente se ha publicado una etiqueta con el mismo nombre, podemos eliminarla y volver a publicar la etiqueta con el mismo nombre.

Fuentes

 Esta historia se publicó originalmente en https://betterprogramming.pub/android-ci-cd-git-tags-and-automatic-tagging-with-gitlab-ci-9ee1045822e1

#android #cicd #git #gitlab 

Android CI/CD: Etiquetas Git Y Etiquetado Automático Con GitLab CI

LWCJestでカバレッジとテストレポーターを使用する

Jestは、Angular、React、SalesforceLightningWebコンポーネントなどのさまざまなタイプのプロジェクトで機能するJavaScriptテストフレームワークです。Salesforceエコシステムでは、LWC単体テストとそのカバレッジはApexコードカバレッジとは対照的にデプロイメントには関係ありませんが、私の意見では、UIで高いコード品質を確保するには、カバレッジの高い優れたテストも重要です。

Lightning Webコンポーネント全般のJestテストについては、すでに多くのよく書かれたガイドがあります。したがって、このガイドでは、テスト結果とカバレッジレポートの部分に焦点を当てたいと思います。

さて、すぐに飛び込みましょう。

デフォルトのLWCジェスト構成

新しいSFDXプロジェクトを作成する場合、LWC単体テストのデフォルトのJest構成は、プロジェクトのルートディレクトリにあり、次のようになります。

const { jestConfig } = require('@salesforce/sfdx-lwc-jest/config');

module.exports = {
  ...jestConfig,
  modulePathIgnorePatterns: ['<rootDir>/.localdevserver']
};

この設定を変更しない場合は、次のコマンドを使用して、現在存在するLWCテストクラスに対応するコードカバレッジを計算できます。

sfdx-lwc-jest --coverage

sfdx -lwc-jestがグローバルにインストールされていないが、現在のプロジェクトの依存関係としてのみインストールされている場合は、次のpackage.jsonように対応するスクリプトをファイルに追加することもできます。

package.jsonでのLWCテスト実行用のスクリプト

package.jsonでのLWCテスト実行用のスクリプト

これらのスクリプトは、たとえば次のように実行できます。

npm run test:unit:coverage

コマンドを実行し、すべてのテストの実行を終了すると、計算されたコードカバレッジがターミナルに出力されます。

LWCコードカバレッジの端末出力

LWCコードカバレッジの端末出力

さらに、LCOVカバレッジレポートが/coverageプロジェクトのディレクトリに自動的に生成されます。ただし、一部のプロジェクトでは、自動パイプライン実行でのレポートまたは公開に使用できるように、CoberturaやJUnitなどの他の形式で生成されたコードカバレッジとテスト結果が必要になる場合があります。

したがって、次のセクションでは、SFDXプロジェクトのLWCJestのデフォルト構成を拡張する方法を見ていきます。

高度なLWCジェスト構成

前のセクションでは、提供されたLWCJestのデフォルト構成で何が可能かを見てきました。ただし、公式ドキュメントを参照すると、さまざまなオプションを使用して構成をオーバーライドまたは拡張することができます(Jestの構成)。これを行う場合は、前述のレポーターであるCobertura、JUnit、またはその他を使用することもできます。

たとえば、Coberturaまたはその他のカバレッジレポーターとフォーマットを利用するには、既存のjest.config.js構成ファイルに次の行を追加するだけです。

coverageReporters: ['clover', 'json', 'text', 'lcov', 'cobertura'],

構成がこのように拡張された場合、これにより、/coverageディレクトリ内の指定されたレポートタイプの追加出力が自動的に行われます。

JUnitサポートも有効にするには、 jest-junitと呼ばれる追加のnpmパッケージが必要です。これは、次のようにプロジェクトの開発依存関係としてインストールできます。

npm i jest-junit --save-dev

このレポーターをJestで自動的に使用するには、このレポーターもjest.config.js構成ファイルに追加する必要があります。すべての調整を含む最終的なJest構成は、次のようになります。

const { jestConfig } = require('@salesforce/sfdx-lwc-jest/config');

module.exports = {
  ...jestConfig,
  coverageReporters: ['clover', 'json', 'text', 'lcov', 'cobertura'],
  modulePathIgnorePatterns: ['/.localdevserver'],
  reporters: [
    'default',
    [
      'jest-junit',
      {
        outputDirectory: 'tests',
        outputName: 'test-results-lwc.xml'
      }
    ]
  ]
};

今後、次の2つのディレクトリには、テストの実行ごとにテストレポートが自動的に入力されます。ディレクトリにはすべての/coverageコードカバレッジ関連情報/testsが含まれ、ディレクトリには最新のテスト実行のすべての一般的な結果が含まれます。

最新のLWCテスト実行の結果を含む生成されたディレクトリ

最新のLWCテスト実行の結果を含む生成されたディレクトリ

CI/CD自動化でのテストレポートの使用

以前、LightningWebコンポーネントのさまざまな形式でテスト結果とコードカバレッジレポートを生成する方法を見てきました。現在、それらにはいくつかの用途があります。たとえば、上記の構成をCI / CDパイプラインで使用して、コードカバレッジ情報をSonarCloudなどのコード分析ツールに公開したり、パイプラインの実行でテスト結果を直接表示したりすることもできます。例としてAzureパイプラインを使用して、後者がどのように機能するかを見てみましょう。

Azureパイプラインでの使用例

Azure Pipelinesは、MicrosoftのAzure DevOpsToolSuite内のCI/CD自動化ソリューションであり、コードのビルド、テスト、およびデプロイに使用できます。もちろん、これはAzure Pipelinesのガイドとなることを意図したものではありませんが、例として、LWCテストの実行と結果のレポートに対応するタスクを追加する方法を見てみましょう。

プルリクエストで自動的に実行されるCIパイプラインがあり、パイプラインごとに対応するテスト結果と計算されたコードカバレッジを実行することを確認したいとします。

まず、以前ローカルで行ったように、テストを実行してレポートを生成する必要があります。パイプラインの設計はYAML形式で定義されています。YAMLパイプライン定義ファイルに、LWCテストを実行するための次のタスクを追加できます。これも、以前に定義したスクリプトを使用しますpackage.json

- bash: npm run test:unit:coverage
  displayName: 'Execute LWC Unit Tests'
  workingDirectory: $(Build.SourcesDirectory)
  continueOnError: true

このタスクはすべてのテストを実行し、一部のテストが失敗しても中止されません。もちろん、最終的に失敗する可能性のあるすべてのテストに関心があるためです。

AzureパイプラインのJUnitテストレポート

現在のテスト実行の全体的な結果を公開するには、パイプライン定義ファイルに別のタスクを追加する必要があります。このタスクは、指定された結果ファイルを自動的に検索し、現在のパイプライン実行用に公開します。


- task: PublishTestResults@2
  displayName: 'Publish Test Results'
  inputs:
    testResultsFormat: 'JUnit'
    testResultsFiles: '**/test-results-*.xml'
    failTaskOnFailedTests: true

次回パイプラインを実行すると、新しい[テスト]タブが表示されます。このタブでは、生成されたテストレポートに基づいて、結果が次のように適切にフォーマットされて表示されます。

AzureパイプラインのサンプルJUnitテストレポート

AzureパイプラインのサンプルJUnitテストレポート

AzureパイプラインのCoberturaコードカバレッジレポート

テストの一般的な結果に加えて、もちろん、それぞれのコードカバレッジにも関心があります。Azure Pipelinesにもこれに対応するタスクがあり、パイプライン定義に追加できます。このタスクは、フォーマットの指定と、結果ファイルへの対応するパスも受け取ります。


- task: PublishCodeCoverageResults@1
  displayName: 'Publish Coverage Results'
  inputs:
    codeCoverageTool: Cobertura
    summaryFileLocation: $(Build.SourcesDirectory)/coverage/cobertura-coverage.xml

次のパイプライン実行後、このタスクは「カバレッジ」というラベルの付いた新しいタブも作成します。これは、現在の実行のLWCテストのそれぞれのコードカバレッジも適切にフォーマットします。

AzureパイプラインのサンプルCoberturaコードカバレッジレポート

AzureパイプラインのサンプルCoberturaコードカバレッジレポート

結論

このガイドでは、LWC Jestを使用してさまざまなタイプのテスト結果とコードカバレッジレポートを生成する方法と、それらをCI/CDプロセスで使用する方法について説明しました。もちろん、これは、ここに例として示されているAzureパイプラインだけでなく、Bitbucket PipelinesGitHub ActionsGitLab CI/CDなどの他のパイプラインソリューションにも当てはまります。

GitHubの私のリポジトリの1つでは、このガイドに示されているテスト構成も参照として利用できます。また、個人のSonarCloudプロジェクトでのテスト結果の自動公開を含むGitHubアクションでの使用も可能です。

 元の記事のソース:https ://betterprogramming.pub/how-to-use-coverage-and-test-reporters-with-lwc-jest-c40caedbf439 

#azure #jest #cicd 

LWCJestでカバレッジとテストレポーターを使用する
Saul  Alaniz

Saul Alaniz

1654061220

Cómo Usar Los Reporteros De Cobertura Y Prueba Con LWC Jest

Jest es un marco de prueba de JavaScript que funciona con diferentes tipos de proyectos, incluidos Angular, React y Salesforce Lightning Web Components. Aunque en el ecosistema de Salesforce, las pruebas unitarias de LWC y su cobertura no son relevantes para las implementaciones en contraste con la cobertura del código Apex , en mi opinión, las buenas pruebas con alta cobertura también son importantes aquí para garantizar una alta calidad del código en la interfaz de usuario.

Ya hay una serie de guías bien escritas sobre las pruebas de Jest para Lightning Web Components en general. Por lo tanto, me gustaría centrarme en el resultado de la prueba y la parte de informes de cobertura de esta guía.

Muy bien, entremos directamente en ello.

Configuración predeterminada de LWC Jest

Al crear un nuevo proyecto SFDX, la configuración predeterminada de Jest para las pruebas unitarias de LWC se encuentra en el directorio raíz del proyecto y se ve así:

const { jestConfig } = require('@salesforce/sfdx-lwc-jest/config');

module.exports = {
  ...jestConfig,
  modulePathIgnorePatterns: ['<rootDir>/.localdevserver']
};

Si deja esta configuración sin cambios, puede usar el siguiente comando para calcular la cobertura de código correspondiente para las clases de prueba LWC existentes actualmente:

sfdx-lwc-jest --coverage

Si sfdx-lwc-jest no está instalado globalmente, sino solo como una dependencia de su proyecto actual, también puede agregar los scripts correspondientes en el package.jsonarchivo de esta manera:

Scripts para la ejecución de pruebas de LWC en package.json

Scripts para la ejecución de pruebas de LWC en package.json

Estos scripts se pueden ejecutar, por ejemplo, de la siguiente manera:

npm run test:unit:coverage

Después de ejecutar el comando y finalizar la ejecución de todas las pruebas, la cobertura de código calculada se muestra en la terminal:

Salida de terminal para cobertura de código LWC

Salida de terminal para cobertura de código LWC

Adicionalmente, se genera automáticamente un reporte de cobertura LCOV en el /coveragedirectorio del proyecto. Sin embargo, en algunos proyectos, es posible que necesite cobertura de código y resultados de prueba generados en otros formatos, como Cobertura o JUnit, para poder usarlos para generar informes o publicar en una ejecución de canalización automatizada.

Entonces, en la siguiente sección, veremos cómo extender la configuración predeterminada de LWC Jest para un proyecto SFDX.

Configuración avanzada de LWC Jest

En la sección anterior, vimos lo que es posible con la configuración predeterminada proporcionada por LWC Jest. Sin embargo, en referencia a la documentación oficial, es posible anular o ampliar la configuración con varias opciones ( Configuración de Jest ). Si haces esto, también puedes usar los reporteros mencionados anteriormente Cobertura, JUnit, o incluso otros.

Por ejemplo, para hacer uso de Cobertura u otros reporteros y formatos de cobertura, solo necesita agregar la siguiente línea al jest.config.jsarchivo de configuración existente:

coverageReporters: ['clover', 'json', 'text', 'lcov', 'cobertura'],

Si la configuración se amplía de esta manera, esto conduce automáticamente a la salida adicional de los tipos de informes especificados en el /coveragedirectorio.

Para tener habilitado el soporte de JUnit, también necesita un paquete npm adicional llamado jest-junit que se puede instalar como una dependencia de desarrollo de su proyecto de la siguiente manera:

npm i jest-junit --save-dev

Para luego usar automáticamente este reportero con Jest, también debe agregarse al jest.config.jsarchivo de configuración. La configuración final de Jest con todos los ajustes se vería así:

const { jestConfig } = require('@salesforce/sfdx-lwc-jest/config');

module.exports = {
  ...jestConfig,
  coverageReporters: ['clover', 'json', 'text', 'lcov', 'cobertura'],
  modulePathIgnorePatterns: ['/.localdevserver'],
  reporters: [
    'default',
    [
      'jest-junit',
      {
        outputDirectory: 'tests',
        outputName: 'test-results-lwc.xml'
      }
    ]
  ]
};

A partir de ahora, los siguientes dos directorios se llenarán automáticamente con nuestros informes de prueba para cada ejecución de prueba. El /coveragedirectorio contiene toda la información relacionada con la cobertura del código y el /testsdirectorio contiene todos los resultados generales de la última ejecución de la prueba.

Directorios generados con los resultados de la última ejecución de prueba LWC

Directorios generados con los resultados de la última ejecución de prueba LWC

Uso de informes de prueba en automatizaciones de CI/CD

Anteriormente, vimos cómo generar resultados de pruebas e informes de cobertura de código en varios formatos para componentes web Lightning. Ahora hay varios usos para ellos. Por ejemplo, la configuración que se muestra arriba se puede usar en canalizaciones de CI/CD para publicar información de cobertura de código en herramientas de análisis de código como SonarCloud o incluso para hacer que los resultados de las pruebas sean visibles directamente en una ejecución de canalización. Echemos un vistazo a cómo funciona este último, usando Azure Pipelines como ejemplo.

Ejemplo de uso con Azure Pipelines

Azure Pipelines es la solución de automatización de CI/CD dentro de Azure DevOps Tool Suite de Microsoft y se puede usar para compilar, probar e implementar su código. Por supuesto, esto no pretende ser una guía para Azure Pipelines, sin embargo, echemos un vistazo a cómo podríamos agregar las tareas correspondientes para la ejecución de la prueba LWC y el informe de resultados como ejemplo.

Supongamos que tenemos una canalización de CI que se ejecuta automáticamente en una solicitud de extracción y nos gustaría ver que cada canalización ejecute los resultados de prueba correspondientes, así como la cobertura del código calculado.

Primero, necesitamos ejecutar nuestras pruebas para generar nuestros informes, como lo hicimos antes localmente. El diseño de las tuberías se define en formato YAML. A nuestro archivo de definición de tubería YAML, podemos agregar la siguiente tarea para la ejecución de las pruebas LWC, que nuevamente usa el script previamente definido desde nuestro archivo package.json.

- bash: npm run test:unit:coverage
  displayName: 'Execute LWC Unit Tests'
  workingDirectory: $(Build.SourcesDirectory)
  continueOnError: true

Esta tarea ejecuta todas las pruebas y no aborta incluso si algunas pruebas fallan, ya que, por supuesto, estamos interesados ​​en todas las pruebas posiblemente fallidas al final.

Informe de prueba JUnit en Azure Pipelines

Para publicar los resultados generales de nuestra ejecución de prueba actual, solo necesitamos agregar otra tarea a nuestro archivo de definición de canalización. Esta tarea busca automáticamente el archivo de resultados especificado y lo publica para la ejecución de canalización actual.


- task: PublishTestResults@2
  displayName: 'Publish Test Results'
  inputs:
    testResultsFormat: 'JUnit'
    testResultsFiles: '**/test-results-*.xml'
    failTaskOnFailedTests: true

La próxima vez que ejecutemos la canalización, veremos una nueva pestaña "Pruebas" donde, según nuestro informe de prueba generado, los resultados se mostrarán con el siguiente formato:

Ejemplo de informe de prueba JUnit en Azure Pipelines

Ejemplo de informe de prueba JUnit en Azure Pipelines

Informe de cobertura de código de Cobertura en Azure Pipelines

Además de los resultados generales de nuestras pruebas, por supuesto, también estamos interesados ​​en su respectiva cobertura de código. También hay una tarea correspondiente en Azure Pipelines para esto, que podemos agregar a nuestra definición de canalización. Esta tarea también recibe la especificación del formato así como la ruta correspondiente al archivo de resultados:


- task: PublishCodeCoverageResults@1
  displayName: 'Publish Coverage Results'
  inputs:
    codeCoverageTool: Cobertura
    summaryFileLocation: $(Build.SourcesDirectory)/coverage/cobertura-coverage.xml

Después de la siguiente ejecución de la canalización, esta tarea también crea una nueva pestaña denominada "Cobertura", que también formatea muy bien la cobertura de código respectiva de nuestras pruebas LWC para la ejecución actual.

Ejemplo de informe de cobertura de código de Cobertura en Azure Pipelines

Ejemplo de informe de cobertura de código de Cobertura en Azure Pipelines

Conclusión

En esta guía, hemos analizado cómo se puede usar LWC Jest para generar diferentes tipos de resultados de pruebas e informes de cobertura de código y cómo se pueden usar en procesos de CI/CD. Por supuesto, esto no solo se aplica a Azure Pipelines como se muestra aquí como ejemplo, sino también a otras soluciones de canalización como Bitbucket Pipelines , GitHub Actions o GitLab CI/CD .

En uno de mis repositorios en GitHub, la configuración de prueba que se muestra en esta guía también está disponible nuevamente como referencia, así como su uso en GitHub Actions, incluida la publicación automática de resultados de prueba en un proyecto personal de SonarCloud.

 Fuente del artículo original en: https://betterprogramming.pub/how-to-use-coverage-and-test-reporters-with-lwc-jest-c40caedbf439

#azure #jest #cicd 

Cómo Usar Los Reporteros De Cobertura Y Prueba Con LWC Jest
Logan  Anderson

Logan Anderson

1654040100

How to Deploy Your React App using A CI/CD Pipeline with Netlify

In this tutorial, we will Learn how to deploy your React app using a CI/CD pipeline with Netlify.

In this tutorial, you will learn how to take control over the deployment process by using CircleCI as your continuous deployment server. With the system you set up using this tutorial, you can perform any custom step you need to complete your build process and deploy your React application to Netlify.


#react #netlify #cicd 

How to Deploy Your React App using A CI/CD Pipeline with Netlify

A Beginners Tutorial in using Azure DevOps (in 2022)

What is Azure DevOps? If you're a beginner, or want to know more about the tool, follow our short tutorial on what it offers.

We'll show the services, which include Azure Boards and how it compares to Jira.

In-addition, we'll show you Azure Pipelines and how it can be used to set up a CI/CD pipeline for automated deployment.

As well as that, we'll demonstrate the other services which include Azure Repos, Azure Test Plans and Azure Artifacts.

Finally, we will look into pricing and show you the cost. This is particularly relevant if you're looking to install Azure DevOps Server onto your local environment.

► Chapters
0:00 Coming up...
0:13 What is Azure DevOps?
0:42 Sign up for Azure DevOps
0:55 Create an organization
1:25 Organization settings
2:17 Create a project
2:52 Project services
4:00 Azure Pipelines
6:04 Hide services
6:32 Pricing
7:37 More resources

► More information: 
https://www.roundthecode.com/dotnet/azure/what-is-azure-devops-learn-services-guide?utm_source=youtube&utm_medium=referral&utm_campaign=What+is+Azure+Devops%3F+A+beginners+tutorial+in+using+the+tool

#azure  #azuredevops  #cicd 

 A Beginners Tutorial in using Azure DevOps (in 2022)

Cómo Configurar La Canalización De CI/CD Para Cloudflare Worker

Hoy, la mayoría de mis proyectos en GitHub se mantienen actualizados con Renovate . Con la fusión automática habilitada, quiero tener la confianza suficiente de que la actualización de dependencias automatizadas no causará ninguna regresión.

Probar Cloudflare Worker está un poco fuera de control. No me malinterpreten, me encanta Cloudflare Worker. Sin embargo, la solución existente parece un poco poco intuitiva. Además de eso, dollarhaveclub/cloudworker ya no se mantiene activamente, lo cual es un fastidio.

TL;DR: Cómo configurar una canalización de CI/CD para un proyecto de Cloudflare Worker usando GitHub Action y Grafana k6 .

Visión general

Anteriormente, construí un clon de acortador de URL con Cloudflare Worker. Usando este proyecto existente ( enlace de GitHub ), buscaremos configurar una canalización de CI/CD para él junto con pruebas de integración simples.

Nuestra canalización de GitHub Action CI/CD es bastante sencilla. Las etapas (trabajos) son las siguientes:

Ejemplo de flujo de trabajo de CI en GitHub

Ejemplo de flujo de trabajo de CI en GitHub ( enlace )

  1. Comprobación de pelusa o prueba unitaria
  2. Implementar en el entorno de ensayo
  3. Ejecute las pruebas de integración en nuestro entorno Staging
  4. Ejecute la liberación semántica e implemente en el entorno de producción

Configuración de Wrangler

Para empezar, tendremos que modificar nuestro archivo existentewrangler.toml . Recuerde, necesitamos implementar un entorno de prueba para ejecutar nuestra prueba de integración en él:

[env.staging]name = "atomic-url-staging"workers_dev = truekv_namespaces = [  { binding = "URL_DB", id = "ca7936b380a840908c035a88d1e76584" },]
  • name— Asegúrese de que el namedebe ser único y alfanumérico ( -están permitidos) para cada entorno. Vamos a nombrar nuestro entorno de Staging atomic-url-staging.
  • worker_dev— Nuestras pruebas de integración se ejecutan en el <NAME>.<SUBDOMAIN>.workers.devpunto final. Por lo tanto, debemos implementar nuestro Cloudflare Worker configurando workers_dev = true( referencia ).
  • kv_namespaces— Atomic URL utiliza KV como su base de datos para almacenar URL abreviadas. Aquí, elegí usar un espacio de nombres de vista previa KV como base de datos de prueba. ¿Por qué? Simplemente porque es el mismo espacio de nombres KV de desarrollo que uso durante el desarrollo local (cuando ejecuto wrangler dev). Por supuesto, podría usar un espacio de nombres KV normal. Solo asegúrese de no estar usando Production KV id. Lea cómo crear un espacio de nombres KV .

A continuación, también necesitaremos crear un entorno de producción para implementar con nuestro espacio de nombres KV de producción:

[env.production]name = "atomic-url"route = "s.jerrynsh.com/*"workers_dev = falsekv_namespaces = [  { binding = "URL_DB", id = "7da8f192d2c1443a8b2ca76b22a8069f" },]

La sección del entorno de producción sería similar a la anterior, excepto que estaremos configurando worker_dev = falsey routepara la producción.

Despliegue

Para implementar manualmente desde su máquina local a su entorno respectivo, ejecute:

  • wrangler publish -e staging
  • wrangler publish -e production

Sin embargo, veremos cómo hacer esto automáticamente a través de nuestra canalización de CI/CD usando GitHub Actions.

Antes de continuar, puede encontrar la wrangler.tomlconfiguración completa aquí .

Oh, aquí hay una hoja de trucos para configurar wrangler.toml. ¡Te recomiendo que hagas uso de esto!

grafana k6

Para las pruebas de integración, usaremos una herramienta conocida como k6. Generalmente, k6 se usa como una herramienta para pruebas de rendimiento y carga. Ahora, tengan paciencia conmigo, no vamos a integrar ninguna prueba de carga en nuestra canalización de CI/CD; hoy no.

Aquí, ejecutaremos pruebas de humo para este proyecto cada vez que se envíen nuevas confirmaciones a nuestra mainrama. Una prueba de humo es esencialmente un tipo de prueba de integración que realiza una verificación de cordura en un sistema.

En este caso, realizar una prueba de humo es suficiente para determinar que nuestro sistema se implementa sin ninguna regresión y puede ejecutarse con una carga mínima.

que probar

Básicamente, aquí hay un par de cosas que queremos verificar como parte de nuestra prueba de humo para nuestra aplicación de acortador de URL en grupos :

  • La página principal debería cargarse como se esperaba con un estado de respuesta 200
group('visit main page', function () {
    const res = http.get(BASE_URL)check(res, {
        'is status 200': (r) => r.status === 200,
        'verify homepage text': (r) =>
            r.body.includes(
                'A URL shortener POC built using Cloudflare Worker'
            ),
    })
})
  • Nuestro principal punto final de la API POST /api/urldebe crear una URL corta con la URL original
group('visit rest endpoint', function () {
    const res = http.post(
        `${BASE_URL}/api/url`,
        JSON.stringify({ originalUrl: DUMMY_ORIGINAL_URL }),
        { headers: { 'Content-Type': 'application/json' } }
    )check(res, {
        'is status 200': (r) => r.status === 200,
        'verify createShortUrl': (r) => {
            const { urlKey, shortUrl, originalUrl } = JSON.parse(r.body)
            shortenLink = shortUrl
            return urlKey.length === 8 && originalUrl === DUMMY_ORIGINAL_URL
        },
    })
})
  • Por último, queremos asegurarnos de que cuando visitemos la URL corta generada, nos redirija a la URL original.
group('visit shortUrl', function () {
    const res = http.get(shortenLink)check(res, {
        'is status 200': (r) => r.status === 200,
        'verify original url': (r) => r.url === DUMMY_ORIGINAL_URL,
    })
})

Para probar localmente, simplemente ejecute k6 path/to/test.js. ¡Eso es todo! Puede encontrar el script de prueba completo aquí .

En caso de que esté pensando en ejecutar pruebas de carga, lea cómo determinar usuarios simultáneos en su prueba de carga.

Acciones de GitHub

Pasaré por alto esta sección ya que es bastante sencilla. Puede consultar el archivo de flujo de trabajo final de GitHub Actions aquí .

Juntemos todo lo que tenemos. A continuación se muestran las acciones de GitHub que necesitaremos usar:

Una cosa a tener en cuenta sobre el archivo de flujo de trabajo: para hacer que un trabajo dependa (necesite) de otro trabajo, utilizaremos la needsintaxis .

Secretos de acciones

Este proyecto requiere 2 acciones secretas:

  1. CF_API_TOKEN— Para ser utilizado por Wrangler GitHub Action para publicar automáticamente nuestro Cloudflare Worker en su entorno respectivo. Puede crear su token API utilizando la Edit Cloudflare Workersplantilla.
  2. NPM_TOKEN— Este proyecto también utiliza la liberación semántica para publicar automáticamente en NPM . Para habilitar esto, deberá crear un token de creación a NPM_TOKENtravés de npm .

Para agregarlo a los secretos de su repositorio de GitHub, consulte esta guía .

Si ha echado un vistazo al archivo de flujo de trabajo final, es posible que haya notado la sintaxis ${{ secrets.GITHUB_TOKEN }}y se haya preguntado por qué no mencioné nada sobre agregar GITHUB_TOKENsecretos de acciones a nuestro proyecto. Resulta que se crea y se agrega automáticamente a todos sus flujos de trabajo .

Comentario final

Es comprensible que las plataformas sin servidor sean generalmente conocidas por ser difíciles de probar y depurar. Sin embargo, eso no significa que debamos ignorarlo.

¿Qué es lo siguiente? Justo encima de mi cabeza, podríamos hacerlo mejor. Aquí hay un par de mejoras que podemos hacer:

  1. Agregue un trabajo/etapa que retroceda automáticamente y revierta la confirmación cuando fallan las pruebas de humo
  2. Cree un entorno de prueba individual después de la creación de relaciones públicas para que podamos realizar pruebas de humo en ellos.
  3. Probablemente sea excesivo para este proyecto: implementar la implementación canary suena como un desafío divertido

Referencias

Si está buscando pruebas unitarias de Cloudflare Workers, estas son mis recomendaciones:

Aquí hay un video decente sobre cómo configurar una canalización de CI/CD ideal pero práctica:

Fuente del artículo original en  https://betterprogramming.pub/  

#cicd #git #cloudflare 

Cómo Configurar La Canalización De CI/CD Para Cloudflare Worker
伊藤  直子

伊藤 直子

1653640984

Cloudflareワーカー用のCI/CDパイプラインを設定する方法

今日、GitHubでの私のプロジェクトのほとんどは、 Renovateで最新の状態に保たれています。自動マージを有効にして、自動依存関係の更新によってリグレッションが発生しないことを十分に確信したいと思います。

Cloudflareワーカーのテストはちょっと手間がかかります。誤解しないでください、私はCloudflareWorkerが大好きです。ただし、既存のソリューションは少し直感的ではないと感じています。その上、dollarshaveclub / cloudworkerはもはや積極的に維持されておらず、これは残念なことです。

TL; DR:GitHubActionとGrafanak6を使用してCloudflareWorkerプロジェクトのCI/CDパイプラインを設定する方法。

概要

以前、CloudflareWorkerを使用してURL短縮クローンを作成しました。この既存のプロジェクト(GitHubリンク)を使用して、簡単な統合テストとともに、そのプロジェクトのCI/CDパイプラインのセットアップを検討します。

GitHub Action CI/CDパイプラインはかなり単純です。ステージ(ジョブ)は次のとおりです。

GitHubでのCIワークフローの例

GitHubでのCIワークフローの例(リンク

  1. リントチェックまたはユニットテスト
  2. ステージング環境にデプロイします
  3. ステージング環境で統合テストを実行します
  4. セマンティックリリースを実行し、本番環境にデプロイします

WranglerConfig

まず、既存のwrangler.tomlファイルを変更する必要があります。統合テストを実行するには、ステージング環境をデプロイする必要があることを忘れないでください。

[env.staging]
name = "atomic-url-staging"
workers_dev = true
kv_namespaces = [
  { binding = "URL_DB", id = "ca7936b380a840908c035a88d1e76584" },
]
  • name—環境ごとnameに一意で英数字(許可)である必要があることを確認してください。-ステージング環境に名前を付けましょうatomic-url-staging
  • worker_dev—統合テストは<NAME>.<SUBDOMAIN>.workers.devエンドポイントで実行されます。workers_dev = trueしたがって、 (参照)を設定してCloudflareワーカーをデプロイする必要があります。
  • kv_namespaces— Atomic URLは、短縮URLを格納するデータベースとしてKVを使用します。ここでは、プレビュー名前空間KVをテストデータベースとして使用することを選択しました。なんで?ローカル開発中(実行中)に使用するのと同じ開発KV名前空間であるという理由だけでwrangler dev。もちろん、通常のKV名前空間を使用することもできます。ProductionKVを使用していないことを確認してくださいidKV名前空間を作成する方法をお読みください

次に、本番KV名前空間を使用してデプロイする本番環境も作成する必要があります。

[env.production]
name = "atomic-url"
route = "s.jerrynsh.com/*"
workers_dev = false
kv_namespaces = [
  { binding = "URL_DB", id = "7da8f192d2c1443a8b2ca76b22a8069f" },
]

本番環境のセクションは、前と同じですが、本番用に設定worker_dev = falseしますroute

展開

ローカルマシンからそれぞれの環境に手動でデプロイするには、次のコマンドを実行します。

  • wrangler publish -e staging
  • wrangler publish -e production

ただし、GitHubアクションを使用してCI/CDパイプラインを介してこれを自動的に行う方法を検討します。

先に進む前に、ここwrangler.tomlで完全な構成を見つけることができます。

ああ、これが設定するチートシートwrangler.tomlです。これを利用することを強くお勧めします!

Grafanak6

統合テストには、k6と呼ばれるツールを使用します。一般に、k6はパフォーマンスと負荷テストのツールとして使用されます。さて、我慢してください。負荷テストをCI/CDパイプラインに統合するつもりはありません。今日ではありません。

ここでは、新しいコミットがブランチにプッシュされるたびに、このプロジェクトのスモークテストを実行します。mainスモークテストは、基本的に、システムの健全性チェックを実行する統合テストの一種です。

この場合、スモークテストを実行するだけで、システムがリグレッションなしで展開され、最小限の負荷で実行できることを確認できます。

何をテストするか

基本的に、グループでのURL短縮アプリのスモークテストの一部として確認したいことがいくつかあります。

  • メインページは、200の応答ステータスで期待どおりに読み込まれるはずです
group('visit main page', function () {
    const res = http.get(BASE_URL)check(res, {
        'is status 200': (r) => r.status === 200,
        'verify homepage text': (r) =>
            r.body.includes(
                'A URL shortener POC built using Cloudflare Worker'
            ),
    })
})
  • メインのPOSTAPIエンドポイント/api/urlは、元のURLで短縮URLを作成する必要があります
group('visit rest endpoint', function () {
    const res = http.post(
        `${BASE_URL}/api/url`,
        JSON.stringify({ originalUrl: DUMMY_ORIGINAL_URL }),
        { headers: { 'Content-Type': 'application/json' } }
    )check(res, {
        'is status 200': (r) => r.status === 200,
        'verify createShortUrl': (r) => {
            const { urlKey, shortUrl, originalUrl } = JSON.parse(r.body)
            shortenLink = shortUrl
            return urlKey.length === 8 && originalUrl === DUMMY_ORIGINAL_URL
        },
    })
})
  • 最後に、生成された短縮URLにアクセスすると、元のURLにリダイレクトされることを確認する必要があります
group('visit shortUrl', function () {
    const res = http.get(shortenLink)check(res, {
        'is status 200': (r) => r.status === 200,
        'verify original url': (r) => r.url === DUMMY_ORIGINAL_URL,
    })
})

ローカルでテストするには、を実行するだけk6 path/to/test.jsです。それで全部です!完全なテストスクリプトはここにあります。

負荷テストの実行を検討している場合は、負荷テストで同時ユーザーを決定する方法をお読みください。

GitHubアクション

このセクションは非常に単純なので、ここで詳しく説明します。ここで、最終的なGitHubActionsワークフローファイルを参照できます

私たちが持っているすべてのものをつなぎ合わせましょう。以下は、使用する必要のあるGitHubアクションです。

ワークフローファイルについて注意すべき点が1つあります。ジョブを別のジョブに依存させる(必要とする)ために、need構文を使用します。

アクションの秘密

このプロジェクトには、2つのアクションシークレットが必要です。

  1. CF_API_TOKEN— Wrangler GitHub Actionが、Cloudflareワーカーをそれぞれの環境に自動的に公開するために使用します。テンプレートを使用してAPIトークンを作成できますEdit Cloudflare Workers
  2. NPM_TOKEN—このプロジェクトは、semantic-releaseを使用してNPMに自動的に公開します。これを有効にするには、vianpmcreatetokenを作成する必要がNPM_TOKENあります

GitHubリポジトリシークレットに追加するには、このガイドを確認してください。

最終的なワークフローファイルをご覧になった方は、構文に気づき、プロジェクトのアクションシークレットに${{ secrets.GITHUB_TOKEN }}追加することについて何も言及しなかったのはなぜか疑問に思われたかもしれません。GITHUB_TOKEN結局のところ、それは自動的に作成され、すべてのワークフローに追加されます

閉会の辞

当然のことながら、サーバーレスプラットフォームは一般に、テストとデバッグが難しいことが知られています。しかし、それは私たちがそれを無視すべきだという意味ではありません。

それで、次は何ですか?私の頭の真上で、私たちはもっとうまくやることができました。これが私たちが行うことができるいくつかの改善です:

  1. スモークテストが失敗したときに自動的にロールバックしてコミットを元に戻すジョブ/ステージを追加します
  2. PRの作成時に個別のテスト環境を作成して、それらに対してスモークテストを実行できるようにします
  3. このプロジェクトではおそらくやり過ぎです—カナリアの展開を実装することは楽しい挑戦のように聞こえます

参考文献

Cloudflareワーカーの単体テストを検討している場合は、次のことをお勧めします。

これは、理想的でありながら実用的なCI/CDパイプラインのセットアップに関する適切なビデオです。

https://betterprogramming.pub/の元の記事のソース   

#cicd #git #cloudflare 

Cloudflareワーカー用のCI/CDパイプラインを設定する方法