{"kind":"AgentDefinition","metadata":{"namespace":"community","name":"pcf-alm","version":"0.1.0"},"spec":{"agents_md":"---\ndescription: 'Application lifecycle management (ALM) for PCF code components'\napplyTo: '**/*.{ts,tsx,js,json,xml,pcfproj,csproj,sln}'\n---\n\n# Code Components Application Lifecycle Management (ALM)\n\nALM is a term used to describe the lifecycle management of software applications, which includes development, maintenance, and governance. More information: [Application lifecycle management (ALM) with Microsoft Power Platform](https://learn.microsoft.com/en-us/power-platform/alm/overview-alm).\n\nThis article describes considerations and strategies for working with specific aspects of lifecycle management from the perspective of code components in Microsoft Dataverse:\n\n1. Development and debugging ALM considerations\n2. Code component solution strategies\n3. Versioning and deploying updates\n4. Canvas apps ALM considerations\n\n## Development and Debugging ALM Considerations\n\nWhen developing code components, you would follow the steps below:\n\n1. Create code component project (`pcfproj`) from a template using `pac pcf init`. More information: [Create and build a code component](https://learn.microsoft.com/en-us/power-apps/developer/component-framework/create-custom-controls-using-pcf).\n2. Implement code component logic. More information: [Component implementation](https://learn.microsoft.com/en-us/power-apps/developer/component-framework/custom-controls-overview#component-implementation).\n3. Debug the code component using the local test harness. More information: [Debug code components](https://learn.microsoft.com/en-us/power-apps/developer/component-framework/debugging-custom-controls).\n4. Create a solution project (`cdsproj`) and add the code component project as a reference. More information: [Package a code component](https://learn.microsoft.com/en-us/power-apps/developer/component-framework/import-custom-controls).\n5. Build the code component in release mode for distribution and deployment.\n\n### Two Deployment Methods to Dataverse\n\nWhen your code component is ready for testing inside a model-driven app, canvas app, or portal:\n\n1. **`pac pcf push`**: This deploys a single code component at a time to a solution specified by the `--solution-unique-name` parameter, or a temporary PowerAppsTools solution when no solution is specified.\n\n2. **Using `pac solution init` and `msbuild`**: Build a `cdsproj` solution project that has references to one or more code components. Each code component is added to the `cdsproj` using `pac solution add-reference`. A solution project can contain references to multiple code components, whereas code component projects may only contain a single code component.\n\nThe following diagram shows the one-to-many relationship between `cdsproj` and `pcfproj` projects:\n\n![One-to-many relationship between cdsproj and pcfproj projects](https://learn.microsoft.com/en-us/power-apps/developer/component-framework/media/code-component-projects.png)\n\nMore information: [Package a code component](https://learn.microsoft.com/en-us/power-apps/developer/component-framework/import-custom-controls#package-a-code-component).\n\n## Building pcfproj Code Component Projects\n\nWhen building `pcfproj` projects, the generated JavaScript depends on the command used to build and the `PcfBuildMode` in the `pcfproj` file.\n\nYou don't normally deploy a code component into Microsoft Dataverse that has been built in development mode since it's often too large to import and may result in slower runtime performance. More information: [Debugging after deploying into Microsoft Dataverse](https://learn.microsoft.com/en-us/power-apps/developer/component-framework/debugging-custom-controls#debugging-after-deploying-into-microsoft-dataverse).\n\nFor `pac pcf push` to result in a release build, the `PcfBuildMode` is set inside the `pcfproj` by adding a new element under the `OutputPath` element:\n\n```xml\n\u003cPropertyGroup\u003e\n   \u003cName\u003emy-control\u003c/Name\u003e\n   \u003cProjectGuid\u003e6aaf0d27-ec8b-471e-9ed4-7b3bbc35bbab\u003c/ProjectGuid\u003e\n   \u003cOutputPath\u003e$(MSBuildThisFileDirectory)out\\controls\u003c/OutputPath\u003e\n   \u003cPcfBuildMode\u003eproduction\u003c/PcfBuildMode\u003e\n\u003c/PropertyGroup\u003e\n```\n\n### Build Commands\n\n| Command | Default Behavior | With PcfBuildMode=production |\n|---------|-----------------|------------------------------|\n| npm start watch | Always development |   |\n| pac pcf push | Development build | Release build |\n| npm run build | Development build | `npm run build -- --buildMode production` |\n\nMore information: [Package a code component](https://learn.microsoft.com/en-us/power-apps/developer/component-framework/import-custom-controls#package-a-code-component).\n\n## Building .cdsproj Solution Projects\n\nWhen building a solution project (`.cdsproj`), you have the option to generate the output as a managed or unmanaged solution. Managed solutions are used to deploy to any environment that isn't a development environment for that solution. This includes test, UAT, SIT, and production environments. More information: [Managed and unmanaged solutions](https://learn.microsoft.com/en-us/power-platform/alm/solution-concepts-alm#managed-and-unmanaged-solutions).\n\nThe `SolutionPackagerType` is included in the `.cdsproj` file created by `pac solution init`, but initially commented out. Uncomment the section and set to Managed, Unmanaged, or Both.\n\n```xml\n\u003c!-- Solution Packager overrides, un-comment to use: SolutionPackagerType (Managed, Unmanaged, Both) --\u003e\n\u003cPropertyGroup\u003e\n   \u003cSolutionPackageType\u003eManaged\u003c/SolutionPackageType\u003e\n\u003c/PropertyGroup\u003e\n```\n\n### Build Configuration Results\n\n| Command | SolutionPackageType | Result |\n|---------|-------------------|---------|\n| msbuild | Managed | Development build inside Managed Solution |\n| msbuild /p:configuration=Release | Managed | Release build inside Managed Solution |\n| msbuild | Unmanaged | Development build inside Unmanaged Solution |\n| msbuild /p:configuration=Release | Unmanaged | Release build inside Unmanaged Solution |\n\nMore information: [Package a code component](https://learn.microsoft.com/en-us/power-apps/developer/component-framework/import-custom-controls#package-a-code-component).\n\n## Source Code Control with Code Components\n\nWhen developing code components, it's recommended that you use a source code control provider such as Azure DevOps or GitHub. When committing changes using git source control, the `.gitignore` file provided by the `pac pcf init` template will ensure that some files are not added to the source control because they're either restored by `npm` or are generated as part of the build process:\n\n```\n# dependencies\n/node_modules\n\n# generated directory\n**/generated\n\n# output directory\n/out\n\n# msbuild output directories\n/bin\n/obj\n```\n\nSince the `/out` folder is excluded, the resulting `bundle.js` file (and related resources) built will not be added to the source control. When your code components are built manually or as part of an automated build pipeline, the `bundle.js` would be built using the latest code to ensure that all changes are included.\n\nAdditionally, when a solution is built, any association solution zip files would not be committed to the source control. Instead, the output would be published as binary release artifacts.\n\n## Using SolutionPackager with Code Components\n\nIn addition to source controlling the `pcfproj` and `cdsproj`, [SolutionPackager](https://learn.microsoft.com/en-us/power-platform/alm/solution-packager-tool) may be used to incrementally unpack a solution into its respective parts as a series of XML files that can be committed into source control. This has the advantage of creating a complete picture of your metadata in the human-readable format so you can track changes using pull requests or similar.\n\n\u003e **Note**: At this time, SolutionPackager differs from using `pac solution clone` in that it can be used incrementally to export changes from a Dataverse solution.\n\n### Example Solution Structure\n\nOnce a solution that contains a code component is unpacked using `SolutionPackager /action: Extract`, it will look similar to:\n\n```\n.\n├── Controls\n│   └── prefix_namespace.ControlName\n│       ├── bundle.js *\n│       └── css\n│          └── ControlName.css *\n│       ├── ControlManifest.xml *\n│       └── ControlManifest.xml.data.xml\n├── Entities\n│   └── Contact\n│       ├── FormXml\n│       │   └── main\n│       │       └── {3d60f361-84c5-eb11-bacc-000d3a9d0f1d}.xml\n│       ├── Entity.xml\n│       └── RibbonDiff.xml\n└── Other\n    ├── Customizations.xml\n    └── Solution.xml\n```\n\nUnder the `Controls` folder, you can see there are subfolders for each code component included in the solution. When committing this folder structure to the source control, you would exclude the files marked with an asterisk (*) above, because they will be output when the `pcfproj` project is built for the corresponding component.\n\nThe only files that are required are the `*.data.xml` files since they contain metadata that describes the resources required by the packaging process.\n\nMore information: [SolutionPackager command-line arguments](https://learn.microsoft.com/en-us/power-platform/alm/solution-packager-tool#solutionpackager-command-line-arguments).\n\n## Code Component Solution Strategies\n\nCode components are deployed to downstream environments using Dataverse solutions. There are two strategies for deploying code components inside solutions:\n\n### 1. Segmented Solutions\n\nA solution project is created using `pac solution init` and then using `pac solution add-reference` to add one or more code components. This solution can then be exported and imported into downstream environments and other segmented solutions will take a dependency on the code component solution such that it must be deployed into that environment first.\n\n**Reasons for adopting segmented solution approach:**\n\n1. **Versioning lifecycle** - You want to develop, deploy, and version-control your code components on a separate lifecycle to the other parts of your solution. This is common in 'fusion team' scenarios where code components built by developers are being consumed by app makers.\n\n2. **Shared use** - You want to share your code components between multiple environments and therefore don't want to couple your code components with any other solution components. This could be if you're an ISV or developing a code component for use by different parts of your organization.\n\n### 2. Single Solution\n\nA single solution is created inside a Dataverse environment and then code components are added along with other solution components (such as tables, model-driven apps, or canvas apps) that in turn reference those code components. This solution can be exported and imported into downstream environments without any inter-solution dependencies.\n\n### Solution Lifecycle Overview\n\n![Solution Strategies](https://learn.microsoft.com/en-us/power-apps/developer/component-framework/media/solution-strategies.png)\n\nMore information: [Package and distribute extensions using solutions](https://learn.microsoft.com/en-us/powerapps/developer/data-platform/introduction-solutions).\n\n## Code Components and Automated Build Pipelines\n\nIn addition to manually building and deploying your code component solutions, you can also build and package your code components using automated build pipelines.\n\n- If you're using Azure DevOps, you can use the [Microsoft Power Platform Build Tool for Azure DevOps](https://learn.microsoft.com/en-us/power-platform/alm/devops-build-tools).\n- If you're using GitHub, you can use the [Power Platform GitHub Actions](https://learn.microsoft.com/en-us/power-platform/alm/devops-github-actions).\n\n### Advantages of Automated Build Pipelines\n\n- **Time-efficient** - Removing the manual tasks makes building and packaging quicker\n- **Repeatable** - Performed the same every time, not dependent on the team member\n- **Versioning consistency** - Automatic versioning relative to previous versions\n- **Maintainable** - Everything needed to build is contained in source control\n\n## Versioning and Deploying Updates\n\nWhen deploying and updating your code components, it's important to have a consistent versioning strategy. A common versioning strategy is [semantic versioning](https://semver.org/), which has the format: `MAJOR.MINOR.PATCH`.\n\n### Incrementing the PATCH Version\n\nThe `ControlManifest.Input.xml` stores the code component version in the control element:\n\n```xml\n\u003ccontrol namespace=\"...\" constructor=\"...\" version=\"1.0.0\" display-name-key=\"...\" description-key=\"...\" control-type=\"...\"\u003e\n```\n\nWhen deploying an update to a code component, the version in the `ControlManifest.Input.xml` must at minimum have its PATCH (the last part of the version) incremented for the change to be detected.\n\n**Commands to update version:**\n\n```bash\n# Advance the PATCH version by one\npac pcf version --strategy manifest\n\n# Specify an exact PATCH value (e.g., in automated build pipeline)\npac pcf version --patchversion \u003cPATCH VERSION\u003e\n```\n\n### When to Increment the MAJOR and MINOR Version\n\nIt's recommended that the MAJOR and MINOR version of the code component's version are kept in sync with the Dataverse solution that is distributed.\n\nA [Dataverse solution has four parts](https://learn.microsoft.com/en-us/powerapps/maker/data-platform/update-solutions#understanding-version-numbers-for-updates): `MAJOR.MINOR.BUILD.REVISION`.\n\n| Code Component | Dataverse Solution | Notes |\n|----------------|-------------------|--------|\n| MAJOR | MAJOR | Set using Pipeline Variable or last committed value |\n| MINOR | MINOR | Set using Pipeline Variable or last committed value |\n| PATCH | BUILD | $(Build.BuildId) |\n| --- | REVISION | $(Rev:r) |\n\n## Canvas Apps ALM Considerations\n\nConsuming code components in canvas apps is different from doing so in model-driven apps. Code components must be explicitly added to the app by selecting **Get more components** on the Insert panel. Once the code component is added to the canvas app, it's included as the content inside the app definition.\n\nTo update to a new version of the code component after it's deployed (and the control version incremented), the app maker must first open the app in Power Apps Studio and select **Update** when prompted on the Update code components dialog. The app must then be saved and published for the new version to be used when the app is played by users.\n\n![Update code components](https://learn.microsoft.com/en-us/power-apps/developer/component-framework/media/upgrade-code-component.png)\n\nIf the app is not updated or **Skip** is used, the app continues to use the older version of the code component, even though it doesn't exist in the environment since it's been overwritten by the newer version.\n\nSince the app contains a copy of the code component, it's therefore possible to have different versions of the code components running side by side in a single environment from inside different canvas apps. However, you cannot have different versions of a code component running side by side in the same app.\n\n\u003e **Note**: Although, at this time, you can import a canvas app without the matching code component being deployed to that environment, it's recommended that you always ensure apps are updated to use the latest version of the code components and that the same version is deployed to that environment first or as part of the same solution.\n\n## Related Articles\n\n- [Application lifecycle management (ALM) with Microsoft Power Platform](https://learn.microsoft.com/en-us/power-platform/alm/overview-alm)\n- [Power Apps component framework API reference](https://learn.microsoft.com/en-us/power-apps/developer/component-framework/reference/)\n- [Create your first component](https://learn.microsoft.com/en-us/power-apps/developer/component-framework/implementing-controls-using-typescript)\n- [Debug code components](https://learn.microsoft.com/en-us/power-apps/developer/component-framework/debugging-custom-controls)\n","description":"Application lifecycle management (ALM) for PCF code components","import":{"commit_sha":"541b7819d8c3545c6df122491af4fa1eae415779","imported_at":"2026-05-18T20:05:35Z","license_text":"MIT License\n\nCopyright GitHub, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.","owner":"github","repo":"github/awesome-copilot","source_url":"https://github.com/github/awesome-copilot/blob/541b7819d8c3545c6df122491af4fa1eae415779/instructions/pcf-alm.instructions.md"},"manifest":{}},"content_hash":[120,163,246,15,159,225,245,54,218,235,151,55,80,37,236,238,116,82,50,223,5,230,51,30,217,4,120,114,185,147,81,223],"trust_level":"unsigned","yanked":false}
