Forms, dry-run y un template serio

Objetivos del capítulo
  • Diseñar forms con validación y conditional fields.

  • Usar dry-run para revisar cada step antes de aplicar.

  • Escribir un template complejo realista.

Forms que se adaptan al developer

Un buen maître de sala no te pregunta el plato principal antes de saber si eres vegetariano. El Scaffolder hace lo mismo con conditional fields: según lo que el developer marca, aparecen (o se ocultan) campos relevantes. Cero preguntas inútiles.

Conditional fields con dependencias

Unresolved directive in chapters/cap-13-scaffolder-forms-y-dry-run.adoc - include::../../chapters/chapter-13-scaffolder-advanced/templates/sazon-service-with-db/template.yaml[tag=conditional-params]
dependencies y ui:autofocus
  • :code:`dependencies` muestra el campo solo si el campo dependiente es true.

  • :code:`ui:autofocus: true` lleva el cursor al campo al cargar.

  • :code:`ui:field: EntityNamePicker` usa un widget custom que valida contra el catalog.

Conditional fields en JSON Schema
Failed to generate image: Could not find the 'mmdc' executable in PATH; add it to the PATH or specify its location using the 'mmdc' document attribute
flowchart TB
  DB{Tiene Postgres?} -->|true| DBName[db_name]
  DB -->|false| SkipDB[(campo oculto)]

Custom widgets: EntityNamePicker, OwnerPicker

Backstage trae widgets custom para campos críticos:

  • EntityNamePicker — autocompleta con entidades del catalog.

  • OwnerPicker — selecciona un Group del catalog.

  • GitHubRepoPicker — autocompleta con repos de una org.

  • RepoUrlPicker — input con validación de URL de repo.

Para usarlos, monta el plugin frontend correspondiente:

pnpm add @backstage/plugin-scaffolder

Dry-run: ensayar antes de publicar

Antes de ejecutar un template en producción, usa dry-run. El Scaffolder aplica los steps en un directorio temporal y te muestra el log de cada acción:

Dry-run vs ejecución real
Failed to generate image: Could not find the 'mmdc' executable in PATH; add it to the PATH or specify its location using the 'mmdc' document attribute
flowchart LR
  Run[Ejecutar] --> Dry{dry-run?}
  Dry -->|sí| Temp[(directorio temporal)]
  Dry -->|no| Real[(publicar en GitHub)]
  Temp --> Inspect[Inspeccionar log]
  Inspect -->|ok| Real
Inspecta siempre el log

Dry-run te muestra qué ha hecho cada step y dónde ha fallado. Si un step falla, no se aplican los siguientes. Revisar el log es obligatorio antes de aceptar un dry-run.

Un template serio: servicio con DB opcional

El template completo, con conditional fields y dos ramas en el skeleton:

Unresolved directive in chapters/cap-13-scaffolder-forms-y-dry-run.adoc - include::../../chapters/chapter-13-scaffolder-advanced/templates/sazon-service-with-db/template.yaml[tag=full-template-v2]
Estructura del skeleton

El skeleton puede tener ramas con {{#if db}}…​{{/if}} (Nunjucks) para generar contenido condicional. Por ejemplo, crear Dockerfile.postgres solo si db: true.

Secrets en output

Si un step expone un secreto en output, marca :code:`output.visible: false` para que no se muestre en el log final ni en respuestas HTTP. Es la pieza que evita filtrar tokens en auditorías.

Example 13. Receta del capítulo
  1. Define conditional fields con dependencies: { campo: true }.

  2. Usa widgets custom para evitar entradas inválidas.

  3. Ejecuta dry-run antes de cualquier publicación real.

  4. Marca output.visible: false en secretos.

  5. Versiona el template en git; cambia el name cuando rompas compatibilidad.

Resumen

  • Conditional fields con dependencies adaptan el form al developer.

  • Widgets custom (EntityNamePicker, OwnerPicker) evitan entradas inválidas.

  • Dry-run aplica los steps en un dir temporal y muestra el log.

  • output.visible: false oculta secretos del log.

Glosario del capítulo

JSON Schema

Estándar para validar la estructura de JSON.

dependencies

Clave de JSON Schema para hacer un campo condicional.

dry-run

Modo de ejecución que aplica los steps en un dir temporal sin publicar.

EntityNamePicker

Widget que autocompleta con entidades del catalog.

output.visible

Si false, el valor del output no aparece en logs.

Próximo capítulo

Auth: GitHub OAuth, Keycloak/OIDC y RBAC —quién entra, cómo se mapea al catalog y qué puede hacer.