Internal doc for you (the author) – not end-user facing. This captures the exact, repeatable steps to develop a change, test it, publish a new container image to the public ACR, and surface the upgrade to running environments via the built‑in banner.
- Dev & test locally.
- Bump
api/package.jsonversion (e.g. 0.1.0 -> 0.2.0) – keep semver. - Commit & push.
- (Optional but recommended when you start using Releases) Create annotated git tag:
git tag -a v0.2.0 -m "v0.2.0"thengit push origin v0.2.0. - Build & push image to ACR:
pwsh ./scripts/publish-acr.ps1 -Registry scimtoolpublic -ResourceGroup scimtool-rg -Latest(adds version + latest). - Update Container App:
az containerapp update -n scimtool-prod -g scimtool-rg --image ghcr.io/kayasax/scimtool:0.2.0. - Open UI → banner should show if newer than running instance.
- (Optional) Publish a GitHub Release for richer banner notes.
- The publish script derives the image tag from
api/package.jsonversion if-Tagnot supplied. - Tagging the repo (vX.Y.Z) after committing the version ensures Git history matches the container version.
- The frontend checks:
GET /releases/lateston GitHub. If a Release exists it usestag_name.- If no Releases exist (404) it falls back to the most recent git tag.
- Once you start creating Releases, only the latest Release will drive the banner (fallback tags ignored when Releases exist).
Run backend & frontend locally (your existing setup.ps1 helpers):
pwsh .\setup.ps1 -TestLocal # or your preferred dev scriptValidate new functionality & log capture.
Edit api/package.json:
"version": "0.2.0"Keep to semantic versioning: MAJOR (breaking) / MINOR (feature) / PATCH (fix).
Stage & commit:
git add api/package.json
git commit -m "chore: bump version to 0.2.0"
git pushIf you are not using GitHub Releases yet and rely only on tags, this still lets the banner work (fallback path):
git tag -a v0.2.0 -m "v0.2.0"
git push origin v0.2.0When ready to leverage richer notes:
- Go to GitHub → Releases → Draft new release.
- Tag:
v0.2.0(create if not existing). - Title:
v0.2.0. - Notes: bullet changes.
- Publish.
Unified (web + api) image is built from repo root Dockerfile.
Local build (fast, if Docker installed):
pwsh ./scripts/publish-acr.ps1 -Registry scimtoolpublic -ResourceGroup scimtool-rg -LatestFlags:
-Latestalso tags:latestpointing to the same digest.- Add
-Tag 0.2.0to override auto-detected version (rarely needed). - Add
-EnableAnonymousonly once (stay public). - Use
-UseRemoteBuildif you want ACR to perform the build (note: we previously saw remote build issues with unicode output & big context; local is currently more stable).
Resulting references:
scimtoolpublic.azurecr.io/scimtool:0.2.0
scimtoolpublic.azurecr.io/scimtool:latest
az containerapp update -n scimtool-prod -g scimtool-rg --image ghcr.io/kayasax/scimtool:0.2.0To always use the moving pointer (still need manual update):
az containerapp update -n scimtool-prod -g scimtool-rg --image ghcr.io/kayasax/scimtool:latestLogs:
az containerapp logs show -n scimtool-prod -g scimtool-rg --tail 50Version endpoint:
Invoke-RestMethod -Headers @{ Authorization = 'Bearer S@g@r2011' } -Uri https://<FQDN>/scim/admin/versionBanner should show new version if the running instance version < latest release/tag.
The UI now provides a streamlined update experience:
Compact Banner:
- Shows: "New version available: [current] → [latest]"
- More button opens modal with release notes
- Copy Update Command button provides one-liner command
Hosted PowerShell Script: Users can update with a single command (copied from banner):
iex (irm https://scimtoolpublic.azurecr.io/scimtool/update-scimtool.ps1)The hosted script:
- Validates Azure CLI authentication
- Prompts for confirmation before updating
- Normalizes version strings (removes 'v' prefix)
- Updates the Container App with proper error handling
- Shows progress and results
Alternative: Direct Azure CLI (still supported):
az containerapp update -n scimtool-prod -g scimtool-rg --image ghcr.io/kayasax/scimtool:0.2.0List revisions:
az containerapp revision list -n scimtool-prod -g scimtool-rg --query "[].{rev:name,img:properties.template.containers[0].image,active:active}" -o tableRoll back by updating image to the prior version tag:
az containerapp update -n scimtool-prod -g scimtool-rg --image scimtoolpublic.azurecr.io/scimtool:0.1.0| Scenario | Action |
|---|---|
| Quick internal build, no public announcement | Tag only (optional) |
| Public / visible upgrade | Git tag + GitHub Release |
| Hotfix | Increment PATCH (0.2.1) |
| Feature batch | Increment MINOR (0.3.0) |
| Breaking API / contract | Increment MAJOR (1.0.0) |
| Issue | Cause | Fix |
|---|---|---|
| Banner never updates | No Release and no new tag | Push new git tag or create Release |
| Wrong image version deployed | Forgot to bump package.json | Bump version, rebuild, redeploy |
| Remote ACR build fails | Unicode log + large context | Use local build path |
| 404 from releases API | No Releases exist | Expected; fallback to tags active |
| Anonymous pull fails | Registry not public yet | Run: az acr update -n scimtoolpublic --anonymous-pull-enabled |
docker run --rm -p 8080:80 ghcr.io/kayasax/scimtool:0.2.0
# Then: curl http://localhost:8080/scim/admin/version (with header if auth required)Potential GitHub Actions workflow:
- Trigger on tag push
v*. - Install Azure CLI (& login via OIDC to Azure).
- Run
publish-acr.ps1with-Registry/-ResourceGroup. - Optionally auto update Container App (or open a PR / create a deployment job).
- Avoid embedding secrets in image; use env vars / Azure secrets.
- SQLite inside image is ephemeral; move to external persistence before multi-instance scaling.
- Consider scanning image (
az acr repository show-manifests+ Defender or Docker Scout) for vulnerabilities.
# Version bump
git add api/package.json; git commit -m "chore: bump version"; git push
# Tag
git tag -a v0.2.0 -m "v0.2.0"; git push origin v0.2.0
# Build & push
pwsh ./scripts/publish-acr.ps1 -Registry scimtoolpublic -ResourceGroup scimtool-rg -Latest
# Deploy
az containerapp update -n scimtool-prod -g scimtool-rg --image ghcr.io/kayasax/scimtool:0.2.0
# Verify
az containerapp logs show -n scimtool-prod -g scimtool-rg --tail 50
Invoke-RestMethod -Headers @{ Authorization = 'Bearer S@g@r2011' } -Uri https://<FQDN>/scim/admin/version Code edit → Local test → Bump version → Commit → (Tag + Release) → Publish image → Update Container App → Verify logs/version → Banner prompts consumers
Rebuild any time you change:
- Backend TypeScript
- Frontend React code
- Prisma schema (requires
prisma generatebaked in build stage) - Dependencies or Node version
publish-acr.ps1auto-detects version fromapi/package.json– override with-Tagonly for exceptional cases.- The Docker build is multi-stage: web → api → runtime. The final image is minimal (production deps only).
- Healthcheck is a simple HTTP GET to
/health(add route implementation if not already present for accurate status).
Feel free to extend this doc when you formalize Releases or introduce CI automation.