Pipeline de una Alexa Skill con GitHub Actions
Pipeline DevOps usando GitHub Actions
Como vimos en el anterior post, hemos desarrollado un pipeline entero para una Skill de Alexa usando CircleCI. Ahora vamos a construir lo mismo, pero usando la nueva herramienta de integración continua proporcionada por GitHub, GitHub Actions para así comprender su funcionamiento y ver las diferencias respecto a la anterior plataforma de CI/CD usada.
A su vez, vamos a utilizar la ASK CLI v2 y también utilizaremos una estructura de ficheros de una Alexa Skill proporcionada por esta nueva segunda versión.
Requisitos previos
Aquí tienes las tecnologías utilizadas en este proyecto:
- Amazon Developer Account - Cómo crear una cuenta
- AWS Account - Regístrate aquí gratis
- ASK CLI - Instalar y configurar ASK CLI
- GitHub Account - Regístrate aquí gratis
- Visual Studio Code
La Alexa Skills Kit Command Line Interface (ASK CLI) es una herramienta para que podamos administrar nuestras Skills de Alexa y recursos relacionados, como las funciones de AWS Lambda. Con la ASK CLI, tenemos acceso a la Skill Management API, que nos permite administrar las Skills de Alexa mediante la línea de comandos.
Si quieres crear una Skill con ASK CLI v2, sigue los pasos descritos en la documentación oficial de Amazon Alexa.
Vamos a utilizar esta herramienta para realizar algunos pasos en nuestro pipeline.
¡Let’s DevOps!
GitHub Actions
GitHub Actions
GitHub Actions nos ayuda a automatizar tareas dentro del ciclo de vida del desarrollo de software. GitHub Actions está controlado por eventos, lo que significa que podemos ejecutar una serie de comandos después de que haya ocurrido un evento específico. Por ejemplo, cada vez que alguien crea una pull request para un repositorio, podemos ejecutar automáticamente un pipeline en GitHub Actions.
Un evento activa automáticamente el workflow
, que contiene uno o varios jobs. Luego, el jobs
usa steps
para controlar el orden en que se ejecutan las acciones. Estas acciones son los comandos que automatizan ciertos procesos.
Pipeline
GitHub Actions Pipeline
Vamos a explicar job por job lo que está sucediendo en nuestro pipeline. En primer lugar, los jobs del workflow se definirán debajo del nodo jobs
en el archivo de configuración de GitHub Actions:
Checkout
El job de checkout ejecutará las siguientes tareas:
- Checkout del código.
- Dar permiso de ejecución para poder ejecutar todos los tests
checkout:
runs-on: ubuntu-latest
name: Checkout
steps:
# To use this repository's private action,
# you must check out the repository
- name: Checkout
uses: actions/checkout@v2
- run: |
chmod +x -R ./test;
ls -la
build
El job de build ejecutará las siguientes tareas:
- Checkout del código.
- Ejecutar
npm install
para descargar todas las dependencias de Node.js
build:
runs-on: ubuntu-latest
name: Build
needs: checkout
steps:
# To use this repository's private action,
# you must check out the repository
- name: Checkout
uses: actions/checkout@v2
- run: |
cd lambda;
npm install
Pretests
El job de pretest ejecutará el checkeo de calidad del código estático. Consulta la explicación completa aquí.
Test
El job de test ejecutará las pruebas unitarias. Consulta la explicación completa aquí.
Code Coverage
El job codecov ejecutará el informe de cobertura de código. Consulta la explicación completa aquí.
Deploy
El job de deploy desplegará la Skill de Alexa en la nube de Alexa en el stage de development. Consulta la explicación completa aquí.
Testing de la Voice User Interface
Estos jobs verificarán nuestro interaction model. Consulta la explicación completa aquí.
Integration tests
Estos jobs verificarán el interaction model y nuestro backend también. Consulta la explicación completa aquí.
End to end tests
Bespoken
Estos jobs verificarán el sistema completo utilizando la voz como entrada gracias a Bespoken. Consulta la explicación completa aquí.
Validation tests
Estos jobs validarán la Skill de Alexa antes de enviarla a certificación. Consulta la explicación completa aquí.
Store-artifacts
El job de store-artifacts ejecutará las siguientes tareas:
- Descargar el código.
- Almacenar el código completo de nuestra Skill de Alexa como un artefacto. Será accesible en GitHub Actions cuando queramos verlo.
store-artifacts:
runs-on: ubuntu-latest
name: Submit
needs: submit
steps:
# To use this repository's private action,
# you must check out the repository
- name: Checkout
uses: actions/checkout@v2}
- name: Upload code
uses: actions/upload-artifact@v2
with:
name: code
path: ${{ github.workspace }}
Submit
Estos jobs enviarán la Skill de Alexa a certificación. Consulta la explicación completa aquí.
Workflow
Al final del archivo de configuración GitHub Actions, definiremos nuestro pipeline como un workflow de GitHub Actions que ejecutará los jobs explicados anteriormente:
on: [push]
jobs:
checkout:
runs-on: ubuntu-latest
name: Checkout
steps:
# To use this repository's private action,
# you must check out the repository
- name: Checkout
uses: actions/checkout@v2
- run: |
chmod +x -R ./test;
ls -la
build:
runs-on: ubuntu-latest
name: Build
needs: checkout
steps:
# To use this repository's private action,
# you must check out the repository
- name: Checkout
uses: actions/checkout@v2
- run: |
cd lambda;
npm install
pretest:
runs-on: ubuntu-latest
name: Pre-test
needs: build
steps:
# To use this repository's private action,
# you must check out the repository
# To use this repository's private action,
# you must check out the repository
- name: Checkout
uses: actions/checkout@v2
- run: |
cd lambda;
npm install;
npm run lint;
npm run lint-html
- name: Upload results
uses: actions/upload-artifact@v2
with:
name: eslint-report
path: lambda/reports/eslint/
test:
runs-on: ubuntu-latest
name: Test
needs: pretest
steps:
# To use this repository's private action,
# you must check out the repository
- name: Checkout
uses: actions/checkout@v2
- run: |
cd lambda;
npm install;
npm run test
- name: Upload results
uses: actions/upload-artifact@v2
with:
name: unit-tests-report-html
path: lambda/mochawesome-report/
- name: Upload results
uses: actions/upload-artifact@v2
with:
name: unit-tests-report-xml
path: lambda/reports/mocha/
codecov:
runs-on: ubuntu-latest
name: Code Coverage
needs: test
steps:
# To use this repository's private action,
# you must check out the repository
- name: Checkout
uses: actions/checkout@v2
- run: |
cd lambda;
npm install;
npm run codecov
env: # Or as an environment variable
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
deploy:
runs-on: ubuntu-latest
name: Deploy
needs: codecov
steps:
# To use this repository's private action,
# you must check out the repository
- name: Checkout
uses: actions/checkout@v2
- run: |
sudo npm install -g ask-cli;
sudo apt-get install -y jq
cd lambda;
npm install;
npm run copy-package;
cd src;
npm run build-production
- run: ls -la && ask deploy --ignore-hash
env: # Or as an environment variable
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
ASK_ACCESS_TOKEN: ${{ secrets.ASK_ACCESS_TOKEN }}
ASK_REFRESH_TOKEN: ${{ secrets.ASK_REFRESH_TOKEN }}
ASK_VENDOR_ID: ${{ secrets.ASK_VENDOR_ID }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
SKILL_ID: ${{ secrets.SKILL_ID }}
check-utterance-conflicts:
runs-on: ubuntu-latest
name: Check Utterance Conflicts
needs: deploy
steps:
# To use this repository's private action,
# you must check out the repository
- name: Checkout
uses: actions/checkout@v2
- run: |
sudo npm install -g ask-cli;
chmod +x -R ./test;
cd test/vui-test/;
./interaction_model_checker.sh $SKILL_ID v2
env: # Or as an environment variable
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
ASK_ACCESS_TOKEN: ${{ secrets.ASK_ACCESS_TOKEN }}
ASK_REFRESH_TOKEN: ${{ secrets.ASK_REFRESH_TOKEN }}
ASK_VENDOR_ID: ${{ secrets.ASK_VENDOR_ID }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
SKILL_ID: ${{ secrets.SKILL_ID }}
check-utterance-resolution:
runs-on: ubuntu-latest
name: Check Utterance Resolution
needs: deploy
steps:
# To use this repository's private action,
# you must check out the repository
- name: Checkout
uses: actions/checkout@v2
- run: |
sudo npm install -g ask-cli;
chmod +x -R ./test;
cd test/vui-test/;
./utterance_resolution_checker.sh $SKILL_ID v2
env: # Or as an environment variable
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
ASK_ACCESS_TOKEN: ${{ secrets.ASK_ACCESS_TOKEN }}
ASK_REFRESH_TOKEN: ${{ secrets.ASK_REFRESH_TOKEN }}
ASK_VENDOR_ID: ${{ secrets.ASK_VENDOR_ID }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
SKILL_ID: ${{ secrets.SKILL_ID }}
check-utterance-evaluation:
runs-on: ubuntu-latest
name: Check Utterance Evaluation
needs: deploy
steps:
# To use this repository's private action,
# you must check out the repository
- name: Checkout
uses: actions/checkout@v2
- run: |
sudo npm install -g ask-cli;
chmod +x -R ./test;
cd test/vui-test/;
./utterance_evaluation_checker.sh $SKILL_ID v2
env: # Or as an environment variable
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
ASK_ACCESS_TOKEN: ${{ secrets.ASK_ACCESS_TOKEN }}
ASK_REFRESH_TOKEN: ${{ secrets.ASK_REFRESH_TOKEN }}
ASK_VENDOR_ID: ${{ secrets.ASK_VENDOR_ID }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
SKILL_ID: ${{ secrets.SKILL_ID }}
integration-test:
runs-on: ubuntu-latest
name: Integration test
needs: check-utterance-evaluation
steps:
# To use this repository's private action,
# you must check out the repository
- name: Checkout
uses: actions/checkout@v2
- run: |
sudo npm install -g ask-cli;
chmod +x -R ./test;
sudo apt-get install -y expect
cd test/integration-test/;
./simple-dialog-checker.sh $SKILL_ID
env: # Or as an environment variable
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
ASK_ACCESS_TOKEN: ${{ secrets.ASK_ACCESS_TOKEN }}
ASK_REFRESH_TOKEN: ${{ secrets.ASK_REFRESH_TOKEN }}
ASK_VENDOR_ID: ${{ secrets.ASK_VENDOR_ID }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
SKILL_ID: ${{ secrets.SKILL_ID }}
end-to-test:
runs-on: ubuntu-latest
name: End-to-end test
needs: integration-test
steps:
# To use this repository's private action,
# you must check out the repository
- name: Checkout
uses: actions/checkout@v2
- run: |
sudo npm install -g ask-cli;
sudo npm install -g bespoken-tools;
chmod +x -R ./test;
bst test --config test/e2e-bespoken-test/testing.json
env: # Or as an environment variable
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
ASK_ACCESS_TOKEN: ${{ secrets.ASK_ACCESS_TOKEN }}
ASK_REFRESH_TOKEN: ${{ secrets.ASK_REFRESH_TOKEN }}
ASK_VENDOR_ID: ${{ secrets.ASK_VENDOR_ID }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
SKILL_ID: ${{ secrets.SKILL_ID }}
- name: Upload code
uses: actions/upload-artifact@v2
with:
name: bespoken-report
path: test_output/
validation-test:
runs-on: ubuntu-latest
name: Validation test
needs: end-to-test
steps:
# To use this repository's private action,
# you must check out the repository
- name: Checkout
uses: actions/checkout@v2
- run: |
sudo npm install -g ask-cli;
chmod +x -R ./test;
cd test/validation-test/;
./skill_validation_checker.sh $SKILL_ID v2
env: # Or as an environment variable
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
ASK_ACCESS_TOKEN: ${{ secrets.ASK_ACCESS_TOKEN }}
ASK_REFRESH_TOKEN: ${{ secrets.ASK_REFRESH_TOKEN }}
ASK_VENDOR_ID: ${{ secrets.ASK_VENDOR_ID }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
SKILL_ID: ${{ secrets.SKILL_ID }}
submit:
runs-on: ubuntu-latest
name: Submit
needs: validation-test
steps:
# To use this repository's private action,
# you must check out the repository
- name: Checkout
uses: actions/checkout@v2
- run: |
sudo npm install -g ask-cli;
chmod +x -R ./test;
cd test/submit/;
./submit.sh $SKILL_ID v2
env: # Or as an environment variable
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
ASK_ACCESS_TOKEN: ${{ secrets.ASK_ACCESS_TOKEN }}
ASK_REFRESH_TOKEN: ${{ secrets.ASK_REFRESH_TOKEN }}
ASK_VENDOR_ID: ${{ secrets.ASK_VENDOR_ID }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
SKILL_ID: ${{ secrets.SKILL_ID }}
store-artifacts:
runs-on: ubuntu-latest
name: Store Artifacts
needs: submit
steps:
# To use this repository's private action,
# you must check out the repository
- name: Checkout
uses: actions/checkout@v2
- name: Upload code
uses: actions/upload-artifact@v2
with:
name: code
path: ${{ github.workspace }}
El archivo de configuración GitHub Actions se encuentra en .github/workflows/main.yml
.
Recursos
- DevOps Wikipedia - Wikipedia
- Documentación oficial del SDK de Node.js - La documentación oficial del SDK de Node.js
- Documentación oficial del Alexa Skills Kit - La documentación oficial del Alexa Skills Kit
- Documentación oficial de GitHub Actions - Documentación oficial de GitHub Actions
Conclusión
Habiendo desarrollado el mismo pipeline en CircleCI como se puede leer en este post, podemos sacar las siguientes conclusiones en base a los problemas que nos hemos encontrado durante el desarrollo de este proyecto:
- GitHub Actions es una plataforma muy joven (apenas tiene año y medio de vida).
- Podemos encontrar funcionalidad básica para cualquier pipeline de DevOps (flujos de control, steps de aprobación manual, etc.) que no está disponible aún en GitHub Actions.
- Ejecutar comandos en un contenedor Docker específico solo es posible a través de las Actions disponibles en su marketplace. Debido a esto, complica un poco el trabajo con ejecutores Docker en esta plataforma.
Puedes encontrar el código en mi GitHub
¡Eso es todo!
¡Espero que te sea útil! Si tienes alguna duda o pregunta, no dudes en ponerte en contacto conmigo o poner un comentario a continuación.
Happy coding!