feat: publish UI stylesheet to CDN on release (YPE-1733) - #331
Open
bdhyv wants to merge 7 commits into
Open
Conversation
🦋 Changeset detectedLatest commit: 168a60c The changes in this PR will be included in the next version bump. This PR includes changesets to release 0 packagesWhen changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Collaborator
|
@bdhyv feel free to tag me for review when this is ready for review! |
When a new @youversion/platform-react-ui version is published, upload packages/ui/dist/tailwind.css to the cdn.youversion.com origin bucket so it is served at https://cdn.youversion.com/platform/<major>/bible.css. Auth uses Workload Identity Federation (no static keys): only this repo can impersonate platform-sdk-cdn-publisher@yvplatform-prod, which can only write under the bucket's platform/ prefix. The <major> path segment lives in packages/ui/CDN_CSS_MAJOR_VERSION and is bumped only for breaking CSS changes (documented in PUBLISHING.md). Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Re-running a failed Release job cannot retry the CDN upload because changesets reports nothing newly published on the re-run. Add a workflow_dispatch trigger that skips versioning/publishing and always uploads the freshly built stylesheet (idempotent), and document it as the recovery path. Addresses Greptile P1 review feedback. Co-authored-by: Cursor <cursoragent@cursor.com>
workflow_dispatch can be triggered from any ref containing the workflow file, which would let a branch build overwrite the production stylesheet. Guard the job to refs/heads/main so non-main dispatches are no-ops. Addresses Greptile security review feedback. Co-authored-by: Cursor <cursoragent@cursor.com>
A manual recovery run previously rebuilt current HEAD, which could contain merged-but-unreleased UI changes and push CSS ahead of the published npm package. Manual runs now check out the newest @youversion/platform-react-ui release tag before building, so the uploaded stylesheet always matches npm. Addresses Greptile review. Co-authored-by: Cursor <cursoragent@cursor.com>
Per the Platform feature-flag conventions (transformers docs/feature_flags.md), the CDN upload now reads the feature.platform.sdkCssCdn flag from the prod Firebase Remote Config server template and skips the upload unless it is "true". The flag ships dark (prod: false) and is launched/killed from the Firebase console without a code change. Flag defined in transformers MR !599. Co-authored-by: Cursor <cursoragent@cursor.com>
Tag creation dates can lie (recreated tags, prereleases), so manual recovery runs now ask npm for the latest dist-tag version and check out the exact matching release tag, failing loudly if it does not exist. Addresses Greptile review feedback. Co-authored-by: Cursor <cursoragent@cursor.com>
bdhyv
force-pushed
the
ype-1733/cdn-css-upload
branch
from
August 14, 2026 14:28
aa9535d to
168a60c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements YPE-1733: when the Release workflow publishes a new
@youversion/platform-react-uiversion to npm, it now also uploads the package's compiled stylesheet (packages/ui/dist/tailwind.css) to thecdn.youversion.comorigin bucket, served at:How it works
release.ymlrun only when@youversion/platform-react-uiis among the packages published by changesets (npm publish happens first, per the ticket)./1path segment is defined in one obvious place —packages/ui/CDN_CSS_MAJOR_VERSION— and is bumped only for breaking CSS changes. Documented inPUBLISHING.md(new "CDN Stylesheet" section).Cache-Control: public, max-age=300, must-revalidatesince this is a mutable object at a stable URL (unlike the hashed immutable CSS the transformers build ships).feature.platform.sdkCssCdnfrom the prod Firebase Remote Config server template (parameterfeature_platform_sdkCssCdn) and skips the upload unless it istrue. The flag is defined in the transformers manifest per Platform conventions — see transformers !599 — withprod: false, so merging this PR does not start CDN publishing by itself; launching (or killing) it is a value flip in the prod Firebase console, no deploy needed.main: manual runs skip versioning/publishing, check out the tag of the latest published UI release (so the CSS always matches npm even ifmainadvanced), and upload. Dispatches from non-mainrefs are no-ops (job-level guard).Authorization (the "delicate part")
No static API keys. This uses Workload Identity Federation, the same pattern as
youversion-platform-accountsandyouversion-platform-developer-hub:github-actions-poolin theyvplatform-prodGCP project.platform-sdk-cdn-publisher@yvplatform-prod.iam.gserviceaccount.com(per-repoworkloadIdentityUserbinding).roles/storage.objectUserongs://cdn-yv-platform-prodrestricted by IAM condition to theplatform/prefix, androles/cloudconfig.vieweronyvplatform-prodfor the feature-flag read. It cannot touchcss/,fonts/,spotlights/, or anything else in GCP.The
WIF_PROVIDER/WIF_SERVICE_ACCOUNTrepo secrets are already set, and the GCP-side resources are already provisioned, so this works as soon as it merges (dark until the flag flips).Test plan
release.ymlpasses YAML validationyouversion/platform-sdk-react, conditional bucket grant in place (platform/ write 200, css/ write 403), Remote Config server template read 200feature_platform_sdkCssCdntotruein the prod Firebase console (server template), run the workflow manually onmain, and confirmhttps://cdn.youversion.com/platform/1/bible.cssserves the latest released build (checklast-modified/ byte size)Greptile Summary
The PR adds feature-flagged publication of the UI package’s compiled stylesheet to a stable CDN URL, including a manual recovery path pinned to the npm
latestrelease tag.tailwind.cssafter a UI package release using workload identity federation.Confidence Score: 5/5
The PR appears safe to merge.
No blocking failure remains.
Important Files Changed
Sequence Diagram
sequenceDiagram participant Trigger as Release trigger participant Workflow as Release workflow participant NPM as npm registry participant Git as Git tags participant RC as Firebase Remote Config participant CDN as GCS CDN origin alt Push to main Trigger->>Workflow: Run release Workflow->>NPM: Publish changed packages Workflow->>RC: Read CDN feature flag RC-->>Workflow: Enabled or disabled opt UI published and flag enabled Workflow->>CDN: Upload compiled bible.css end else Manual recovery on main Trigger->>Workflow: workflow_dispatch Workflow->>NPM: Resolve UI latest version Workflow->>Git: Check out matching release tag Workflow->>Workflow: Build stylesheet Workflow->>RC: Read CDN feature flag opt Flag enabled Workflow->>CDN: Upload compiled bible.css end endReviews (8): Last reviewed commit: "fix: resolve manual recovery tag from th..." | Re-trigger Greptile