Skip to content

BDMS-884: App refresh banner — notify users when a new version is deployed#292

Open
jeremyzilar wants to merge 8 commits into
stagingfrom
BDMS-884-app-refresh-bar
Open

BDMS-884: App refresh banner — notify users when a new version is deployed#292
jeremyzilar wants to merge 8 commits into
stagingfrom
BDMS-884-app-refresh-bar

Conversation

@jeremyzilar

@jeremyzilar jeremyzilar commented Jun 11, 2026

Copy link
Copy Markdown
Contributor
image

Why

Field staff and hydrogeologists keep Ocotillo open for extended periods. Without a notification, they can stay on a stale version for hours after a deploy — potentially missing bug fixes or new features, or hitting broken experiences. This adds a visible banner that prompts them to reload.

How version detection works

There is nothing to manually increment. The system uses a build timestamp, not a version number.

Every time code is merged to staging or production, the CI/CD pipeline runs npm run build:ci. During that build, a Vite plugin runs before any code is compiled and writes this file to the output:

dist/version.json  →  { "buildTime": "2026-06-11T19:42:00.000Z" }

The timestamp is set to the exact moment the build ran. No two builds produce the same value.

When a user loads Ocotillo, the app fetches /version.json and stores that timestamp as its baseline. Every 5 minutes it fetches /version.json again. If the timestamp has changed, a new version is live and the banner appears.

The full sequence for a production deploy:

  1. PR is merged into production branch
  2. GitHub Actions triggers CD deploy production to GAE
  3. npm run build:ci runs — the Vite plugin writes a new version.json with the current timestamp
  4. The build output (including the new version.json) is deployed to App Engine
  5. Within 5 minutes, any user who still has the old version open will see the banner

The same sequence applies to staging via CD deploy staging to GAE.

The Cache-Control: no-store header in app.yaml and app-staging.yaml ensures App Engine never serves a cached copy of version.json. Every poll hits the live file.

The version number in the sidebar

image

The v1.0.1 shown at the bottom of the sidebar is a separate thing. It comes from package.json and is bumped manually by the team when cutting a named release (e.g., v1.1.0). It is not involved in banner detection — it is just there for reference so users and support staff can quickly see which release is running.

What changed

File Change
vite.config.ts write-version-json plugin writes public/version.json at build start
public/version.json Placeholder for local dev ({"buildTime":"dev"})
src/hooks/useNewVersion.ts Polling hook — fetches on mount to capture baseline, polls every 5 min; ?preview-refresh-banner URL param forces it visible for testing
src/components/NewVersionBanner.tsx Indigo banner with the message and a Refresh Now button (shadcn Button)
src/components/AppShell.tsx Banner mounted inside AppContent above the header; sidebar footer shows v{version} from package.json
app.yaml / app-staging.yaml Added Cache-Control: no-store handler for /version.json so GAE never caches it

Banner text

We just made Ocotillo 5% better. Refresh to get the good stuff!

Behaviour

  • Banner only appears after a new deploy is detected — never on first load
  • "Refresh Now" calls window.location.reload()
  • No dismiss option — the banner stays until the user reloads
  • Polling stops once the banner is visible

Testing locally

Append ?preview-refresh-banner to any URL to force the banner visible without waiting for a real deploy:

http://localhost:5173/?preview-refresh-banner

…s deployed

Adds a non-intrusive top banner that appears when a new build has been deployed
while a user has the app open. Detects new versions by polling /version.json
every 5 minutes and comparing against the build time captured at initial load.

- vite.config.ts: new write-version-json plugin writes public/version.json with
  the current ISO build time at the start of every build
- public/version.json: placeholder file for local dev (contains "dev")
- src/hooks/useNewVersion.ts: polls /version.json, returns isNewVersionAvailable
  and dismiss(); stops detecting once the user dismisses the banner
- src/components/NewVersionBanner.tsx: full-width indigo banner with
  "We just made Ocotillo 5% better. Refresh to get the good stuff!",
  a Refresh Now button that reloads the page, and an X to dismiss
- src/components/AppShell.tsx: banner rendered above AppLayout in a flex-col
  wrapper so it takes only the space it needs and the shell fills the rest
@github-actions

Copy link
Copy Markdown

Preview Deployment

Preview URL: https://preview-bdms-884-app-refresh-bar-auejgdbofq-uc.a.run.app

Note: This preview uses the staging API endpoints.

@github-actions

Copy link
Copy Markdown

Preview Deployment

Preview URL: https://preview-bdms-884-app-refresh-bar-auejgdbofq-uc.a.run.app

Note: This preview uses the staging API endpoints.

2 similar comments
@github-actions

Copy link
Copy Markdown

Preview Deployment

Preview URL: https://preview-bdms-884-app-refresh-bar-auejgdbofq-uc.a.run.app

Note: This preview uses the staging API endpoints.

@github-actions

Copy link
Copy Markdown

Preview Deployment

Preview URL: https://preview-bdms-884-app-refresh-bar-auejgdbofq-uc.a.run.app

Note: This preview uses the staging API endpoints.

@github-actions

Copy link
Copy Markdown

Preview Deployment

Preview URL: https://preview-bdms-884-app-refresh-bar-auejgdbofq-uc.a.run.app

Note: This preview uses the staging API endpoints.

@github-actions

Copy link
Copy Markdown

Preview Deployment

Preview URL: https://preview-bdms-884-app-refresh-bar-auejgdbofq-uc.a.run.app

Note: This preview uses the staging API endpoints.

@github-actions

Copy link
Copy Markdown

Preview Deployment

Preview URL: https://preview-bdms-884-app-refresh-bar-auejgdbofq-uc.a.run.app

Note: This preview uses the staging API endpoints.

@github-actions

Copy link
Copy Markdown

Preview Deployment

Preview URL: https://preview-bdms-884-app-refresh-bar-auejgdbofq-uc.a.run.app

Note: This preview uses the staging API endpoints.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants