Welcome to the Inedo Forums! Check out the Forums Guide for help getting started.
If you are experiencing any issues with the forum software, please visit the Contact Form on our website and let us know!
ProGet 2025.10: License Update API Issues
-
ProGet: 2025.10
Inedo.Proget: 2.0.5The Update License API does not update the database in all cases.
For example just updating the title via a partial object (which is supposed to be supported according to docs?) never seems to update the database, even though the call always succeeds.
await _progetClient.UpdateLicenseAsync(new LicenseInfo { Id = 59, Code = "CC-BY-1.0", Title = "Test" });
I've had some success with updating the
Urls
andPackageNames
properties, but even these calls are not always immediately reflected in the database or the UI. Sometimes it feels like the changes only get persisted after clicking around in the UI a bit, but that could just be coincidence. Rarely it is visible directly after the API call.I've also tried retrieving the full LicenseInfo object from the database, and using a modified clone of the object with the Update API, but this has also flaky behavior and the title update also never works.
Am I doing something wrong or is there a glitch in the update API?
-
It appears the
AddLicenseAsync()
API also has issues:- Spdx is sometimes modified, sometimes not set at all
- PUrl is not set
- PackageNames is not set
-
Hi @jw ,
I'm not able to reproduce any issues on my end; I'm not entirely sure how you're testing, but let me share with you the code on the server side in ProGet:
private static async Task UpdateLicenseAsync(AhHttpContext context, LoggedResponseStream output, WebApiContext apiContext) { EnsureMethod(context, "POST"); EnsureCanManageLicenses(apiContext); var input = await JsonSerializer.DeserializeAsync(context.Request.InputStream, LicenseApiJsonContext.Default.LicenseInfo, context.CancellationToken) ?? throw new HttpException(400, "Expected license object."); var license = await DB.Licenses_GetLicenseAsync(External_Id: input.Code) ?? throw new HttpException(404, "License not found."); List<int>? nameIds = null; if (input.PackageNames?.Count > 0) { nameIds = []; foreach (var n in input.PackageNames) { if (!PackageNameId.TryParse(n, out var nameId)) throw new HttpException(400, $"Invalid package name: {n}"); nameIds.Add((await nameId.EnsureDatabaseIdAsync()).Id!.Value); } } List<int>? versionIds = null; if (input.Purls?.Count > 0) { versionIds = []; foreach (var v in input.Purls) { if (!PUrl.TryParse(v, out var purl)) throw new HttpException(400, $"Invalid purl: {v}"); versionIds.Add((await ((PackageVersionId)purl).EnsureDatabaseIdAsync()).Id!.Value); } } await DB.Licenses_UpdateLicenseDataAsync( License_Id: license.License_Id, PackageVersionIds_Csv: versionIds?.Count > 0 ? string.Join(',', versionIds) : null, PackageNameIds_Csv: nameIds?.Count > 0 ? string.Join(',', nameIds) : null, SpdxIds_Csv: input.Spdx?.Count > 0 ? string.Join(',', input.Spdx) : null, Urls_Csv: input.Urls?.Count > 0 ? string.Join(',', input.Urls) : null ); }
I'm not sure if that's helpful, but if not... can you put a specific reproduction case?
Also note that the license data in the UI is cached, but it's invalidated when you visit the
/licenses
page and others.Thanks,
Steve