Symbol Packages
Since 0.5.9, the symbols commands produce the packages that Restore
consumes. They transform compiled apps into symbol-only apps, wrap them in NuGet packages,
and publish them to a feed or local folder. No Business Central container, server, or BC
credentials are required. These commands do not deploy apps into Business Central.
compiled .app -> symbols create -> symbol-only .app -> symbols pack -> .nupkg
|
symbols push
|
NuGet feed
|
alwasp restore
symbols publish runs create → pack → push. build never publishes; keep publication as an
explicit release step with its own write credentials.
Create a symbol-only app
alwasp symbols create ./output/MyApp.app
alwasp symbols create ./output/MyApp.app --output ./symbols
The default output is MyApp.symbols.app beside the input. --output accepts a .app file
path or a folder receiving <input name>.symbols.app. The input cannot be overwritten.
Once ALTool is resolved, an existing output file is deleted before generation so a failed
run cannot report a stale artifact as its result.
ALWasp invokes ALTool’s CreateSymbolPackage, then verifies that the output preserves the
input’s app ID, publisher, name, and version. ALTool resolves through AL_PATH, then the
cached/downloaded Microsoft.Dynamics.BusinessCentral.Development.Tools package. If the
required operation is unavailable, run alwasp tools update or point AL_PATH to a newer
ALTool. See Tool acquisition.
Symbol package validation
create checks its output, pack checks its input, and push checks the app inside the
NuGet package. Every app must have:
- A manifest and usable
SymbolReference.jsonagreeing on app ID, publisher, name, and version. - ALTool confirmation that
IsSymbolOnlyisTrueandIsRuntimePackageisFalse.
Missing source files alone do not prove an app is symbol-only. A runtime package is rejected, and an ALTool lacking the verification operations fails rather than using a weaker check. Consequently, even jobs that only pack or push need access to a compatible ALTool.
Pack a NuGet package
alwasp symbols pack ./symbols/MyApp.symbols.app --output ./packages
Package metadata comes from the symbol app’s manifest:
| Field | Value |
|---|---|
| Package ID | {Publisher}.{Name}.symbols.{AppId}; publisher and name keep only [A-Za-z0-9_], and the GUID is lowercase |
| Version | The app version in normalized NuGet form; 2.1.0.5 remains unchanged, while 3.0.0.0 becomes 3.0.0 |
| Dependencies | Explicit AL dependencies, each with its package ID and minimum version range [minVersion, ), sorted by ID |
| Content | One symbol app at the package root as {Publisher}_{Name}_{Version}.app |
| Output | {ID}.{version}.nupkg in --output, or beside the input when omitted |
Malformed app versions, prerelease versions, and empty or malformed dependency versions fail
packing. application and platform are not added as package dependencies: consumers restore
their own implicit Microsoft requirements, including their localization choices.
For a dependency published under a non-standard package ID, supply its exact ID:
alwasp symbols pack ./symbols/MyApp.symbols.app --output ./packages \
--dependency-package-id 11111111-2222-3333-4444-555555555555=Contoso.Base-Core.symbols
The option is repeatable and preserves the mapped ID without normalization. Invalid GUIDs, invalid package IDs, or mappings for apps not in the dependency list fail. The package is read back and verified before success is reported. Identity, layout, and dependency ordering are deterministic, but archive bytes are not guaranteed to be byte-for-byte reproducible.
Push to a feed or folder
alwasp symbols push ./packages/Contoso.MyApp.symbols.11111111-2222-3333-4444-555555555555.1.0.0.nupkg \
--source ./local-feed --skip-duplicate
--source is required and accepts a NuGet v3 index URL, a nuget.config source name, or a
local folder, which is created if missing. Before sending anything, ALWasp requires exactly
one valid symbol-only .app and a package version matching the app version. Non-standard
package IDs are preserved, allowing existing symbol packages to move between feeds. If an ID
ends in an app GUID, that GUID must match the contained app. Ordinary NuGet packages are refused.
--api-keyfalls back toALWASP_NUGET_API_KEY, thennuget.configAPI keys.--skip-duplicatetreats an existing package version (HTTP 409) as success.--nuget-config,--auth-mode,--feed-token-env, and--patuse the restore credential options, applied only to the push source.ALWASP_PATremains the PAT fallback.- An HTTP source requires
allowInsecureConnections="true"on itsnuget.configentry.
See Authentication for write credentials and CI behavior. Publication can require authentication even when consumers read anonymously.
Publish in one command
alwasp symbols publish ./output/MyApp.app --output ./symbols --source ./local-feed \
--skip-duplicate --format json --result-file ./symbol-publish.json
--output is always a folder for both the symbol app and NuGet package, defaulting to the
input’s folder. Dependency ID mappings and push/authentication options work as above.
Publication stops at the first failing stage and exits 1, recording failedStage as
create, pack, or push. Successful structured results include appPath, symbolAppPath,
packagePath, packageId, packageVersion, dependencies, and source. NDJSON emits a
symbols.stage event as each stage starts. Normal success exits 0.
Consume the packages
alwasp restore --feed ./local-feed
Add the source with --feed or nuget.config. The generated IDs follow the existing restore
convention, and package dependencies are followed transitively. Existing restore and NuGet
version-source behavior is unchanged. The AL Language extension can also use the feed through
al.nugetFeeds; ALWasp recognizes that VS Code setting but does not apply it automatically.
For separating package preparation from a protected publication job, see CI/CD.