Support for local filesystem-based registry aliases#19452
Conversation
There was a problem hiding this comment.
Pull request overview
Adds support for filesystem-backed br/<alias>: module aliases so developers can redirect OCI module references to local .bicep files during iteration (Bicep.Core registry/config + tests/baselines).
Changes:
- Extend
moduleAliases.br.<alias>to support afileSystemtarget (mutually exclusive withregistry). - Add an emulated OCI artifact reference type and a registry implementation to load modules directly from disk without restore/cache.
- Update diagnostics/tests and refresh the
Registry_LFbaseline to include an emulated registry alias scenario.
Reviewed changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Bicep.Core/Registry/OciArtifactRegistry.cs | Routes br/<alias>: parsing to a filesystem-emulated reference when the alias has fileSystem. |
| src/Bicep.Core/Registry/Oci/OciArtifactReferenceFacts.cs | Adds internal scheme constant for emulated OCI references. |
| src/Bicep.Core/Registry/Oci/OciArtifactEmulatedReference.cs | New artifact reference type resolving br/<alias>: modules to local .bicep files. |
| src/Bicep.Core/Registry/FileSystemModuleRegistry.cs | New registry for br-fs references used during restore/check operations. |
| src/Bicep.Core/Registry/DefaultArtifactRegistryProvider.cs | Registers the new registry and wires IFileExplorer into OciArtifactRegistry. |
| src/Bicep.Core/Modules/ModuleReferenceSchemes.cs | Exposes the internal emulated scheme. |
| src/Bicep.Core/Diagnostics/DiagnosticBuilder.cs | Updates alias diagnostics and hides the internal scheme from “unknown scheme” messages. |
| src/Bicep.Core/Configuration/ModuleAliasesConfiguration.cs | Adds fileSystem to OCI alias config and validates mutual exclusivity. |
| src/Bicep.Core.UnitTests/Utils/OciRegistryHelper.cs | Updates test helper for new OciArtifactRegistry constructor signature. |
| src/Bicep.Core.UnitTests/Registry/OciArtifactEmulatedReferenceTests.cs | New unit tests for parsing/emulated reference behavior and alias validation. |
| src/Bicep.Core.UnitTests/Modules/OciArtifactModuleReferenceTests.cs | Updates expected diagnostics for alias validation changes. |
| src/Bicep.Core.Samples/Files/baselines/Registry_LF/* | Baseline updates to cover filesystem-based alias usage. |
Comments suppressed due to low confidence (1)
src/Bicep.Core/Configuration/ModuleAliasesConfiguration.cs:118
TryGetOciArtifactModuleAliasenforcesregistryXORfileSystem, but it allowsmodulePathto be set alongsidefileSystem. In the current implementation,modulePathis ignored for filesystem-based aliases, which makes that configuration misleading. Consider either (a) rejectingfileSystem+modulePathwith a diagnostic, or (b) applyingmodulePathas an additional subdirectory when resolvingmodulePath.bicepso behavior stays aligned with howmodulePathworks for registry aliases.
if (alias.Registry is not null && alias.FileSystem is not null)
{
return new(x => x.InvalidOciArtifactModuleAliasRegistryAndFileSystemSetTogether(aliasName, configFileUri));
}
if (alias.Registry is null && alias.FileSystem is null)
{
return new(x => x.InvalidOciArtifactModuleAliasRegistryNullOrUndefined(aliasName, configFileUri));
}
return new(alias);
…d diagnostics reserving br-fs scheme for internal use only
…t alias paths relative to bicepconfig
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
|
Looking at this bicepconfig example, it's using the To me it's confusing that the following would map to the file system: module myModule 'br/MyRegistry:mymodule:1.0.0' = {}Whereas the following is clearer: module myModule 'local/myAlias:mymodule' = {} |
|
The purpose of this PR is to be able to locally emulate an ACR to shorten the dev-cycle of modules. Imagine I have a prod ACR where all company modules are hosted. They are of course immutable and won't be changed once published. I have a module (mymodule@1.0.0) that I need to update and release in version 1.1.0. To make sure of the quality of my new module version, I want to deploy a few of my existing templates using this new version of my module. What I would do today is create a personal ACR (or a personal namespace/path in a dev-ACR without immutability), publish my module there for QA and change the module alias to point to my personal ACR. Everyone involved in QA of my module would either have to have access to my personal ACR or publish the module to their own personal ACR. This quickly becomes complicated if the module I'm testing also depends on other modules in the same registry, then they have to be published to my personal ACR as well. With this feature, anyone can check out my PR to the modules repo, point/redirect the module alias to the local repository folder and deploy any template without modification and without worrying about which modules that has to be available as well. That's why I've chosen to call the class OciArtifactEmulatedReference since the whole purpose is to be able to emulate an ACR registry. The EmulatedReference also uses the same br prefix to be able to deploy existing templates without modifications. I don't mind implementing a local or fs alias as well, I think that might be useful instead of using paths like |
I asked the same question earlier, before @SimonWahlin sent the PR. I think he made a good point that requiring the author to change the module path scheme in order to test a new module version would not be ideal. That said, after reading through the samples and test code, I do feel that overloading the existing moduleAliases section could lead to confusion. I have an alternative idea: could we introduce a moduleAliasesMock section that, if present, would supersede moduleAliases? For example: {
"moduleAliasesMock": {
"br": {
"MyRegistry": {
"fileSystem": "bicepModules"
}
}
}
}@SimonWahlin @anthony-c-martin What do you think? |
|
I like the idea of calling it a moduleAliasesMock, that would clear up risk of confusion and also be very clear about the purpose of the feature. |
Description
When developing modules that are published to a module registry, this feature will add the ability to test existing templates by redirecting a br/alias to a filesystem path.
Fixes #17096
Example Usage
Having an existing template that deploys a module using the following code:
main.bicep
I want to make changes to mymodule and need to validate them before publishing version 1.0.1 to my registry. I update mymodule and save it as
mymodule.bicepin a subfolder namedbicepmodules.bicepmodules/mymodule.bicep
To make my template (main.bicep) use the updated module on my filesystem instead of the one from my container registry, I update my
bicepconfig.jsonto the following:bicepconfig.json
{ "moduleAliases": { "br": { "MyRegistry": { "fileSystem": "bicepModules" } } } }I have intentionally not exposed a new prefix for moduleAliases to be able to deploy existing templates that are using the br/ prefix.
Checklist
Microsoft Reviewers: Open in CodeFlow