Las vistas previas de compilación no son nada nuevo o innovador. Heroku los tuvo durante años. Sin embargo, si está construyendo en Google Cloud Platform, las cosas son un poco más difíciles. Google Cloud Build se puede usar para implementar en Cloud Functions, Cloud Run, Kubernetes, App Engine, etc., etc. Esto es lo que complica un poco las vistas previas, ya que Cloud Build no sabe dónde está implementando su aplicación o servicio. Tienen una aplicación GitHub para conectar los repositorios y mostrar el estado de compilación en GitHub, pero eso es todo. Sin vistas previas, comentarios ni ninguna de las cosas "normales" a las que estamos acostumbrados con productos como Heroku, Vercel o Fly.
Hay una forma "fácil" de publicar un comentario en una solicitud de extracción de GitHub desde Cloud Build con una simple solicitud HTTP. Pero, ¿por qué es fácil cuando puede usar la API de implementaciones de GitHub ?
Con esta API, puede crear entornos, tener diferentes variables por entorno y mostrar el estado de compilación e implementación directamente en una solicitud de incorporación de cambios. Y una vez que se realiza la implementación en su plataforma de CD, puede agregar la URL al estado de implementación. Esto es lo que vamos a hacer en este artículo.
Nuevamente, hay otra forma de hacer esto mediante el uso de la API de implementaciones directamente con solicitudes HTTP. Sin embargo, esto puede ser complicado a veces y deberá definir un token de acceso personal para autenticarse con GitHub. En cambio, decidimos armar un pequeño servicio de Node.js que usa GitHub Apps para generar un token de aplicación e interactuar con la API de implementaciones. Esto permite un control un poco más preciso sobre el proceso de implementación.
Este artículo está escrito exclusivamente para Google Cloud Platform y GitHub. Se asume una comprensión básica de Google Cloud Platform, Google Cloud Build y los permisos de IAM.
Debe tener un proyecto de Google Cloud Platform configurado.
GitHub Deployer es un pequeño servicio de Node.js que se autoriza con una aplicación de GitHub e interactúa con la API de implementaciones de GitHub. Los comandos están predefinidos y es necesario integrar cierta información en la imagen de Docker, ya que, de lo contrario, la configuración del tiempo de ejecución en Cloud Build sería demasiado compleja.
La imagen de Docker no está lista; deberá compilarlo usted mismo y enviarlo a su registro. El mejor lugar es Google Artifact Registry, donde también se almacenan las imágenes de su aplicación (Container Registry está obsoleto):
Si aún no lo ha hecho, cree un repositorio de registro de artefactos
Cree una aplicación de GitHub e instálela en su organización
Permisos requeridos: 'pull_requests', 'implementaciones', 'metadatos'
Copie la ID de la aplicación (desde la pantalla de configuración de la aplicación) y la ID de instalación de la aplicación (después de hacer clic en "Configurar", encontrará la ID de instalación en la URL. No tengo idea de dónde más se puede encontrar)
Cree y descargue una clave privada y conviértala a base64 ( base64 -i your.private-key.pem
)
Cloud Build se ejecuta en amd64
, por lo que necesitamos buildx
para crear la imagen para la plataforma x86:
docker buildx build --platform linux/amd64 . -t us-central1-docker.pkg.dev/[PROJECT]/docker/gh-deployer \
--build-arg GH_APP_ID=[GITHUB_APP_ID] \
--build-arg GH_APP_PRIVATE_KEY=[GITHUB_PRIVATE_KEY_BASE_64] \
--build-arg GH_APP_INSTALLATION_ID=[GITHUB_INSTALLATION_ID] \
--build-arg GH_OWNER=[GITHUB_ORG]
Empuje la imagen a su registro:
docker push us-central1-docker.pkg.dev/[PROJECT]/docker/gh-deployer
docker run -it -e REPO_NAME=test -e REF=main -e ENVIRONMENT=test us-central1-docker.pkg.dev/[PROJECT]/docker/gh-deployer:latest create
REPO_NAME
: requiere el nombre del repositorio (por ejemplo, gh-deployer
)REF
: requiere la rama, etiqueta o SHA para implementar (por ejemplo, main
)ENVIRONMENT
: requiere el entorno para implementar (por ejemplo, preview
)TRANSIENT_ENVIRONMENT
: opcional/falso si se establece en true
, la implementación se eliminará después de cierto tiempoDESCRIPTION
: opcional una descripción de la implementaciónLos siguientes comandos están disponibles como primer argumento:
create
- crear una nueva implementaciónpending
: la compilación está pendientein_progress
- la compilación está en progresoqueued
: la compilación está en colasuccess
- la implementación fue exitosaerror
- algo salió malfailure
: la implementación falló
Con Cloud Build, las opciones actualmente son un poco limitadas. No hay un estado pending
, ya que Cloud Build debe iniciarse para crear la implementación inicial. queued
tampoco tiene mucho sentido, por lo que en nuestra propia configuración, estamos usando lo siguiente:
gh-deployer/create
para crear la implementación transitoria para una confirmaciónpgh-deployer/ending
directamente después de creargh-deployer/in_progress
después de completar la compilación y antes de implementar la imagengh-deployer/success
después de implementar la imagen
Nuevamente, con Cloud Build no sabemos dónde se realizará la implementación, por lo que hay dos formas de pasar la URL de implementación al paso success
:
/workspace/deployer_environment_url
success
Usamos Cloud Run para nuestras implementaciones, así que este es el paso de compilación para recuperar la URL de implementación para un número de solicitud de extracción determinado:
- nombre: gcr.io/google.com/cloudsdktool/cloud-sdk
env: - PR_NUMBER=$_PR_NUMBER script: >- gcloud run services list --project [project] --filter preview-$PR_NUMBER --format "value(status.address.url)" > /workspace/deployer_environment_url
Aquí hay un ejemplo completo usando el archivo de configuración cloudbuild.yaml
. Usamos Kaniko para construir y Cloud Run como objetivo de implementación.
Si trabaja con Terraform, también hay un archivo de Terraform que falla: preview.tf
Al utilizar la API de implementaciones, puede desencadenar acciones de GitHub en deployment_status
. Esto facilita la ejecución de comprobaciones de control de calidad, pruebas de extremo a extremo, etc. en cada compilación de vista previa. Aquí hay un ejemplo para ejecutar Playwright en cada vista previa usando la environment_url
que se pasa para el estado success
:
dramaturgo-qa:
if: ${{ github.event.deployment\_status.state == 'success' }} timeout-minutes: 60 runs-on: ubuntu\-latest steps: \- uses: actions/[\[email protected\]](/cdn-cgi/l/email-protection) \- uses: actions/setup\-[\[email protected\]](/cdn-cgi/l/email-protection) with: node-version: 20 cache: 'npm' \- run: npm ci \- name: Install Playwright Browsers run: npm exec playwright install \-\-with\-deps \-y \- name: Run Playwright tests run: pnpm exec playwright test env: BASE\_URL: ${{github.event.deployment\_status.environment\_url}} \- uses: actions/upload\-[\[email protected\]](/cdn-cgi/l/email-protection) if: always() with: name: playwright\-report path: playwright\-report/ retention-days: 30
gcr.io/google.com/cloudsdktool/cloud-sdk
es relativamente grande. Puede crear su propia imagen pequeña de gcloud con componentes de Cloud Run para acelerar las compilaciones.
Los comentarios sobre las solicitudes de extracción de GitHub son fáciles al principio, pero cuando tiene múltiples implementaciones por solicitud de extracción, compilaciones fallidas, etc., no ofrecen mucha flexibilidad y son difíciles de mantener/actualizar. La API de implementaciones de GitHub ofrece una forma elegante de crear y administrar implementaciones desde cualquier sistema CI/CD de terceros. Con GitHub Deployer
intentamos agilizar la interacción con la API de implementaciones y solucionar algunos efectos secundarios o dificultades que son imposibles de resolver solo con la API HTTP.
Otro beneficio de usar la API de implementaciones de GitHub es que puede usar el disparador deployment_status
para las acciones de GitHub y obtener la environment_url
directamente con la carga útil del evento.
Puede encontrar instrucciones de instalación / compilación un poco más detalladas y todo el código en el repositorio de GitHub
Si tiene alguna pregunta o comentario , comuníquese con BlueSky / Twitter o únase a la discusión en GitHub .
También publicado aquí.