Deploy
Skill microsoft/power-platform-skills/plugins/mobile-apps/skills/deploy
Use when the user wants to deploy / publish / push a Power Apps mobile app to a Power Platform tenant so others can run it.From its SKILL.md
npx -y skills add microsoft/power-platform-skills --skill deployAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
SKILL.md
9.5 KB, ~2.3k tokens by cl100k_base, as published. Nobody here has run it
π Shared instructions: shared-instructions.md β read first.
Deploy
Builds the mobile app in the current directory and pushes it to the Power Platform environment recorded in power.config.json.
This skill uses the standard 4-step deployment flow for this plugin: check memory bank, build, deploy, then update memory bank.
Out of scope (deliberately)
expo run:ios/expo run:androidβ local native compile is the user's choice; run your platform-specific native command directly when ready.- OTA updates and store distribution β out of scope for v0.
- Starting Metro for local dev β run
npm run dev(=expo start) directly.
Workflow
- Check memory bank β 2. Build β 2.5 Offline profile coverage gate β 3. Deploy β 4. Update memory bank
Step 1 β Check memory bank
Read memory-bank.md from the project root if present. Capture:
- Project name
- Environment (id + display name)
- Current version
If absent, continue β the project may have been created without the plugin. Re-derive env from power.config.json if needed.
Step 2 β Build
Print before starting:
"β Building production web bundle via
npm run build(=expo export --platform web). ~30β90 seconds."
First regenerate connectorSchemas.ts so app/_layout.tsx's schemaMap import reflects every connector currently in .power/schemas/. The npm prestart/preandroid/preios hooks cover dev runs, but npm run build does not β if a connector was added since the last npm run dev, the bundled JS would ship a stale schema map. Always regenerate before build:
npm run generate-schemas
npm run build
If package.json has no build script, fall back to:
npx expo export --platform web
(That's what the upstream template's build script runs.)
If the build fails:
TS6133(unused import) β remove the import and retry once.- Other TypeScript errors β report file + line and STOP. Don't deploy a broken build.
- Metro bundler errors β surface the full stack and STOP.
Verify dist/ exists with index.html before continuing.
Step 2.5 β Offline profile coverage gate
This is the final chance to catch schema that never made it into the Mobile Offline Profile before it ships β a table added to the data model but not the profile never syncs to devices, and a new column arrives blank offline. Validate that every schema change is covered before pushing.
Run the local, no-network delta check (.datamodel-manifest.json vs offline-profile.json):
node "${CLAUDE_SKILL_DIR}/../../scripts/offline-profile-delta.js"
Branch on the JSON status (full contract in offline-profile-reconciliation.md):
status | Action |
|---|---|
no-manifest | Connectors-only app β no Dataverse schema. Continue to Step 3 silently. |
no-profile | No offline profile in this project. Print one line: β· No offline profile β skipping offline coverage check. Run /setup-offline-profile if you want offline support. Continue to Step 3. |
in-sync | Print β Offline profile covers all schema changes. Continue to Step 3. |
error | offline-profile.json is unreadable β the script prints status: error and exits non-zero. Offline coverage can't be validated against a corrupt file, so STOP before pushing: surface the error string and have the user fix offline-profile.json and re-run, or type the deploy without offline override (below) to push anyway. |
delta | STOP before pushing. See below. |
On delta β print the uncovered schema, then gate with AskUserQuestion:
β The offline profile is missing schema changes. If you deploy now, these won't be
available on disconnected devices:
Tables not in the profile : <missingTables[].logicalName>
Tables with new columns : <tablesWithNewColumns[].logicalName (newColumns)>
Options:
- Update the offline profile now (recommended) β invoke
/add-table-to-offline-profilefor eachmissingTables[]entry (or once with--all-new) and/edit-offline-profile --table <t> --columns add:<newColumns>for eachtablesWithNewColumns[]entry, following the ordering in the reconciliation reference. Then re-run the delta check; when it reportsin-sync, continue to Step 3. - Deploy anyway β requires an explicit override. Wait for the exact phrase
deploy without offline(case-insensitive); a barey/yesis not enough, mirroring the environment-mismatch gate in Step 3. Then continue to Step 3 and note the skipped reconciliation in the Step 4 build-history row.
Do not push until the gate is resolved (reconciled to in-sync, or explicitly overridden).
Step 3 β Deploy
Resolve and confirm the target environment FIRST. npx power-apps push deploys to the environment configured in power.config.json. Resolve that ID to a Dataverse URL so the user catches drift before pushing.
Run:
ENV_ID=$(node -e "console.log(require('./power.config.json').environmentId)")
node "${CLAUDE_SKILL_DIR}/../../scripts/resolve-environment.js" "$ENV_ID"
From resolve-environment.js capture the Environment URL (e.g. https://contoso.crm.dynamics.com/), Environment ID, and Tenant ID. Cross-check against memory-bank.md / power.config.json:
- Match β proceed to the confirmation prompt below.
- Mismatch β STOP. Surface both values side-by-side and ask the user to either (a) update
power.config.jsonby re-running init in the intended app root, or (b) explicitly typeoverrideto push to the environment already recorded inpower.config.json. Do not proceed on a barey. - Cannot resolve/authenticate β STOP with
az login --tenant <env-tenant>instructions, or ask the user to provide the environment URL directly.
Print before starting:
"β Pushing bundle to Power Platform via
npx power-apps push. ~30β60 seconds."
Confirm with the user using the resolved env URL, not just the friendly name:
"Ready to deploy to <env-name> (
<env-url>)? This will update the live app for every user in that environment. Typeyes deploy to <env-name>to confirm."
Wait for the exact phrase yes deploy to <env-name> (case-insensitive, env-name matching). A bare y / yes is not enough β too easy to fire on autopilot when the wrong env is active. Then:
npx power-apps push --non-interactive
Capture the app URL from the output if printed.
If deploy fails, report the error and STOP β do not retry silently. Common fixes:
| Error | Fix |
|---|---|
npx power-apps push auth error, wrong user, or multiple accounts | Follow shared-instructions command-failure handling. az login / az account set does not switch the standalone Power Apps CLI account. |
| Environment mismatch | Re-run npx power-apps init -t MobileApp --display-name <name> --environment-id <id> --non-interactive in a fresh/app root for the intended target |
npx power-apps push not recognised | Run npm install in the project so @microsoft/power-apps provides the CLI, or install @microsoft/power-apps-cli only as a last-resort prerequisite after user confirmation. |
Step 4 β Update memory bank
If memory-bank.md exists, increment the version (v1.0.0 β v1.1.0) and update:
- Current version
- Last deployed timestamp
- App URL (if captured)
- Append a row to the Build history section:
| v1.1.0 | <timestamp> | deploy | success |
Print the summary card:
β
Deploy β <project-name>
βββββββββββββββββββββββββββββββββββββββββββββ
Version : <new-version>
Environment : <env-name>
App URL : <url or "see make.powerapps.com">
Bundle path : dist/
Local dev: npm run dev (= expo start, QR for native dev clients)
Re-deploy: /deploy
List conns: /list-connections
βββββββββββββββββββββββββββββββββββββββββββββ
Local dev (out of scope for this skill β for reference only)
When the user wants to iterate locally, they run directly:
npm run dev # = expo start β Metro + QR for native dev clients
This launches Metro and prints a QR code. They can:
- Scan the QR with the installed native dev client
- Press
rto reload,jto open the debugger,mfor the dev menu
Runtime debugging for this plugin uses /debug-app with native dev-client sessions and Metro terminal logs. Do not use React Native Web, browser automation, direct Metro/localhost HTTP probes, or screen-by-screen runtime checks.
If they want to compile a native binary locally, they run the platform-specific native command directly. Local native compile and manual device testing are user-owned and are not deployment gates for this skill.
Reference
shared/version-check.mdβ min versions (only Always-required tier matters here)shared/memory-bank.mdβ Build history schemashared/references/offline-profile-reconciliation.mdβ Step 2.5 offline coverage gate
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.