Publicación de Módulos

La publicación empaqueta un módulo y hace que una versión o etiqueta mutable esté disponible mediante Wippy Hub.

Este documento es un flujo de publicación y una referencia. Los módulos acme/*, las URL, los tokens, las credenciales y el código fuente de ejemplo son ilustrativos; sustitúyelos por recursos que pertenezcan a tu organización.

Requisitos Previos

  1. Cree una cuenta en hub.wippy.ai
  2. Cree una organización o únase a una
  3. Tenga permiso para crear módulos en esa organización — el primer wippy publish registra el módulo automáticamente

Estructura del Módulo

mymodule/
├── wippy.yaml      # Module manifest
├── src/
│   ├── _index.yaml # Entry definitions
│   └── *.lua       # Source files
└── README.md       # Documentation (optional)

wippy.yaml

Define los metadatos del módulo en wippy.yaml:

organization: acme
module: http-utils
type: library
description: HTTP utilities and helpers
license: MIT
repository: https://github.com/acme/http-utils
homepage: https://acme.dev
keywords:
  - http
  - utilities
authors:
  - Acme Engineering <eng@acme.dev>
embed:
  - acme.http:assets
exclude:
  - test/**
  - "*.test.lua"
  - acme.http:debug_handler
exclude_meta:
  stage:
    - experimental
metadata:
  support_url: https://acme.dev/support
Campo Requerido Descripción
organization Sí Nombre de su organización en el hub
module Sí Nombre del módulo
type No Tipo de módulo: library, application, agent o plugin
description No Descripción breve
license No Identificador SPDX (MIT, Apache-2.0)
repository No URL del repositorio fuente
homepage No Página principal del proyecto
keywords No Palabras clave de búsqueda
authors No Lista de autores
version No Versión semántica; --version la sobrescribe
exclude No Patrones a descartar: los valores que contienen : son IDs de entradas, todo lo demás es un glob de archivos fuente
embed No Patrones de empaquetado fs.directory por defecto cuando no se pasa --embed
exclude_meta No Mapa de campo de metadatos a valores; las entradas cuyos metadatos coinciden se descartan
metadata No Metadatos arbitrarios de clave/valor que acompañan al módulo publicado
publish.profiles No Qué perfiles de configuración incluir en el paquete (ver Publicar Perfiles)
publish.runtime No Qué secciones de configuración del runtime incluir como valores por defecto del paquete; solo type: application

exclude se divide por forma en vez de por un campo aparte. _old/**, test/** y *.test.lua filtran archivos fuente a medida que se recolectan; acme.http:debug_handler deshabilita una entrada del registro después de que las entradas se decodifican. Un segmento ** abarca cualquier número de segmentos de directorio.

type es la fuente de verdad de cómo el hub clasifica el módulo y puede cambiarse en una publicación posterior; --module-type lo sobrescribe para una única publicación. Cuando se omite, los módulos recién creados usan application por defecto con una advertencia de deprecación.

Definiciones de Entradas

Las entradas se definen en _index.yaml:

version: "1.0"
namespace: acme.http

entries:
  - name: definition
    kind: ns.definition
    meta:
      title: HTTP Utilities
      description: Helpers for HTTP operations
    readme: file://README.md
    wiki:
      GUIDE.md: file://docs/GUIDE.md
      examples/auth.md: file://docs/auth.md

  - name: client
    kind: library.lua
    source: file://client.lua
    modules:
      - http_client
      - json

El mapa wiki: en ns.definition publica páginas de documentación adicionales junto al readme: las claves son rutas de página, los valores son referencias file://. Los contenidos se incrustan en el momento del empaquetado y el hub los sirve como una wiki navegable por módulo.

Dependencias

Declare dependencias de otros módulos:

entries:
  - name: __dependency.wippy.test
    kind: ns.dependency
    meta:
      description: Testing framework
    component: wippy/test
    version: ">=0.3.0"

Restricciones de versión:

Restricción Significado
* Cualquier versión
1.0.0 Versión exacta
>=1.0.0 Versión mínima
^1.0.0 Compatible (misma mayor)

Requisitos

Defina la configuración que los consumidores deben proporcionar:

entries:
  - name: api_endpoint
    kind: ns.requirement
    meta:
      description: API endpoint URL
    targets:
      - entry: acme.http:client
        path: ".meta.endpoint"
    default: "https://api.example.com"

Los targets especifican dónde se inyecta el valor:

  • entry - ID completo de la entrada a configurar
  • path - JSONPath para la inyección del valor

default acepta cualquier tipo escalar — default: 20 fluye hacia un target numérico como número, no como cadena. Lo mismo aplica a parameters[].value en entradas ns.dependency, y ambos aceptan referencias ${env:NAME}, transportadas literalmente y resueltas cuando la entrada de destino se decodifica.

Los consumidores configuran mediante override. La bandera -o toma una tripleta namespace:entry:field=value:

wippy run -o acme.http:client:meta.endpoint=https://custom.api.com

Imports

Referencie otras entradas:

- name: handler
  kind: function.lua
  source: file://handler.lua
  modules:
    - json
  imports:
    client: acme.http:client           # Same namespace
    utils: acme.utils:helpers          # Different namespace
    base_registry: :registry           # Built-in

En Lua:

local client = require("client")
local utils = require("utils")

Contratos

Defina interfaces públicas:

- name: http_contract
  kind: contract.definition
  meta:
    name: HTTP Client Contract
  methods:
    - name: get
      description: Perform GET request
    - name: post
      description: Perform POST request

- name: http_contract_binding
  kind: contract.binding
  contracts:
    - contract: acme.http:http_contract
      methods:
        get: acme.http:get_handler
        post: acme.http:post_handler

Flujo de Publicación

1. Autenticarse

wippy auth login

2. Preparar

wippy init
wippy update
wippy lint

3. Validar

wippy publish --dry-run

Publish construye el paquete de la misma forma con o sin --dry-run, de modo que la validación cubre todo lo que produciría la publicación real:

  • organization y module deben ser alfanuméricos en minúsculas con guiones interiores, version debe ser semver, y type debe ser uno de los cuatro tipos de módulo.
  • publish.runtime pertenece a las aplicaciones: declarar source, sections o vars bajo él sin type: application falla.
  • Cada recurso que declara meta.artifact.format es inspeccionado por ese formato. Un artefacto mal formado falla aquí en lugar de en un consumidor, y dos artefactos cuyas salidas caerían en directorios solapados se rechazan.
  • El formato node-package requiere además que package.json lleve una version semántica que sea igual a la versión del módulo que se publica, un name de paquete válido, y ningún script de ciclo de vida preinstall, install, postinstall o prepare.

La última regla es la que muerde durante una release: suba version en wippy.yaml y en el package.json del artefacto a la vez, o la publicación se detiene.

4. Publicar

wippy publish --version 1.0.0

Con notas de versión:

wippy publish --version 1.0.0 --release-notes "Initial release"

Banderas Adicionales

Bandera Descripción
--label <name> Publicar como etiqueta mutable (ej. latest, beta) en lugar de una versión inmutable
--protected Marcar la versión publicada como protegida (no puede eliminarse ni sobrescribirse)
--registry <url> Anular la URL del registro para esta publicación
--config <dir> Directorio que contiene wippy.yaml (predeterminado: directorio actual)
--create Registrar el módulo en el hub si aún no existe, luego publicar
--module-visibility <v> Visibilidad para --create: private (predeterminado) o public
--module-type <t> Tipo de módulo: library, application, agent o plugin (sobrescribe type: en wippy.yaml)
--module-display-name <n> Nombre visible para --create

Empaquetado de Archivos Estáticos

Los módulos con entradas fs.directory (assets estáticos, plantillas, archivos públicos) deben usar --embed para incluirlos en el paquete publicado. Sin él, una entrada fs.directory se empaqueta sin el contenido de su directorio.

wippy publish --version 1.0.0 --embed app:public_files
wippy publish --version 1.0.0 --embed app:assets,app:templates

La lista del manifiesto y la bandera --embed aceptan IDs de entrada o nombres que coincidan con entradas fs.directory. La bandera puede repetirse y cada valor puede ser una lista separada por comas. La misma bandera de CLI está disponible en wippy pack; una selección explícita mediante CLI sustituye la lista del manifiesto para esa invocación.

Primera Publicación

La primera vez que publicas un módulo se registra en el hub automáticamente (privado por defecto) y la publicación se reintenta una vez. Pasa --create para registrarlo de antemano y establecer sus propiedades:

wippy publish --create --version 0.1.0 \
  --module-visibility public \
  --module-type library \
  --module-display-name "HTTP Utils"

--create es idempotente — para un módulo ya registrado, el paso de creación no hace nada. Si tu cuenta no puede crear módulos en la organización, el hub devuelve un error de permiso en lugar de publicar.

Publicar en un Hub Local

Apunta --registry a un hub que se ejecute localmente para publicar e instalar sin el registro público. Se permite HTTP plano solo para hosts locales — localhost, 127.0.0.1 y los alias de contenedor host.docker.internal (Docker Desktop / OrbStack) y host.containers.internal (Podman); cualquier otro host debe usar HTTPS.

wippy auth login --registry http://localhost:8080 --token wpy_xxx
wippy publish --registry http://localhost:8080 --create --version 0.1.0

El registro y el token también pueden provenir de las variables de entorno WIPPY_REGISTRY y WIPPY_TOKEN. Cuando no se establecen, el registro toma por defecto https://hub.wippy.ai.

Cuotas

Si la cuota de módulos privados de la organización está agotada, la publicación falla con un mensaje como cannot publish: Private-module quota exhausted (5 of 5).... Haz el módulo público o pide a un administrador de la organización que aumente la cuota. Las cargas y descargas se reintentan automáticamente ante errores de red transitorios.

Publicar Valores por Defecto de Runtime :id=publishing-runtime-defaults

Las aplicaciones (solo type: application) pueden distribuir valores por defecto de configuración de runtime dentro de sus packs mediante publish.runtime en wippy.yaml:

type: application
publish:
  runtime:
    source: .wippy.yaml            # default: .wippy.yaml
    sections: [security, registry, override]
    vars: [public_url]
Campo Descripción
source Archivo de configuración del que se leen las secciones (por defecto: .wippy.yaml)
sections Secciones de configuración de runtime copiadas a los metadatos del pack como valores por defecto
vars Lista explícita de variables a empaquetar incluso cuando no se referencian

Reglas:

  • Solo se empaquetan las variables referenciadas por las secciones seleccionadas o los perfiles publicados (seguidas transitivamente); todo lo demás necesita una entrada en vars.
  • Las referencias ${env:...} en la configuración exportada se rechazan — el entorno del publicador nunca se filtra a un pack.
  • Las secciones locales de máquina boot, extensions y workspace no pueden exportarse.
  • Solo el pack de la aplicación principal proporciona valores por defecto de runtime del host; los metadatos de runtime en los packs de dependencias se ignoran.

En el destino, la configuración se aplica de menor a mayor: valores por defecto del pack de la app, valores por defecto integrados del runtime, archivos de configuración locales, perfiles seleccionados, sobrescrituras de CLI.

Publicar Perfiles :id=publishing-profiles

Los perfiles de la aplicación raíz se exportan a los metadatos runtime.profiles del pack. Publicar no selecciona ni fija un perfil — los consumidores eligen uno en tiempo de ejecución con wippy run --profile <name>:

publish:
  profiles:
    enabled: true
    source: config/profiles.yaml   # default: .wippy.yaml
    include: [production]          # omit to publish all non-workspace profiles

include: [] no publica ninguno; un nombre desconocido hace fallar la publicación. Las subsecciones workspace nunca se exportan, ni siquiera dentro de un perfil publicado. Ver Configuración para declarar perfiles.

Uso de Módulos Publicados

Agregar Dependencia

wippy add acme/http-utils
wippy add acme/http-utils@1.0.0
wippy install

Configurar Requisitos

Anular valores en tiempo de ejecución:

wippy run -o acme.http:client:meta.endpoint=https://my.api.com

O en .wippy.yaml:

override:
  acme.http:client:meta.endpoint: "https://my.api.com"

Importar en Su Código

# your src/_index.yaml
entries:
  - name: __dependency.acme.http
    kind: ns.dependency
    component: acme/http-utils
    version: ">=1.0.0"

  - name: my_handler
    kind: function.lua
    source: file://handler.lua
    imports:
      http: acme.http:client

Ejemplo Completo

wippy.yaml:

organization: acme
module: cache
type: library
description: In-memory caching with TTL
license: MIT
keywords:
  - cache
  - memory

src/_index.yaml:

version: "1.0"
namespace: acme.cache

entries:
  - name: definition
    kind: ns.definition
    meta:
      title: Cache Module

  - name: cache
    kind: library.lua
    source: file://cache.lua
    modules:
      - time

src/cache.lua:

local time = require("time")

local cache = {}
local store = {}

function cache.set(key, value, ttl)
    store[key] = {
        value = value,
        expires = ttl and (time.now():unix() + ttl) or nil
    }
end

function cache.get(key)
    local entry = store[key]
    if not entry then return nil end
    if entry.expires and time.now():unix() > entry.expires then
        store[key] = nil
        return nil
    end
    return entry.value
end

return cache

Publicar:

wippy init
wippy update
wippy lint
wippy publish --version 1.0.0

Véase También