Using Nuget.Protocol to delete a package from Azure DevOps - azure-devops

I'm writing a simple application to implement package retention in our AzureDevOps NuGet feed, but I can't delete a package -- nothing happens.
(I want to keep all release packages, but delete all pre-release packages for branches that nolonger exist and keep only the latest three pre-release packages for branches that do exist.)
// Log in and whatnot.
PackageSource packageSource = new PackageSource("https://pkgs.dev.azure.com/Organisation/_packaging/Organisation/nuget/v3/index.json")
{
Credentials = new PackageSourceCredential(
source: "https://pkgs.dev.azure.com/Organisation/_packaging/Organisation/nuget/v3/index.json",
username: "rwb#organisation.co.uk",
passwordText: _Pat,
isPasswordClearText: true,
validAuthenticationTypesText: null)
};
NuGet.Protocol.Core.Types.SourceRepository repository = NuGet.Protocol.Core.Types.Repository.Factory.GetCoreV3(packageSource);
PackageSearchResource packageSearch = repository.GetResourceAsync<NuGet.Protocol.Core.Types.PackageSearchResource>().Result;
PackageUpdateResource packageUpdate = repository.GetResourceAsync<PackageUpdateResource>().Result;
// Delete a package -- doesn't work!
packageUpdate.Delete("Organisation.MyDll", "1.0.1-branch.build", packageSource => _Pat, packageSource => true, false, _Logger);
The .Delete doesn't throw an exception or log any error, but the package remains in AzureDevOps.
I think I need to add .Wait() because of the async nonsense, but even so: the packages appear srikethrough in the Azure DevOps website, but not in the feed's recycle bin, and they're still listed in NuGet package manager in VisualStudio.
How do you actually delete the things?
Update
So apparently the C# only delists and you have to use the HTTP API directly to actually delete. However, it's impossible to authenticate.
private static void Delete(NuGet.Packaging.Core.PackageIdentity packageIdentity)
{
// https://learn.microsoft.com/en-us/nuget/api/package-publish-resource
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("X-NuGet-ApiKey", "VSTS");
//httpClient.DefaultRequestHeaders.Add("X-NuGet-ApiKey", _Pat);
//httpClient.DefaultRequestHeaders.Add("X-NuGet-ApiKey", "rwb#organisation.co.uk:" + _Pat);
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", ":" + _Pat);
//httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", "rwb#organisation.co.uk:" + _Pat);
//httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _Pat);
// https://learn.microsoft.com/en-us/rest/api/azure/devops/artifactspackagetypes/nuget/delete-package-version?view=azure-devops-rest-6.0
HttpResponseMessage rx = httpClient.DeleteAsync($"https://pkgs.dev.azure.com/Organisation/_apis/packaging/feeds/FeedName/nuget/packages/{packageIdentity.Id}/versions/{packageIdentity.Version}?api-version=6.0-preview.1").Result;
}

I had exactly the same issue that the standard NuGet delete will only delist the package.
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", "", _Pat))));
What worked for me (authentication-wise) was the ToBase64String conversion.

Related

Groovy Script in SoapUI

When I'm running the following script in my SOAPUI, I'm getting error related to HTTPBuilder. Error is still there even after adding #Grab statement.
def http = new HTTPBuilder(serviceEndPoint)
def scanResultFile = new File(testRunner.testCase.getPropertyValue("ScanResultFile"))
http.request( POST ){ req ->
headers.'Connection' = 'Keep-Alive'
headers.'User-Agent' = 'SoapUI 4.5.1'
requestContentType = 'multipart/form-data'
ByteArrayBody bin = new ByteArrayBody(scanResultFile.readBytes(), "application/octet-stream", "jobResult");
StringBody info = new StringBody(testRunner.testCase.getPropertyValue("JsonScanResult"), "application/json", java.nio.charset.StandardCharsets.UTF_8);
MultipartEntity entity = new MultipartEntity()
entity.addPart("info", info);
entity.addPart("jobResult", bin)
req.entity = entity
}
Any solution to run this groovy script in SOAP UI.
SoapUI does not come with HTTPBuilder. Further, since the Groovy engine has already been started in a running SoapUI instance, your #Grab annotation will not work.
In order to extend the functionality of SoapUI, you must download the .jar and all dependencies manually, and place them in $SOAPUI_HOME/bin/ext folder. You will need to restart SoapUI for this to take effect.

Calling External WCF Service (using generated client) from CRM sandboxed plugin OnPremise is failing

How to call HTTPS WCF web service in Plugin, plugin assembly is registered in sandbox mode. I am getting System.Security.SecurityException exception, Can somebody please provide the way to all https web service. My code is below :
BasicHttpBinding myBinding = new BasicHttpBinding();
myBinding.MaxReceivedMessageSize = Int32.MaxValue;
myBinding.Name = “basicHttpBinding”;
if (EndPoint.ToLower().Contains(“https://”))
{
//Throwing exception here – System.Security.SecurityException exception,
ServicePointManager.ServerCertificateValidationCallback += (sendr, cert, chain, sslPolicyErrors) => true;
ServicePointManager.SecurityProtocol = (SecurityProtocolType)768 | (SecurityProtocolType)3072 | (SecurityProtocolType)192;
myBinding.Security.Mode = BasicHttpSecurityMode.Transport;
}
else
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
myBinding.Security.Mode = BasicHttpSecurityMode.None;
}
myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
myBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
myBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
EndpointAddress endPointAddress = new EndpointAddress(EndPoint);
WebIALClient myClient = new WebIALClient(myBinding, endPointAddress)
Since you are in on-premise version, you can register the plugin assembly in non-sandbox mode. ie Isolation mode = none to overcome such errors.
In case you wanted to use sandbox mode, try using WebClient class for invoking WCF service call. Read more
using (WebClient client = new WebClient())
{
byte[] responseBytes = client.DownloadData(webAddress);
string response = Encoding.UTF8.GetString(responseBytes);
tracingService.Trace(response);
// For demonstration purposes, throw an exception so that the response
// is shown in the trace dialog of the Microsoft Dynamics CRM user interface.
throw new InvalidPluginExecutionException("WebClientPlugin completed successfully.");
}
Can you try and also include: using System.Web.Http.Cors;
[EnableCors(origins: "*", headers: "*", methods: "*")]
[Route("api/ConvertUpload/{env}/{id}")]
public string Get(string env, string id)
{
return "hi";
}
You may have to use WebClient as #Arun has mentioned.

wixsharp service not getting installed

This may be a newbie question so excuse me for that.
My installation works fine without any error, All the files get copied to the install folder BUT there is no service installed? Any help is appreciated.
I have a simple installation that copies few files into the install directory and then installs the service from one of the installed files. Here is the my program.cs relevant code
WixSharp.File service;
var project = new ManagedProject("DMACSServer",
new Dir( #"%ProgramFiles%\DRR\DMACS SLM",
new DirFiles(#"Z:\DEV\current\FrameworkDLLS\*.*")));
new Dir(#"%ProgramFiles%\DRR\DMACS SLM",
service = new WixSharp.File(#"Z:\DEV\current\FrameworkDLLS\SLMService.exe"));
service.ServiceInstaller = new ServiceInstaller
{
Name = "DMACS SLM Service",
StartOn = SvcEvent.Install, //set it to null if you don't want service to start as during deployment
StopOn = SvcEvent.InstallUninstall_Wait,
RemoveOn = SvcEvent.Uninstall_Wait,
//DelayedAutoStart = true,
};
project.GUID = new Guid("97b17bfe-6086-4072-8f23-6859a44c4fa4");
project.MajorUpgradeStrategy = MajorUpgradeStrategy.Default;
project.ManagedUI = ManagedUI.Empty; //no standard UI dialogs
project.ManagedUI = ManagedUI.Default; //all standard UI dialogs
//custom set of standard UI dialogs
project.ManagedUI = new ManagedUI();
project.ManagedUI.InstallDialogs.Add(Dialogs.Welcome)
.Add<EnvironmentDialog>()
.Add<RolesDialog>()
.Add(Dialogs.InstallDir)
.Add(Dialogs.Progress)
.Add(Dialogs.Exit);
project.ManagedUI.ModifyDialogs.Add(Dialogs.MaintenanceType)
.Add(Dialogs.Features)
.Add(Dialogs.Progress)
.Add(Dialogs.Exit);
project.Load += Msi_Load;
project.BeforeInstall += Msi_BeforeInstall;
project.AfterInstall += Msi_AfterInstall;
project.PreserveTempFiles = true;
//project.SourceBaseDir = "<input dir path>";
//project.OutDir = "<output dir path>";
project.BuildMsi();

How to set Gradle Artifactory Publish plugin default configuration/properties from custom plugin

I have been trying to set the properties of publish(PublisherConfig), defaults(defaultsClosure) from my custom plugin. What is the best way to do this ?
I tried the following;
Approach 1: Tried setting the properties on the extensions
project.getExtensions().publishing.getProperties().each { println it }
Approach 2: Tried adding compile time dependency on the Gradle Artifactory plugin and importing the plugin classes...
```
if (project.plugins.hasPlugin("com.jfrog.artifactory")) {
println "I found jfrog.artifactory plugin"
Plugin jfrogArtifactory = project.getPlugins().getPlugin("com.jfrog.artifactory")
ArtifactoryPluginConvention apc = new ArtifactoryPluginConvention(project);
project.getExtensions().add("artifactory", apc);
apc.contextUrl = 'https://myrepo.com/artifactory/'
PublisherConfig pc = new PublisherConfig(apc);
pc.defaults {
println "in my plugin pc.defaults : " + it.metaClass
publications('mavenJava')
publishConfigs('archives', 'published')
properties = ['my.gitCommitUrl': project.getExtensions().findByType(BuildPropertiesPluginExtension.class).gitCommitUrl, 'my.gitHash': project.getExtensions().findByType(BuildPropertiesPluginExtension.class).gitHash, 'my.gitBranch': project.getExtensions().findByType(BuildPropertiesPluginExtension.class).gitBranch]
publishBuildInfo = true //Publish build-info to Artifactory (true by default)
publishArtifacts = true //Publish artifacts to Artifactory (true by default)
publishPom = true //Publish generated POM files to Artifactory (true by default).
publishIvy = false //Publish generated Ivy descriptor files to Artifactory (true by default).
}
pc.repository {
println "in my plugin pc.repository : " + it.metaClass
repoKey = 'my-mvn' //The Artifactory repository key to publish to
username = project.findProperty("artifactory_user") ?: "" //The publisher user name
password = project.findProperty("artifactory_api_key") ?: "" //The publisher password
}
apc.setPublisherConfig(pc)
}
```
Compile and Build are successful, artifact and its info is not published.
:artifactoryPublish
BUILD SUCCESSFUL
Total time: 3.313 secs
Here is what worked for me!!!
`
if (project.plugins.hasPlugin("com.jfrog.artifactory")) {
Plugin jfrogArtifactory = project.getPlugins().getPlugin("com.jfrog.artifactory")
//maven install task is required to publishPom (using artifactory plugin)
if (!project.plugins.hasPlugin("maven")) {
project.apply(plugin: MavenPlugin)
}
Closure artifactoryPublishClosure = {
contextUrl = 'https://myrepo.com/artifactory/'
publications('mavenJava')
publishConfigs('archives', 'published')
properties = ['gitCommitUrl': project.getExtensions().findByType(BuildPropertiesPluginExtension.class).gitCommitUrl, 'gitHash': project.getExtensions().findByType(BuildPropertiesPluginExtension.class).gitHash, 'gitBranch': project.getExtensions().findByType(BuildPropertiesPluginExtension.class).gitBranch]
publishBuildInfo = true //Publish build-info to Artifactory (true by default)
publishArtifacts = true //Publish artifacts to Artifactory (true by default)
publishPom = true //Publish generated POM files to Artifactory (true by default).
publishIvy = false //Publish generated Ivy descriptor files to Artifactory (true by default).
// Redefine basic properties of the build info object
clientConfig.setIncludeEnvVars(true)
clientConfig.timeout = 600 // Artifactory connection timeout (in seconds). The default timeout is 300 seconds.
publish {
//A closure defining publishing information
repository {
repoKey = 'my-mvn' //The Artifactory repository key to publish to
username = project.findProperty("artifactory_user") ?: "" //The publisher user name
password = project.findProperty("artifactory_api_key") ?: "" //The publisher password
}
}
resolve {
repository {
repoKey = 'my-mvn' //The Artifactory (preferably virtual) repository key to resolve from
}
}
}
project.getTasks().findByName("artifactoryPublish").configure(artifactoryPublishClosure)
}
`

How to read an installed feature (eclipse PDE)?

Is it possible to read a feature like its possible to read a plugin use the eclipse PDE API? Currently I read plugins using:
Bundle[] bundles = Platform.getBundles(name, version);
if (bundles == null) {
throw new NullPointerException("No bundle found with ID: " + name
+ " and version: " + version);
} else {
for (Bundle bundle : bundles) {
System.out.println(bundle.getSymbolicName());
}
}
But if I specify the name of an installed feature I just get null. Is there some other way that features should be read?
And when I have read the feature I would like to iterate all the plugins that it reference.
You can try to use p2 API to query the installed feature. P2 is the manager of eclipse installation.
// IProvisioningAgent is a OSGi service
IProvisioningAgent agent = ...;
IProfileRegistry profileRegistry = (IProfileRegistry) agent.getService(IProfileRegistry.SERVICE_NAME);
IProfile profile = profileRegistry.getProfile(IProfileRegistry.SELF);
IQueryResult rt = profile.query(QueryUtil.createIUPropertyQuery("org.eclipse.equinox.p2.eclipse.type", "feature"), null);