Overall I see this as a reasonable proposal. I have a number of questions/concerns some of which I’ve raised outside of this thread and I’ll raise them again to get input from the community. I’d love to see these addressed either in this proposal or in a future one after this is approved.
- Registry Only - Some users will want an option to only fetch from a registry (i.e. don’t fallback to downloading from a URL specified in the Package.swift). This is important for use in organizations that want all package downloads to come from a private registry. I’d expect this to be a config option that a user can set. If the client doesn’t find a package in the registry then fail instead of fetching by URL.
- Packages without an ID - How can I use a registry to fetch packages that only have a URL and don’t (yet?) have a new-style ID (scope + name)? The
GET /identifiers{?url}
API doesn’t seem to help with this. This is related to the first item. Ideally, even packages that do not have an ID could be added to and fetched from a registry so that an organization that wants to fetch all packages from a private registry would have a way to handle open source packages in their dependency graph that don’t have an ID. - Credentials - There has already been some discussion around avoiding passwords in URLs and whether
.netrc
works on non-mac platforms. But.netrc
assumes the user has one set of credentials per host name while users may need to use different credentials with different private registries hosted by the same service provider (e.g. different Azure Artifacts registries hosted on pkgs.dev.azure.com). I’d suggest modeling username and password as separate CLI parameters when configuring a registry and store them as separate fields. Ideally a project-level config file could specify which registries to use and credentials for each registry URL could be read from a user-level config file. See this comment where I compare how credentials are handled in npm. I’d prefer if the swift client supported something like NuGet credential providers but that would definitely warrant a separate proposal. - List available files - For future alternative formats (such as binary XCFramework distributions) and for mirroring support I’d like if the registry protocol provided a list of files available for each release. (For previous discussion see my comment and mattt’s reply).
- JSON manifest - When publishing a release to a registry I’d suggest converting the imperative Package.swift into a declarative data model (preferable JSON). Perhaps this is something that
swift package archive-source
could do? I realize that today Package.swift files can have non-deterministic behavior so this is probably better addressed in a separate proposal. (For previous discussion see this comment and this one). - Publishing - This proposal calls out that publishing is out of scope. But developers using a private registry service (such as AWS CodeArtifact, Azure Artifacts, JFrog Artifactory or Sonatype Nexus) would benefit from having a standard registry API and CLI command for publishing. (This could easily be a separate proposal)
- Registering Package URLs - How does a package owner register primary and alternative URLs for a package? Should these be specified in Package.swift so that when a package is published (whether by a push or pull model) the registry becomes aware of them (and it may require some form of verification)?
- Centralized vs Decentralized - It appears to me that this registry design works best with a central public registry. It seems likely, whether intentional or not, that GitHub well become the de-facto public registry. If so, will GitHub allow package authors to distribute packages in GitHub public registry even if the package uses a different source code hosting provider? Or if the Swift community's intent is for a decentralized model then I'll echo Simon's question: