[!NOTE]
Changes to the implementation made on December 18th 2023
Summary
Why NuGet?
Creating a Business Central specific package format, a package manager, integrating this in GitHub Packages and Azure Artifacts and potentially building a public feed for BC packages seems like overkill. Cheapest and best approach would be to find a suitable package format.
Even though Universal packages (from a technology standpoint) seems like the right choice, we should not settle on a format, which isn't natively supported by GitHub packages. Maven is mostly used for Java and doesn't seem like the right format.
npm is for node.js modules and NuGet is for dotnet packages, both formats could be used, but NuGet seems to be the easiest to work with wrt simplicity (just a .zip file) and access (public API for NuGet feed servers)
Must contain id, version, title, description and authors.
For GitHub, repository should point to the owning repository of the package.
The default naming of nuget packages is Publisher.Name.AppId (where publisher and name are normalized - i.e. spaces, dots and special characters are removed, dashes are kept.)
Dependencies includes all dependencies (including Application dependency and Platform dependency)
Dependency resolution is done on the AppId only (if the package/dependency name ends with a GUID - considered to be the appid) - if the name does not end with an AppId, then the full name is used for dependency resolution)
Referencing a BcNuGet Package in your project
In app.json you include a reference to the app on which you have a dependency, like:
Patterns specifies which package patterns are considered in the corresponding feed. This can be the full name of a package, a registered prefix (like microsoft.*), but please note that anybody can publish malicious packages to f.ex. nuget.org, so please only trust registered prefixes or only signed packages.
Fingerprints specifies that you only want to consider packages, which are signed with any of the fingerprints in the array. Note that NuGet.org signs all packages with a repository signature. That one should not be trusted - you should trust only author signatures.
If no AuthTokenSecret specified, the nuget feed is considered public.
If a downloaded package contains dependencies to other NuGet packages, these are downloaded from the same nuget feed or other trusted nuget feeds.
NOTE that All trusted feeds are searched for a dependency to be resolved. If
Microsoft is also planning on creating a public NuGet feed containing NuGet packages for symbols for AppSource apps., This NuGet feed will automatically be trusted by BcContainerHelper.
Generation of NuGet packages
AL-Go for GitHub will have support for generating, delivering and updating NuGet packages with the content of a repository.
Main part of the functionality will reside in BcContainerHelper and can be used in other DevOps solutions as well.
Downloading NuGet packages
BcContainerHelper will have functionality for downloading BcNuGet packages, which will be used by AL-Go. This function will among other things have a parameter specifying which apps are already installed / existing. Apps in this collection will NOT be downloaded.
Try it out
Run Update AL-Go System Files with freddydk/AL-Go@nuget to try out the latest version of this.
Summary
Why NuGet?
Creating a Business Central specific package format, a package manager, integrating this in GitHub Packages and Azure Artifacts and potentially building a public feed for BC packages seems like overkill. Cheapest and best approach would be to find a suitable package format.
Azure Artifacts supports NuGet, Maven, npm, Gradle and Universal Packages. GitHub packages supports NuGet, Maven, npm, pip and RubyGems Nuget.org obviously supports NuGet
Even though Universal packages (from a technology standpoint) seems like the right choice, we should not settle on a format, which isn't natively supported by GitHub packages. Maven is mostly used for Java and doesn't seem like the right format.
npm is for node.js modules and NuGet is for dotnet packages, both formats could be used, but NuGet seems to be the easiest to work with wrt simplicity (just a .zip file) and access (public API for NuGet feed servers)
NuGet package format
The NuGet package format is described here: https://learn.microsoft.com/en-us/nuget/reference/nuspec
BcNuGet package format
A BcNuGet package contains exactly one .app file (or a runtime package)
A normal BcNuGet package is formattet like:
Sample manifest.nuspec:
Must contain id, version, title, description and authors. For GitHub, repository should point to the owning repository of the package.
The default naming of nuget packages is Publisher.Name.AppId (where publisher and name are normalized - i.e. spaces, dots and special characters are removed, dashes are kept.)
Dependencies includes all dependencies (including Application dependency and Platform dependency)
Dependency resolution is done on the AppId only (if the package/dependency name ends with a GUID - considered to be the appid) - if the name does not end with an AppId, then the full name is used for dependency resolution)
Referencing a BcNuGet Package in your project
In app.json you include a reference to the app on which you have a dependency, like:
In your AL-Go repository settings you specify a list of trusted NuGet feeds like:
Patterns specifies which package patterns are considered in the corresponding feed. This can be the full name of a package, a registered prefix (like microsoft.*), but please note that anybody can publish malicious packages to f.ex. nuget.org, so please only trust registered prefixes or only signed packages.
Fingerprints specifies that you only want to consider packages, which are signed with any of the fingerprints in the array. Note that NuGet.org signs all packages with a repository signature. That one should not be trusted - you should trust only author signatures.
If no AuthTokenSecret specified, the nuget feed is considered public.
If a downloaded package contains dependencies to other NuGet packages, these are downloaded from the same nuget feed or other trusted nuget feeds.
NOTE that All trusted feeds are searched for a dependency to be resolved. If
Versioning
NuGet package versioning will have the same version as the app contained. NuGet package versioning and dependency versioning follows this schema: https://learn.microsoft.com/en-us/nuget/concepts/package-versioning
BcContainerHelper does support pre-release packages - this support will be added to AL-Go for GitHub as well.
A Public feed for Microsoft apps
Microsoft is planning on creating a public NuGet feed for all Microsoft apps. This NuGet feed will automatically be trusted by BcContainerHelper. A Proof-Of-Concept implementation of this feed can be found here: https://pkgs.dev.azure.com/freddydk/apps/_packaging/MyApps/nuget/v3/index.json
A Public feed for AppSource app symbols
Microsoft is also planning on creating a public NuGet feed containing NuGet packages for symbols for AppSource apps., This NuGet feed will automatically be trusted by BcContainerHelper.
Generation of NuGet packages
AL-Go for GitHub will have support for generating, delivering and updating NuGet packages with the content of a repository. Main part of the functionality will reside in BcContainerHelper and can be used in other DevOps solutions as well.
Downloading NuGet packages
BcContainerHelper will have functionality for downloading BcNuGet packages, which will be used by AL-Go. This function will among other things have a parameter specifying which apps are already installed / existing. Apps in this collection will NOT be downloaded.
Try it out
Run Update AL-Go System Files with freddydk/AL-Go@nuget to try out the latest version of this.