Add dataverse Copilot skills#10
Conversation
Add two GitHub Copilot prompt files for Power Apps Full Code Apps development: - codeapp-dataverse-query: Scaffolds typed Dataverse data hooks using generated services from the @microsoft/power-apps SDK (34 rules covering pagination, null filters, OptionSet values, lookup resolution, parameterized hooks, etc.) - codeapp-deploy: Build, validate, and deploy workflow with pre-flight checks, bundle size validation, and structured status reporting (14 rules + 7 safety constraints) Both follow the existing opsx-* prompt file conventions and include SKILL.md metadata files matching the openspec schema.
There was a problem hiding this comment.
Pull request overview
This PR adds two new GitHub template “skills” for Power Apps Code Apps: one to scaffold typed Dataverse query hooks using generated services, and one to build/validate/deploy Code Apps via the @microsoft/power-apps CLI. It extends the existing templates/github/{skills,prompts} system with new SKILL metadata + prompt playbooks.
Changes:
- Added
codeapp-deployskill metadata and a deployment prompt with pre-flight checks, build gating, and controlled retry/confirmation behavior. - Added
codeapp-dataverse-queryskill metadata and a hook-generation prompt with guidance for sanitization, pagination caps, and throttling handling. - Linked the two skills to form a “query then deploy” workflow.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| templates/github/skills/codeapp-deploy/SKILL.md | New skill metadata/README for Code App deployment, including usage and related-skill linkage. |
| templates/github/skills/codeapp-dataverse-query/SKILL.md | New skill metadata/README for scaffolding typed Dataverse query hooks via generated services. |
| templates/github/prompts/codeapp-deploy.prompt.md | New deployment prompt defining phased validation/build/deploy/report rules and safety constraints. |
| templates/github/prompts/codeapp-dataverse-query.prompt.md | New Dataverse hook generator prompt defining service-only access patterns, sanitization, pagination, and retry behavior. |
Comments suppressed due to low confidence (6)
templates/github/skills/codeapp-deploy/SKILL.md:10
metadata.generatedByis inconsistent with the rest of the skill templates in this repo (most existing skills usegeneratedBy: "1.3.1", e.g.templates/github/skills/openspec-explore/SKILL.md:9). IfgeneratedByis meant to reflect the generator version, update it here to match the current template set (or document why this skill differs).
metadata:
author: powerplatform-skills
version: "1.0"
generatedBy: "1.0.0"
---
templates/github/skills/codeapp-deploy/SKILL.md:46
- Skill invocation examples use a
--environmentflag, but the prompt's Input section describes the post-command argument as a positional environment identifier. Align the public interface so users don’t have to guess whether to call/codeapp:deploy <env>vs/codeapp:deploy --environment <env>.
**Usage**:
/codeapp:deploy
/codeapp:deploy --environment https://org123.crm.dynamics.com
templates/github/skills/codeapp-dataverse-query/SKILL.md:10
metadata.generatedByis inconsistent with the rest of the skill templates in this repo (most existing skills usegeneratedBy: "1.3.1", e.g.templates/github/skills/openspec-explore/SKILL.md:9). If this field is used for auditing or tooling, update it here to match the current generator version (or document the divergence).
metadata:
author: powerplatform-skills
version: "1.0"
generatedBy: "1.0.0"
---
templates/github/prompts/codeapp-deploy.prompt.md:85
- The build output validation and size checks use POSIX-only shell commands (
test,du). If this skill is intended to work for Windows users too, add PowerShell equivalents or use a cross-platform Node script approach; otherwise, explicitly state that these steps assume a Unix-like shell (Codespaces/Linux runner).
8. **Validate build output**:
```bash
test -d dist && test -f dist/index.html
- If missing → stop. Build produced no output.
- Check bundle size:
du -sh dist/
- If > 30 MB → warn: "Bundle exceeds the ~30 MB Code Apps upload limit. Consider code-splitting, removing unused dependencies, or optimizing assets."
**templates/github/prompts/codeapp-dataverse-query.prompt.md:97**
* The 429 retry snippet increments `retryCount` but never resets it after a successful request/page. This can cause later pages to stop retrying early (or break) due to retries consumed by previous pages. Make retry counting scoped per request/page, or reset `retryCount` on success.
```typescript
const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
let retryCount = 0;
// Inside pagination or retry logic:
if (result.error?.message?.includes('Rate limit') || result.error?.message?.includes('429')) {
const backoff = Math.min(2000 * Math.pow(2, retryCount), 8000);
await delay(backoff);
retryCount++;
if (retryCount >= 3) break; // Max 3 retries
continue; // Retry the same page
}
```
Maximum 3 retries with exponential backoff (2s, 4s, 8s), then stop and return partial data with a warning.
**templates/github/prompts/codeapp-dataverse-query.prompt.md:207**
* The AbortController example calls `controller.abort()`, but the controller’s `signal` is never passed into `ContactsService.getAll(...)`. As written, this does not abort the underlying request—only prevents state updates after completion. Either pass the signal if the generated services support it, or reword the guidance/comments to reflect “ignore stale responses” rather than “abort request”.
// Abort previous in-flight request
abortRef.current?.abort();
const controller = new AbortController();
abortRef.current = controller;
const load = async () => {
setLoading(true);
setError(null);
try {
const result = await ContactsService.getAll({
select: ['contactid', 'fullname', 'emailaddress1'],
filter: `statecode eq 0 and contains(fullname,'${sanitize(searchTerm)}')`,
top: 50,
});
if (controller.signal.aborted) return; // Stale response
if (result.data) {
</details>
---
💡 <a href="/voyager163/codespec/new/develop?filename=.github/instructions/*.instructions.md" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Add Copilot custom instructions</a> for smarter, more guided reviews. <a href="https://docs.github.com/en/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Learn how to get started</a>.
| name: codeapp-deploy | ||
| description: Build, validate, and deploy a Power Apps Code App using npx power-apps push. | ||
| license: MIT | ||
| compatibility: Requires @microsoft/power-apps SDK. |
| description: Scaffold a typed Dataverse data hook using generated services from @microsoft/power-apps SDK. | ||
| license: MIT | ||
| compatibility: Requires @microsoft/power-apps SDK and generated services. |
| let allRecords: T[] = []; | ||
| let skipToken: string | undefined; | ||
| let pageCount = 0; | ||
| do { | ||
| const result = await Service.getAll({ select: [...], maxPageSize: 500, skipToken }); | ||
| if (result.data) allRecords = [...allRecords, ...result.data]; | ||
| skipToken = result.skipToken; | ||
| pageCount++; | ||
| if (pageCount >= MAX_PAGES) { | ||
| console.warn(`Pagination capped at ${MAX_PAGES} pages (${allRecords.length} records). Refine your filter.`); | ||
| break; |
| # Power Apps Code App Deployment | ||
|
|
||
| **Input**: The argument after `/codeapp:deploy` is optional. It can be an environment identifier or left blank to use the environment from `power.config.json`. | ||
|
|
||
| ## Persona |
voyager163
left a comment
There was a problem hiding this comment.
Lets test it out in develop branch
Adds Dataverse Copilot skills for Power Apps Code Apps (prompts + SKILL metadata). Source of truth in templates/github; .github contains symlinked discovery entries. Includes dataverse-query (sanitization, pagination cap, 429 handling, AbortController) and deploy (pre-flight, build checks, safe push). Ready for review against develop.