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

apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: sazon-service-with-db
  title: Sazón Service + (optional) Postgres
spec:
  owner: platform-sazon
  type: service
  parameters:
    - title: Service basics
      properties:
        name:
          title: Service name
          type: string
        owner:
          title: Owner
          type: string
        db:
          title: Needs Postgres?
          type: boolean
          default: false
        db_name:
          title: Postgres DB name
          type: string
          ui:field: EntityNamePicker
          dependencies:
            db: true
  steps:
    - id: fetch
      action: fetch:template
      input:
        url: ./skeleton
        values:
          name: ${{ parameters.name }}
          owner: ${{ parameters.owner }}
          db: ${{ parameters.db }}
    - id: publish
      action: publish:github
      input:
        repoUrl: https://github.com/sazon-foods/${{ parameters.name }}
        sourcePath: ./result
    - id: register
      action: catalog:register
      input:
        repoContentsUrl: ${{ steps.publish.output.repoContentsUrl }}
        catalogInfoPath: /catalog-info.yaml
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.

Diagram
Figure 15. Conditional fields en JSON Schema

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:

Diagram
Figure 16. Dry-run vs ejecución 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:

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.