Can Nuget prerelease packages be overwritten on Artifactory? - nuget

Nuget packages are immutable. All documentation makes this very clear.
I am investigating an issue on my internal Nuget server where prerelease packages can be overwritten. Normally, when trying to upload a package with an existing version, the upload will fail. The Nuget server in question is an Artifactory server.
I immediately assume this to be a bug, but in searching to find other people encountering the same issue, I instead turn up posts from people implying this is normal.
This person asks how to always get the latest version when repeatedly publishing v1.0.0-prerelease.
This person found an Artifactory bug where prerelease packages can't be overwritten if they have a dot in the name.
Another Artifactory bug where STABLE packages can be overwritten because they are incorrectly identified as prerelease
I have yet to find any actual documentation saying prerelease packages can be overwritten on Nuget or Artifactory. I would not expect to, but those posts take it as a fact!

Upon more research and testing, the conclusion is this appears to be an undocumented feature of Artifactory.
The closest they come to documenting this is here:
https://www.jfrog.com/confluence/display/RTF/Managing+Permissions#ManagingPermissions-PreventingOverwritingDeployments
You can prevent a user or group from overwriting a deployed release or
unique snapshot by not granting the Delete permission. Non-unique
snapshots can always be overwritten (provided the Deploy permission is
granted).
That section of the documentation is not specific to any kind of repository. It is never specifically clarified anywhere that Nuget prerelease packages are considered "snapshots", but the terms "prerelease" and "unstable" are not used anywhere in the documentation (for any repository type).
Since this cannot be turned off, my team went with using automatically-generated versioning for prerelease packages to avoid having issues caused by package overwrite.
nuget.org does not allow any overwriting of prerelease packages.

Related

How to delete old snapshot artifacts from GitHub packages

I have a GitHub worflow which builds and deploys a snapshot version of a library as a GitHub package, e.g., mycompany.mytool.1.0.0-SNAPSHOT.jar. Whenever I make a new build and deploy, a new asset is created, like, e.g., mycompany.mytool.1.0.0-20210723.145233-1.jar instead which is then somehow associated with the SNAPSHOT tag. This all seems to work and I can access mycompany.mytool.1.0.0-SNAPSHOT.jar without problem.
My question now is, how can I get rid of all these older versions of this jar? Actually I just want to keep the latest version. I can delete them manually via the web-interface but that is a more than awkward task. I would somehow like to automate this too.
This is not possible as of this writing. GitHub staff member Jamie Cansdale wrote this in their community forum:
SNAPSHOT versions are exposed as artifacts inside a regular versions. There isn’t an API for cleaning up artifacts, only whole versions.
(source)
Which means that a single SNAPSHOT version (like 1.0.0-SNAPSHOT) will accumulate all builds you make, and all artifacts will show up on the Assets list to the right of the web page.
The only practical solution I can think of, is that you delete the whole version from a script, before publishing each build's artifacts. Then you'd have the effect of having a single set of artifacts stored as part of the 1.0.0-SNAPSHOT version name.
However this solution is not ideal: public package versions cannot be deleted if they are popular enough (probably to avoid squatting attacks):
If the package is public and the package version has more than 5,000 downloads, you cannot delete the package version. In this scenario, contact GitHub support for further assistance.

Industry standard for managing Nuget packages within the enterprise

I have a situation where we have multiple C# projects that use similar set of Nuget packages (ex. Newton Json, Microsoft Compilers and CodeDom, Owin, log4net, jQuery, EntityFramework etc.)
I am trying to see how we can have a shared location for all Nuget packages to reduce the footprint of those binaries in Git, having a single repo for them by centralizing them in one place.
One option I found is to use Nuget.config in each project with repositoryPath set to point at the shared location. This works great for adding/upgrading/restoring Nuget packages in the project but it is not very clean when a package gets removed from one project but is still required in a different one. Basically the package will get removed from the shared location and the change is committed to Git, then when the other project requires it, it would get restored and added back to Git. Not a perfect solution in my mind.
I have a two part question:
1. Is there a way to improve the above workflow when packages get removed?
2. What is the industry standard for handling third party libraries delivered via Nuget? Or if there is none, can you share your experience handling Nuget packages across multiple projects.
If the concern lies with the footprint/organization of the Git repository, maybe you can do a .git ignore for the dependencies folders to prevent git from committing them into the repositories. When you need to build the projects from source, just do a dotnet /nuget restore to get the dependencies from the source you configured in the Nuget.config
Not sure if it is the industry standard, but we host our own Nuget server to control the libraries that the different teams can use. Microsoft has an article on Hosting your own NuGet feeds
Hope it helps.

push NuGet packages to TeamCity NuGet server

I have turned on TeamCity's NuGet Server and I want to push in common packages (i.e. from public sources such as NuGet.org) because the build server cannot see outside our company, so restoring packages on the build server from NuGet.org is not possible.
I cannot see how to push these packages on to our TeamCity server. I've seen various answers suggesting to use a package build still or some other means of publishing from within a build, but this is not appropriate for my use case.
If I try to publish from a command line it complains that it cannot find an API key (where do I get that from?) and it won't allow me to enter my credentials (I assume my team city login would be it) as it tells me "Cannot prompt for input in non-interactive mode." (I didn't set that mode and I can't see how to turn that off).
So, how do I push/publish an adhoc package that I obtained elsewhere into team city?
I believe that the nuget functionality provided by TeamCity is an API added on top of TeamCity's builtin artifact functionality.
There are a number of consequences of that:
When a build configuration is executed that produces any .nupkg files that are marked as artifacts, they will be available on the Teamcity nuget feed.
As with all other artifacts nupkgs published in TeamCity are subject to Teamcity's general artifact retention rules.
Access rules for nuget packages are the same as access to the TeamCity projects.
There is however as far as I know no implementation in the Teamcity Nuget API for pushing packages to it. The general practice for storing original or generated packages is to use a stand alone nuget server or service like a normal file share, a Nuget.Core based server, proget or myget.org.
Update:
If you end up with many packages of your own I've heard people reporting that Teamcity becomes quite slow when the clients are resolving the packages.
Update 2:
The last years I've adopted the notion of separating build artifact packages into the two categories library package and deployment package. A separate package repository can be used for both types but a repository such as the one available in for instance Octopus deploy should only be used for deployment packages.
Update 3:
Microsoft have a page for a number of nuget server options.

Mirror all packages from a Nuget repository

I have two questions about mirroring Nuget packages using the nuget mirror command (reference).
We are migrating our internal Nuget repository to Artifactory and for the time being I need to have all the packages (and all their versions) from the original nuget repo mirrored to Artifactory.
First, does nuget mirror take into account packages that are already present at the destination? Because so far no matter what I do, the package is always re-uploaded with every call, even though it is already there. Setting up a job responsible for mirroring all the packages would be pretty costly if it always re-uploaded all of them.
Second, is it possible to tell the command to mirror all packages? The documentation states I have to either specify a package ID or a file containing the IDs, but I want to mirror them all.
Related, is it possible to tell the command to mirror all versions of a package? Because if a version is not speficied, only the latest one gets mirrored.
Thanks
As per comments - nuget mirror can only mirror a single package/version. In order to mirror all packages, you need to make a script that scrapes the package info from the Nuget server and then mirror them one-by-one.

NuGet causing Azure Pipeline issues

Not every time but quite frequently I get ##[error]The nuget command failed with exit code(1) and error(NU1102: Unable to find package MyPackage with version (>= 1.0.5)
in my Azure Pipelines builds (different packages and different versions):
The package definitely exists as it had just been built a couple of minutes ago and I can see it in the Artifact Feed:
Here is my pipeline:
The project consists of multiple packages so this is starting to get really inconvenient. If I try on different build agents I eventually get one to work but the pipelines are supposed to be more of a hands off process. As far as I can tell (or guess), Nuget is caching the index.json for the feed. The only other issues I can find related to this specifically happen in people's local environments. Is there some way to get Nuget to properly check if packages exist?
1.Not sure about the real cause of your issue, but if cleaning cache can help to resolve your issue, you only need to enable this option in Restore task.
2.Also, sometimes the package not found error could be related to feed permissions in Devops. Go Artifacts=>custom Feed=>Feed Settings in right corner:
Make sure your build service have access to that feed.
NuGet does cache what versions of a package are available on each feed for 30 minutes, so the package was published more recently than that, and that machine had already restored a different version of the package within the last 30 minutes, it will be a problem.
You could run dotnet nuget locals http-cache --clear or nuget.exe locals http-cache -clear before the restore, that will delete NuGet's HTTP cache.