Skip to main content

Portal Patch

Overview

Portal Patch applies declarative recipes to the documents generated by the Portal Controller, so you can shape the entities a Promise publishes without writing a script. It runs as a container in a PortalCustomization's configure lane. See Portal Patch for the full documentation.

Portal Patch is optional. The configure lane runs any image you give it, and Portal Patch is a helper we ship for the common cases.

The image is available at:

ghcr.io/syntasso/portal-patch:VERSION
The image tag is the grammar version

Portal Patch is versioned independently of the Portal Controller, and its image tag is the recipe grammar version. Recipes written against a tag keep working on that tag, so pin a version rather than tracking latest.

The release manifest is available at:

http://syntasso-enterprise-releases.s3-website.eu-west-2.amazonaws.com/#portal-patch/

Release Notes

v0.7.0 (2026-07-30)

The first release of Portal Patch.

Shaping a generated entity previously meant writing a shell or yq container, which had to know the document's structure and would silently do the wrong thing when that structure moved. Portal Patch replaces that with recipes that select what they mean, compose in order, and fail loudly rather than shipping a wrong document.

Features

  • Declarative recipes. Each container argument is a recipe naming a target and a change. Recipes apply in order and compose, so a batch reads as a list of intentions rather than a script.

  • Strategic merge. Patches merge recursively into the target: maps merge key by key, lists replace wholesale, and a null value deletes a key.

  • Targets that survive regeneration. Select a document by kind in a multi-document catalog-info.yaml, or a single-document file by name. Within a document, select list items by key rather than by index, including chains that reach into nested items, so recipes keep working when the generate stage reorders a list.

  • op: remove deletes a selected list item outright.

  • op: singleSpecPage collapses a Backstage Template's per-property pages into one, the per-Promise equivalent of the portal-wide --single-spec-page flag.

  • op: hideNamespaceManifest fixes the namespace in a generated request manifest, so resources land in a namespace you choose rather than one the developer picks.

  • op: cortexEntityProjection rewrites a Cortex workflow placeholder to project one attribute of a picked entity.

  • Fails loudly, and atomically. A recipe that matches nothing, matches ambiguously, or names a missing field fails the whole batch and writes no files, so a partly-applied change never ships. The one exception is an absent catalog-info.yaml, which is skipped with a log line.

Known issues

  • Recipes that target the ske-configure-resource step, including hideNamespaceManifest, fail under pull-request delivery mode, because that step only exists in push mode. The recipe matches nothing, which aborts the sync and ships no entity.