Skip to content

Rewrite packaging script for pre-built CF deploy#5260

Open
norman-abramovitz wants to merge 27 commits intodevelopfrom
feature/rewrite-packaging-script
Open

Rewrite packaging script for pre-built CF deploy#5260
norman-abramovitz wants to merge 27 commits intodevelopfrom
feature/rewrite-packaging-script

Conversation

@norman-abramovitz
Copy link
Contributor

@norman-abramovitz norman-abramovitz commented Mar 6, 2026

New Features

  • Pre-built CF packaging - Rewrites bin/package to produce pre-built
    CF deployment zips for both amd64 and arm64 using binary_buildpack
    instead of stratos-buildpack. No compilation during staging. Supports
    --skip-build flag to repackage from existing build artifacts.

  • Home page column span - Cards can now declare columnSpan to occupy
    multiple grid columns in multi-column layouts.

Improvements

  • Home page first-load rendering - Cards now render correctly on
    initial page load without requiring back-button navigation. Uses a
    counter signal instead of boolean to ensure every check triggers a
    unique emission, and recomputes effective layout after definition is
    set in ngOnInit.

  • Recent apps list width - The recently updated applications list now
    stretches to fill the full available card width, with app names
    left-aligned and timestamps right-aligned.

  • Home page card ordering - Cards are now sorted by renderPriority
    within each favorites group, so Cloud Foundry cards appear before
    GitHub cards.

  • Metric tiles layout - Applications, Orgs, and Routes metrics stay
    on a single horizontal row using flex-wrap, adapting gracefully to
    narrow viewports.

  • Routes metric visibility - Routes metric is now visible in both
    single-column and two-column layouts.

  • Sidebar width in multi-column - Sidebar width is reduced in
    two-column layouts to prevent content compression.

  • Recent apps row count - Adjusted row count for two-column view
    to better fill available space.

  • Timestamps in all layouts - Timestamps are now shown in all home
    page layout modes.

  • Compact app card text overflow - Long app names truncate with
    ellipsis instead of overflowing.

Bug Fixes

  • Endpoints page icon centering - Fixed off-centered + button by
    replacing app-custom-icon with span.material-icons so global
    button icon styles apply correctly through Angular's view encapsulation.

  • Toggle label - Renamed "Show all endpoints" to "Show connected
    endpoints" for clarity.

Full Changelog: develop...feature/rewrite-packaging-script

Replace the old bin/package that compiled from
source with a script that uses Makefile build
targets and produces a zip for cf push -p with
binary_buildpack. Old script kept as package.old
until verified by Kevin Rutten.
Use make build-backend-all to cross-compile for
all platforms, then package linux/amd64 and
linux/arm64 zips for CF deployment.
Include OS name in generated zip files and staging
directories (e.g. stratos-cf-4.4.0-linux-amd64.zip)
to support future OS/arch combinations. Update README
packaging section to match.
Auto-resolve org/space GUIDs from names via cf CLI
when not explicitly provided in secrets.yaml. Detect
SSO vs local login in check spec to support both
deployment types.
OpenSSL aes-256-cbc with pbkdf2 key derivation.
Allows secrets.yaml.enc to be committed safely
while keeping plaintext secrets.yaml gitignored.
Verifies recent apps timestamps persist when
switching between single and two column layouts.
Covers FWT-678.
Remove layout-conditional showDate binding that
hid timestamps in multi-column views. FWT-678.
Replace layout$ | async with direct signal read
layout() in the template. With OnPush and
zoneless change detection, the async pipe can
miss the initial emission from the signal-to-
observable bridge.
Change condition from layout.x === 1 to
layout.x <= 2 so the Routes count appears
in both single and two-column layouts.
Use flex layout with wrap for the metrics tile
group so tiles stay in one row when there is
enough width and wrap on narrow viewports.
Use w-48 (192px) instead of w-80 for the
favorites/shortcuts sidebar when cards are in a
multi-column grid. Prevents the sidebar from
compressing main card content.
Set distinct row counts per layout mode:
- 3+ columns: hide recent apps (0 rows)
- Compact modes: 5 rows
- Two-column: 7 rows
- Single column: 10 rows

Add markForCheck() call so OnPush detects the
imperative property update on the dynamically
created component.
Allow endpoint types to declare how many grid
columns their home card should span. The grid
uses dense auto-flow to backfill gaps.

- Add columnSpan to HomeCardMetadata interface
- CF registers columnSpan: 2 for wider content
- getEffectiveSpan() clamps to available columns
- Wrapper computes effective layout so cards
  make content decisions based on actual width
- Automatic layout caps at 2 columns when >50%
  of cards are wide
Add text-overflow ellipsis and nowrap on dates
to prevent layout wrapping in narrow columns.
Set min-height and flex-wrap for consistent
card sizing across layout modes.
Document the home page subsystem including
endpoint type vs instance model, home card
resolution flow, layout system, columnSpan
behavior, and extension guide.
Replace app-custom-icon with span.material-icons
so global button icon styles apply correctly.
Use counter signal instead of boolean to ensure
every check triggers a unique emission. Recompute
effective layout after definition is set in ngOnInit.
Use renderPriority as tiebreaker within each
favorites group so CF cards appear before GitHub.
Add flex-direction column to card content so inner
div expands to full width. Set block display on
host elements and default grid column to 1fr.
@norman-abramovitz
Copy link
Contributor Author

Difficult Fix: Recent Apps List Not Filling Width

Issue: The recently updated applications list only filled about 60% of the available card width, leaving empty space between the row borders and the Favorites sidebar.

Root cause: Angular's emulated view encapsulation and CSS specificity. The card-cf-recent-apps component applies .recent-apps-card__content as a class on the app-card-content host element. In compiled CSS, this scoped class selector (.recent-apps-card__content[_ngcontent-xxx] — specificity 0,2,0) beats the component's own :host rule ([_nghost-yyy] — specificity 0,1,0). The parent's style set display: flex without specifying flex-direction, so it defaulted to row. This caused the inner <div class="px-6 py-4"> (rendered by app-card-content's template) to become a row flex item, which shrinks to content width instead of filling the container.

Fix: Added flex-direction: column to .recent-apps-card__content. In column direction, flex items stretch to fill the cross-axis (width) by default, so the inner content div now expands to full width. Additionally set display: block on host elements of cfhome-card and compact-app-card (block elements naturally fill their containing block), and added grid-template-columns: 1fr to app-tile-grid which had no default column definition for desktop — causing CSS grid to use implicit auto-sized columns.

Commits: d95ed8b

@norman-abramovitz
Copy link
Contributor Author

Difficult Fix: Endpoints Page Icon Centering

Issue: The + button on the endpoints page was visually off-centered compared to identical + buttons on other pages that rendered correctly.

Root cause: Angular's emulated view encapsulation. Working + buttons throughout the app use bare <span class="material-icons"> elements, which the global CSS rule .btn-icon .material-icons { font-size: 20px; ... } can target directly. The endpoints page used <app-custom-icon>add</app-custom-icon> instead, which wraps the icon text in an <i> element inside a host element. Angular's emulated encapsulation adds [_ngcontent-xxx] attributes that increase specificity on the component's scoped font-size: 24px rule, preventing the global button icon styles from penetrating the encapsulation boundary. Multiple attempts to fix this within the custom-icon component (display: contents, :host-context(.btn-icon)) failed because the scoped attribute selectors consistently won the specificity battle.

Fix: Replaced <app-custom-icon> with <span class="material-icons"> on the endpoints page, matching the pattern used by every other page. Removed the unused CustomIconComponent import. The global styles now apply directly without any encapsulation barrier.

Commits: a58d7ce

@norman-abramovitz
Copy link
Contributor Author

Difficult Fix: Home Page First-Load Card Rendering

Issue: Home page cards showed placeholder/error state on first load and only rendered correctly after navigating away and back (e.g., using the browser back button).

Root cause: Two separate timing issues compounding each other.

  1. Boolean signal deduplication. The _checkLayout signal was signal<boolean>(true). After the initial emission triggered card loading, the subscription handler called _checkLayout.set(false) to reset it. Subsequent calls to checkCardsInView() called _checkLayout.set(true) — but if the signal was already true (e.g., the reset hadn't propagated yet, or two checks fired in quick succession), Angular's signal deduplication silently dropped the emission. The toObservable() bridge only emits on new values, so identical consecutive values were swallowed.

  2. @Input setter firing before ngOnInit. The layout input setter on HomePageEndpointCardComponent fires during parent template binding, which happens before the component's own ngOnInit. The setter computed effective layout using this.definition?.homeCard?.columnSpan, but this.definition is only set in ngOnInit (after the entity catalog lookup). On the first call, definition was undefined, so columnSpan defaulted to 1 and the effective layout was wrong.

Fix:

  1. Changed _checkLayout from signal<boolean>(true) to signal<number>(0) with update(v => v + 1). Every call now produces a unique value that toObservable() will always emit. Removed the filter(v => v) gate and the _checkLayout.set(false) reset — both are unnecessary with a counter.

  2. Extracted layout computation into computeEffectiveLayout() and called it both in the @Input setter (for subsequent updates) and at the end of ngOnInit (after this.definition is set), followed by updateLayout() to propagate the corrected layout to children.

Commits: a808d45

Document the plugin system covering backend
interfaces, registration, dependency resolution,
frontend integration, and cross-build dependency.
Single source of truth for extra plugins compiled
into the jetstream binary. Both go generate and the
frontend prebuild read from this file.
Reads plugin-config.yaml and writes extra_plugins.go
with blank imports. Validates each plugin directory
exists under plugins/.
Run go generate before go build in both the Makefile
build-backend target and cross-compile.sh so the
backend builds independently of the frontend.
Frontend prebuild and StratosConfig now read from
plugin-config.yaml instead of scanning package.json
stratos.backend arrays. Remove backend declarations
from all 4 frontend package.json files.
Reflect the new plugin-config.yaml flow, decoupled
builds, and updated key files reference.
The backend.ts prebuild now merges plugins from
stratos.yaml backend key, matching the behavior
of StratosConfig.getBackendPlugins().
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant