diff --git a/content/releases/_index.md b/content/releases/_index.md index 91cb5bfaa034..b5a22d4c357e 100644 --- a/content/releases/_index.md +++ b/content/releases/_index.md @@ -1,4 +1,57 @@ --- title: Releases meta_desc: A running log of major platform updates from the Pulumi team. + +# Opt this section into JSON and RSS feeds (built in config/_default/config.yml). +# JSON -> /releases/index.json (layouts/releases/list.json) +# RSS -> /releases/rss.xml (layouts/releases/rss.xml) +outputs: + - HTML + - JSON + - RSS + +# A single, newest-first list of release-page entries. Each entry has a `type`: +# - updates: a lightweight month of items, rendered inline on the list page +# as
disclosures. Each item: { title, description, url?, tier? } +# — description is required. +# - release: a pointer to a full release. Everything else — the card's title, +# description, and image, plus the feed's items (sourced from the +# detail page's section cards: title, description, url, tier) — is +# read from the detail page at `url`. Only `date` (for ordering) +# and `url` live here, so there is nothing to hand-sync. +# The list page, JSON (/releases/index.json), and RSS (/releases/rss.xml) all +# render from this array, sorted by `date` descending (newest month first). +entries: + - type: updates + label: June 2026 Updates + date: 2026-06-24 + items: + - title: "Neo code reviews: AI code review built for infrastructure" + description: "Neo reviews each pull request as an agent — reading the code, the preview plan, and the resulting infrastructure diff together — and posts inline findings on the affected lines." + url: /blog/neo-code-reviews/ + - title: "Browse and publish private Terraform modules in the Pulumi Cloud registry" + description: "Publish your existing Terraform and OpenTofu modules to the Pulumi Cloud private registry with the tooling you already use, and browse them in the console — a drop-in migration path from HCP Terraform." + tier: Enterprise + - title: "Dark mode for the docs" + description: "😎 The Pulumi docs now offer a light, dark, and system theme toggle." + url: /docs/ + - title: "Individual user authentication for GitHub Enterprise Server" + description: "Self-hosted GitHub Enterprise operations now run as the individual user who triggered them, so pull requests, commits, and comments are attributed to that person and respect their permissions." + url: /docs/integrations/version-control/github-app/#individual-user-authentication-for-github-enterprise-server + tier: Business Critical + - title: "One CLI for Pulumi ESC with pulumi env" + description: "The standalone esc CLI is retiring in favor of pulumi env, so a single Pulumi CLI now manages your IaC, Deployments, and ESC environments." + url: /docs/esc/ + - title: "Universal Search: a Cmd/Ctrl+K command palette for Pulumi Cloud" + description: "A keyboard-first command palette (Cmd/Ctrl+K) jumps you to any stack, environment, resource, or member without leaving the page you're on." + - title: "Trigger deployments from Git tags on any supported VCS" + description: "Push a git tag to trigger a deployment, with optional glob filters, across GitHub, GitLab, Bitbucket, Azure DevOps, and Custom VCS." + url: /blog/trigger-deployments-on-git-tags/ + - title: "Pulumi CLI v3.245–v3.248: pulumi logs ls/rm, stack new, richer do and neo" + description: "June's CLI releases add pulumi logs ls/rm, rename stack init to stack new, and bring richer pulumi do and pulumi neo workflows." + url: https://github.com/pulumi/pulumi/releases + + - type: release + date: 2026-05-19 # for ordering; title, label, and feed items come from the detail page + url: /releases/agentic-infrastructure-era/ --- diff --git a/layouts/partials/releases/card-text-block.html b/layouts/partials/releases/card-text-block.html index 8feb8b6ccbdf..8413579e73b0 100644 --- a/layouts/partials/releases/card-text-block.html +++ b/layouts/partials/releases/card-text-block.html @@ -15,12 +15,15 @@ - title: Card title. - description: Card description (markdown). - isLinked: Bool. Adds the inline arrow icon when true. + - tier: Optional product tier (e.g. "Team"). Renders a badge inline after the + title; the badge picks up a violet tint when a linked card is hovered. */}} {{ $icon := .icon }} {{ $title := .title }} {{ $description := .description }} {{ $isLinked := .isLinked }} +{{ $tier := .tier }}
{{ with $icon }} @@ -29,7 +32,7 @@
{{ end }} {{ with $title }} -

{{ . }}

+

{{ . }}{{ with $tier }}{{ . }}{{ end }}

{{ end }} {{ with $description }}
diff --git a/layouts/partials/releases/card.html b/layouts/partials/releases/card.html index 2cd5e1fa4039..11bd1b401fc8 100644 --- a/layouts/partials/releases/card.html +++ b/layouts/partials/releases/card.html @@ -28,6 +28,7 @@ {{ $image := .image }} {{ $imageAlt := .image_alt | default $title }} {{ $link := .link }} +{{ $tier := .tier }} {{/* Span classes per variant (mobile is always single-column) */}} {{ $spanClass := "lg:col-span-1 lg:row-span-1" }} @@ -50,7 +51,7 @@ {{ end }} {{ end }} -{{ $textBlockArgs := dict "icon" $icon "title" $title "description" $description "isLinked" $isLinked }} +{{ $textBlockArgs := dict "icon" $icon "title" $title "description" $description "isLinked" $isLinked "tier" $tier }} {{ if $isLinked }}{{ else }}
{{ end }} diff --git a/layouts/partials/releases/updates.html b/layouts/partials/releases/updates.html new file mode 100644 index 000000000000..1888dda93478 --- /dev/null +++ b/layouts/partials/releases/updates.html @@ -0,0 +1,44 @@ +{{/* + Releases Updates + + A lightweight, card-less list of one month's update items. A small + uppercase mono overline (the month label) sits above the list. Each item is + a native
disclosure: the row shows the title + optional + tier badge + a chevron, and expanding it reveals a one-sentence description + with an inline "Read more" link when the item has a url. Using as + the toggle keeps the link a plain in-body , so the two never fight over + the click. No JS — matches the no-JS partial convention on /releases. + /releases is not a /docs page, so no dark-mode tokens are needed. + + Parameters: + - label: Overline text (e.g., "June 2026"). + - items: Slice of maps: { title, description, url?, tier? }. description is required. +*/}} + +{{ $label := .label }} +{{ $items := .items }} + +{{ $badgeClasses := "inline-flex items-center align-middle ml-2 rounded-full bg-gray-100 text-gray-600 px-2 py-0.5 text-[10px] font-mono uppercase tracking-wider leading-none" }} + +
+ {{ with $label }} +

{{ . }}

+ {{ end }} + +
+
diff --git a/layouts/releases/list.html b/layouts/releases/list.html index ab5046379775..bf21fad9aca0 100644 --- a/layouts/releases/list.html +++ b/layouts/releases/list.html @@ -9,16 +9,27 @@

{{ .Title }}

- {{ $items := where (where .Site.Pages "Type" "releases") "Kind" "eq" "page" }} - {{ range sort $items ".Params.date" "desc" }} - {{ partial "releases/release-item.html" (dict - "overline" .Params.label - "heading" .Params.title - "description" .Params.short_description - "feature_image" .Params.feature_image - "feature_image_alt" .Params.feature_image_alt - "link" .RelPermalink - ) }} + {{/* One newest-first list of updates + release entries (see _index.md). */}} + {{ range $idx, $entry := sort .Params.entries "date" "desc" }} + {{ if eq $entry.type "updates" }} + {{ partial "releases/updates.html" (dict + "label" $entry.label + "items" $entry.items + "idx" $idx + ) }} + {{ else if eq $entry.type "release" }} + {{/* Card visuals come from the detail page at `url`. */}} + {{ with site.GetPage (strings.TrimSuffix "/" $entry.url) }} + {{ partial "releases/release-item.html" (dict + "overline" .Params.label + "heading" .Params.title + "description" .Params.short_description + "feature_image" .Params.feature_image + "feature_image_alt" .Params.feature_image_alt + "link" .RelPermalink + ) }} + {{ end }} + {{ end }} {{ end }}
diff --git a/layouts/releases/list.json b/layouts/releases/list.json new file mode 100644 index 000000000000..e9d42ce487fb --- /dev/null +++ b/layouts/releases/list.json @@ -0,0 +1,56 @@ +{{- /* + Releases JSON feed -> /releases/index.json + + A single machine-readable document built from the `entries` manifest in + content/releases/_index.md, emitted newest-first by `date`. Each entry + carries a `type`: + - updates: items come from the manifest ({ title, description, url?, tier? }). + - release: a pointer; title/label and the item list are read from the + detail page at `url` (one item per section card: title, + description, url, tier). + Mirrors layouts/index.json and the dict/slice/append + jsonify style of + layouts/docs/list.llmsitemap.json. All relative URLs are absolutized with + absURL (which leaves already-absolute links like npm/GitHub URLs unchanged). +*/ -}} +{{- $entries := slice -}} +{{- range sort .Params.entries "date" "desc" -}} + {{- if eq .type "updates" -}} + {{- $items := slice -}} + {{- range .items -}} + {{- $item := dict "title" .title "description" .description -}} + {{- with .url -}}{{- $item = merge $item (dict "url" (absURL .)) -}}{{- end -}} + {{- with .tier -}}{{- $item = merge $item (dict "tier" .) -}}{{- end -}} + {{- $items = $items | append $item -}} + {{- end -}} + {{- $entries = $entries | append (dict + "type" "updates" + "label" .label + "date" (time.Format "2006-01-02" .date) + "items" $items) -}} + {{- else if eq .type "release" -}} + {{- with site.GetPage (strings.TrimSuffix "/" .url) -}} + {{- $items := slice -}} + {{- range .Params.sections -}} + {{- range .cards -}} + {{- $item := dict "title" .title "description" (.description | markdownify | plainify | htmlUnescape | chomp | replaceRE "\\s+" " ") -}} + {{- with .link -}}{{- $item = merge $item (dict "url" (absURL .)) -}}{{- end -}} + {{- with .tier -}}{{- $item = merge $item (dict "tier" .) -}}{{- end -}} + {{- $items = $items | append $item -}} + {{- end -}} + {{- end -}} + {{- $entries = $entries | append (dict + "type" "release" + "title" .Title + "label" .Params.label + "date" (time.Format "2006-01-02" .Params.date) + "url" .Permalink + "items" $items) -}} + {{- end -}} + {{- end -}} +{{- end -}} + +{{- dict + "title" .Title + "url" (absURL .RelPermalink) + "entries" $entries + | jsonify (dict "indent" " ") -}} diff --git a/layouts/releases/rss.xml b/layouts/releases/rss.xml new file mode 100644 index 000000000000..7680db69e841 --- /dev/null +++ b/layouts/releases/rss.xml @@ -0,0 +1,52 @@ +{{ printf "" | safeHTML }} +{{- /* + Releases RSS feed -> /releases/rss.xml + + Driven by the `entries` manifest in content/releases/_index.md, emitted + newest-first by date, and mirroring the JSON feed's items. An `updates` + entry emits one per item that carries a url. A `release` entry emits + one per linked section card on its detail page (resolved at `url`), + using the card's title, link, and description. Modeled on layouts/blog/rss.xml + and layouts/events/rss.xml. URLs are absolutized with absURL. +*/ -}} + + + Pulumi Releases + {{ .Permalink }} + A running log of major platform updates from the Pulumi team. + {{ .Site.LanguageCode }} + {{ range sort .Params.entries "date" "desc" }} + {{ if eq .type "release" }} + {{ with site.GetPage (strings.TrimSuffix "/" .url) }} + {{ $date := .Params.date }} + {{ range .Params.sections }} + {{ range $card := .cards }} + {{ with $card.link }} + + {{ $card.title }} + {{ absURL . }} + {{ $date | time.Format "2006-01-02" }}-{{ absURL . }} + {{ time.Format "Mon, 02 Jan 2006 15:04:05 -0700" $date | safeHTML }} + {{ $card.description | markdownify | plainify | htmlUnescape | chomp | replaceRE "\\s+" " " }} + + {{ end }} + {{ end }} + {{ end }} + {{ end }} + {{ else if eq .type "updates" }} + {{ $date := .date }} + {{ range $item := .items }} + {{ with $item.url }} + + {{ $item.title }} + {{ absURL . }} + {{ $date | time.Format "2006-01-02" }}-{{ absURL . }} + {{ time.Format "Mon, 02 Jan 2006 15:04:05 -0700" $date | safeHTML }} + {{ $item.description }} + + {{ end }} + {{ end }} + {{ end }} + {{ end }} + +