Deployment Guide
This document covers the complete build and deployment pipeline for Foundation/Lens, including environment management and recovery procedures.
Prerequisites
Section titled “Prerequisites”| Requirement | Version | Notes |
|---|---|---|
| Node.js | 22.x | Forge runtime target (nodejs22.x in manifest) |
| Forge CLI | Latest | npm install -g @forge/cli |
| Atlassian developer account | — | Must have access to the app at ari:cloud:ecosystem::app/650bca70-387f-4693-96fc-d85cd80a344f |
| npm | 8+ | Bundled with Node.js |
Verify your Forge CLI is authenticated:
cd foundation && forge whoamiIf not authenticated, log in:
forge loginPackage Structure
Section titled “Package Structure”The project has four npm packages, each with their own node_modules:
foundation/ # Backend (Forge resolvers, services, actions) package.json .npmrc # legacy-peer-deps=true static/main/ # Main UI (AG Grid, toolbar, panels) package.json .npmrc # legacy-peer-deps=true static/issue-context/ # Issue Context panel UI package.json .npmrc # legacy-peer-deps=true static/admin/ # Admin page UI package.json .npmrc # legacy-peer-deps=trueAll four .npmrc files set legacy-peer-deps=true. Never pass --legacy-peer-deps manually.
Build Pipeline
Section titled “Build Pipeline”1. Frontend Build
Section titled “1. Frontend Build”The deploy script builds all three frontend packages automatically when builds are stale. To build manually:
# Build all three frontend packagesbash foundation/scripts/build-static-resources.sh --deploy-target development
# Or build just the main UIcd foundation/static/main && npm run buildThe build script sets REACT_APP_FOUNDATION_DEPLOY_TARGET as an environment variable and writes a .foundation-deploy-target marker file into each build/ directory. The deploy script uses this marker to detect stale builds.
2. Deploy Hash
Section titled “2. Deploy Hash”A deploy hash is auto-generated before each deploy (scripts/generate-deploy-hash.js). This embeds a short git SHA into the build for version identification.
3. Manifest Check
Section titled “3. Manifest Check”Before deploying, the manifest guardrails script validates:
- Manifest YAML is valid
- Raw byte size is under the 23,500-byte CaaS budget (ECO-1310)
- Function count is under the 50-function limit
- All action references point to defined functions
- All module references point to defined resources
- All Rovo agent action references point to defined actions
cd foundation && npm run check:manifest4. Forge Deploy
Section titled “4. Forge Deploy”# Deploy to the working development environmentcd foundation && npm run deploy:dev
# Deploy to production (requires --confirm)cd foundation && npm run deploy:production
# Deploy using the wrapper script directlybash foundation/scripts/deploy.sh --environment dev-recoverybash foundation/scripts/deploy.sh --environment production --confirmThe deploy wrapper script (scripts/deploy.sh) performs these safety checks before deploying:
- Worktree detection — Blocks deployment if running from a git worktree
- Branch check — Production deploys must be from
main - Uncommitted changes warning — Warns if working tree is dirty
- Manifest guardrails — Runs
check-manifest-limits.js - Build freshness — Rebuilds frontend if builds are stale or missing
- Production confirmation — Requires
--confirmflag for production
Environment Management
Section titled “Environment Management”Current Environments
Section titled “Current Environments”| Environment | Status | Default | Notes |
|---|---|---|---|
dev-recovery | Working | Yes | Created after original development env became corrupted |
development | Corrupted | No | CaaS manifest release fails with INTERNAL_SERVER_ERROR 500 |
staging | Corrupted | No | Deploy failures |
production | Working | No | Live Marketplace app |
Creating a Fresh Environment
Section titled “Creating a Fresh Environment”When an environment becomes corrupted (persistent 500 errors during CaaS manifest release), create a new one:
cd foundation && forge environments create --environment dev-new --non-interactivecd foundation && forge deploy --environment dev-newcd foundation && forge settings set default-environment dev-newAfter switching the default environment, run a plain deploy to confirm:
cd foundation && forge deploySetting Environment Variables
Section titled “Setting Environment Variables”Use the setup script to configure required Forge environment variables:
# Interactive guide for all environmentsbash foundation/scripts/setup-env.sh
# Commands for a specific environmentbash foundation/scripts/setup-env.sh --environment dev-recoveryRequired variables:
| Variable | Sensitive | Purpose |
|---|---|---|
SENTRY_DSN | Yes (encrypted) | Error tracking DSN |
Set variables before the first deploy:
cd foundation && forge variables set SENTRY_DSN <value> --environment dev-recovery --encryptInstalling on a Jira Site
Section titled “Installing on a Jira Site”After deploying to an environment, install the app on your Jira Cloud site:
cd foundation && forge install --environment dev-recovery --site humanr.atlassian.net --product Jira --confirm-scopes --non-interactiveTo upgrade an existing installation after a new deploy:
cd foundation && forge install --environment dev-recovery --site humanr.atlassian.net --product Jira --upgrade --confirm-scopes --non-interactiveProduction Release
Section titled “Production Release”The full production release script handles verification, deployment, installation, and post-deploy validation:
cd foundation && npm run release:production:local# or directly:bash foundation/scripts/release-production.sh --confirmThis script:
- Runs
verify:quick(manifest + TypeScript + frontend builds) - Configures Forge CLI for non-interactive use
- Verifies Forge authentication
- Deploys to production via
deploy.sh --environment production --confirm - Installs or upgrades the Jira production site
- Verifies the deployment and installation are successful
The Verification Pipeline
Section titled “The Verification Pipeline”Every code change must follow this pipeline before being committed:
Step 1: Unit Tests
Section titled “Step 1: Unit Tests”# Backend testscd foundation && npm test
# Frontend testscd foundation/static/main && npm testStep 2: Quick Verification
Section titled “Step 2: Quick Verification”cd foundation && npm run verify:quickThis runs:
- Forge consumption guardrails (
check-consumption.js) - Manifest + TypeScript release readiness (
predeploy:check: manifest check +tsc --noEmit) - Frontend production builds (all three packages)
Step 3: Full Verification (Optional)
Section titled “Step 3: Full Verification (Optional)”cd foundation && npm run verify:localAdds to the quick pipeline:
- Backend Jest suite
- Main UI Jest suite
Step 4: Deploy
Section titled “Step 4: Deploy”cd foundation && npm run deploy:devStep 5: Visual Verification
Section titled “Step 5: Visual Verification”After deploying, refresh the Foundation tab in Jira Cloud and take a screenshot to verify:
- No crashes or blank screens
- Expected UI elements are visible
- Data renders correctly
The Foundation app runs in a Forge Custom UI cross-origin iframe. Browser-level screenshots can see inside the iframe.
Step 6: Functional Verification
Section titled “Step 6: Functional Verification”Interactive testing (clicking buttons, opening menus, filling forms) must be done manually by the user. The Forge iframe prevents automated click interactions from external tools.
Step 7: Commit
Section titled “Step 7: Commit”Only commit after all verification steps pass.
Forge Deploy Recovery
Section titled “Forge Deploy Recovery”Symptom: Repeated 500 Errors During CaaS Manifest Release
Section titled “Symptom: Repeated 500 Errors During CaaS Manifest Release”If forge deploy repeatedly fails only in one environment during the “Release CaaS manifest” step with INTERNAL_SERVER_ERROR 500:
- Do not assume the code is broken. The environment itself may be corrupted on Atlassian’s side.
- Test in another environment. Deploy to
stagingor a fresh environment to confirm. - Create a fresh environment if the corruption is confirmed:
cd foundation && forge environments create --environment dev-fresh --non-interactivecd foundation && forge deploy --environment dev-freshcd foundation && forge settings set default-environment dev-fresh- Do not delete the corrupted environment immediately. Keep it until the replacement is verified.
Symptom: Fresh Install Fails
Section titled “Symptom: Fresh Install Fails”The app broke at 45/45 action modules during fresh Jira installations. The fix was reducing to 44/44 actions. Current manifest has 35 actions with ~650 bytes of headroom.
If install fails:
- Check the manifest action count:
cd foundation && npm run check:manifest - Check if the manifest byte size exceeds the CaaS limit
- Try uninstalling from the Jira admin panel and reinstalling
Known Non-Blocking Warnings
Section titled “Known Non-Blocking Warnings”These warnings appear during lint/build but do not prevent deployment:
manifest.yml: deprecatedapp.namemanifest.yml: deprecatedpermissions.external.fetch.backendentriessrc/resolvers/inline-edit.ts: deprecatedstorageexport from@forge/api- CRA/Atlaskit source-map warnings in
static/issue-contextandstatic/admin - CRA/CssMinimizer
postcss-calcwarnings from@atlaskit/lozengeinstatic/main
Worktree Rules
Section titled “Worktree Rules”- Never deploy from a worktree. The deploy script blocks this automatically.
- Never run
forge tunnelfrom a worktree. - Worktrees are for isolated development. Merge or PR back to
mainfirst, then deploy from the main working tree. - After merging a PR, always
git pull origin mainin the main working tree to keep localmainin sync.