Skip to content

Commit a479e67

Browse files
conan2 support
1 parent 2e936d9 commit a479e67

31 files changed

+1453
-31
lines changed

README.md

+60-31
Original file line numberDiff line numberDiff line change
@@ -30,37 +30,60 @@ The *[JFrog Extension](https://marketplace.visualstudio.com/items?itemName=JFrog
3030

3131
## Table of contents
3232

33-
- [Table of contents](#Table-of-contents)
34-
- [Overview](#Overview)
35-
- [Download and Installation](#Download-and-Installation)
36-
- [Installing the Extension](#Installing-the-Extension)
37-
- [Installing the Build Agent](#Installing-the-Build-Agent)
38-
- [Configuring the Service Connections](#Configuring-the-Service-Connections)
39-
- [Executing JFrog CLI Commands](#Executing-JFrog-CLI-Commands)
40-
- [Build tools Tasks](#build-tools-tasks)
41-
- [JFrog Maven](#JFrog-Maven-Task)
42-
- [JFrog Gradle](#JFrog-Gradle-Task)
43-
- [JFrog Npm](#JFrog-Npm-Task)
44-
- [JFrog Nuget](#JFrog-Nuget-and-NET-Core-Task)
45-
- [JFrog .NET Core](#JFrog-Nuget-and-NET-Core-Task)
46-
- [JFrog Pip](#JFrog-Pip-Task)
47-
- [JFrog Conan](#JFrog-Conan-Task)
48-
- [JFrog Go](#JFrog-Go-Task)
49-
- [Build Tasks](#Build-tasks)
50-
- [JFrog Collect Build Issues](#JFrog-Collect-Build-Issues)
51-
- [JFrog Publish Build Info](#JFrog-Publish-Build-Info)
52-
- [JFrog Build Promotion](#JFrog-Build-Promotion)
53-
- [Discarding Published Builds](#Discarding-Published-Builds-from-Artifactory)
54-
- [Managing Generic Artifacts](#Managing-Generic-Artifacts)
55-
- [JFrog Xray](#JFrog-Xray-tasks)
56-
- [Audit project's dependencies for Security Vulnerabilities](#Audit-projects-dependencies-for-Security-Vulnerabilities)
57-
- [Scanning Published Builds for Security Vulnerabilities with JFrog Xray](#Scanning-Published-Builds-for-Security-Vulnerabilities)
58-
- [JFrog Docker Tasks](#JFrog-Docker-tasks)
59-
- [Pushing and Pulling Docker Images to and from Artifactory](#Pushing-and-Pulling-Docker-Images-to-and-from-Artifactory)
60-
- [Scanning Local Docker Images with JFrog Xray](#Scanning-Local-Docker-Images-with-JFrog-Xray)
61-
- [JFrog Distribution](#Managing-and-Distributing-Release-Bundles)
62-
- [JFrog Distribution Task](#JFrog-Distribution-V2-Task)
63-
- [Contributions](#Contribution)
33+
- [JFrog Azure DevOps Extension](#jfrog-azure-devops-extension)
34+
- [Overview](#overview)
35+
- [Table of contents](#table-of-contents)
36+
- [Download and Installation](#download-and-installation)
37+
- [Installing the Extension](#installing-the-extension)
38+
- [Installing the Build Agent](#installing-the-build-agent)
39+
- [Automatic Installation](#automatic-installation)
40+
- [Custom tools Installation](#custom-tools-installation)
41+
- [Manual Installation](#manual-installation)
42+
- [Installing JFrog CLI](#installing-jfrog-cli)
43+
- [Installing the Maven Extractor](#installing-the-maven-extractor)
44+
- [Installing the Gradle Extractor](#installing-the-gradle-extractor)
45+
- [Installing Conan](#installing-conan)
46+
- [Using TFS 2015](#using-tfs-2015)
47+
- [Configuring the Service Connections](#configuring-the-service-connections)
48+
- [Executing JFrog CLI Commands](#executing-jfrog-cli-commands)
49+
- [JFrog CLI V2 Task](#jfrog-cli-v2-task)
50+
- [Managing Generic Artifacts](#managing-generic-artifacts)
51+
- [Generic artifacts handling](#generic-artifacts-handling)
52+
- [Downloading generic build dependencies from Artifactory](#downloading-generic-build-dependencies-from-artifactory)
53+
- [Uploading generic build artifacts to Artifactory](#uploading-generic-build-artifacts-to-artifactory)
54+
- [Setting / Deleting properties on files in Artifactory](#setting--deleting-properties-on-files-in-artifactory)
55+
- [Moving / Copying / Deleting artifacts in Artifactory](#moving--copying--deleting-artifacts-in-artifactory)
56+
- [Build tools Tasks](#build-tools-tasks)
57+
- [JFrog Maven Task](#jfrog-maven-task)
58+
- [JFrog Gradle Task](#jfrog-gradle-task)
59+
- [JFrog Npm Task](#jfrog-npm-task)
60+
- [JFrog Nuget and .NET Core Task](#jfrog-nuget-and-net-core-task)
61+
- [JFrog Pip Task](#jfrog-pip-task)
62+
- [JFrog Conan Task](#jfrog-conan-task)
63+
- [JFrog Go Task](#jfrog-go-task)
64+
- [Build Tasks](#build-tasks)
65+
- [JFrog Collect Build Issues](#jfrog-collect-build-issues)
66+
- [Configuration properties](#configuration-properties)
67+
- [JFrog Publish Build Info](#jfrog-publish-build-info)
68+
- [JFrog Build Promotion](#jfrog-build-promotion)
69+
- [Using Build Promotion in a Release](#using-build-promotion-in-a-release)
70+
- [Discarding Published Builds from Artifactory](#discarding-published-builds-from-artifactory)
71+
- [JFrog Xray tasks](#jfrog-xray-tasks)
72+
- [Audit project's dependencies for Security Vulnerabilities](#audit-projects-dependencies-for-security-vulnerabilities)
73+
- [Scanning Published Builds for Security Vulnerabilities](#scanning-published-builds-for-security-vulnerabilities)
74+
- [JFrog Docker tasks](#jfrog-docker-tasks)
75+
- [Pushing and Pulling Docker Images to and from Artifactory](#pushing-and-pulling-docker-images-to-and-from-artifactory)
76+
- [Scanning Local Docker Images with JFrog Xray](#scanning-local-docker-images-with-jfrog-xray)
77+
- [Using Published Artifacts in a Release](#using-published-artifacts-in-a-release)
78+
- [Using JFrog Generic Artifacts task](#using-jfrog-generic-artifacts-task)
79+
- [Using Azure Artifact source](#using-azure-artifact-source)
80+
- [Managing and Distributing Release Bundles](#managing-and-distributing-release-bundles)
81+
- [JFrog Distribution V2 Task](#jfrog-distribution-v2-task)
82+
- [Contribution](#contribution)
83+
- [Building](#building)
84+
- [Testing](#testing)
85+
- [Skipping Tests](#skipping-tests)
86+
- [Reporting issues](#reporting-issues)
6487

6588
## Download and Installation
6689

@@ -661,6 +684,12 @@ The full documentation of Conan is available at the [conan website](https://docs
661684
pathOrReference: './'
662685
buildName: '$(Build.DefinitionName)'
663686
buildNumber: '$(Build.BuildNumber)'
687+
- task: JFrogConanV2@2
688+
inputs:
689+
conanCommand: 'Install'
690+
pathOrReference: './'
691+
buildName: '$(Build.DefinitionName)'
692+
buildNumber: '$(Build.BuildNumber)'
664693
```
665694

666695
For more information about Conan repositories,

tasks/JFrogConanV2/conanBuild.js

+246
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
const conanutils = require('./conanUtils.js');
2+
const tl = require('azure-pipelines-task-lib/task');
3+
const utils = require('@jfrog/tasks-utils/utils.js');
4+
5+
function run() {
6+
let conanCommand = tl.getInput('conanCommand', true);
7+
8+
// Handle different conan commands
9+
switch (conanCommand) {
10+
case 'Config Install':
11+
handleConfigInstallCommand();
12+
break;
13+
case 'Add Remote':
14+
handleAddRemoteCommand();
15+
break;
16+
case 'Create':
17+
handleCreateCommand();
18+
break;
19+
case 'Install':
20+
handleInstallCommand();
21+
break;
22+
case 'Upload':
23+
handleUploadCommand();
24+
break;
25+
case 'Custom':
26+
handleCustomCommand();
27+
break;
28+
default:
29+
tl.setResult(tl.TaskResult.Failed, 'Conan Command not supported: ' + conanCommand);
30+
}
31+
}
32+
33+
/**
34+
* Handle Conan Config Install Command
35+
*/
36+
function handleConfigInstallCommand() {
37+
let configSourceType = tl.getInput('configSourceType', true);
38+
let configInstallItem = tl.getInput('configInstallItem', true);
39+
let extraArguments = tl.getInput('extraArguments', false);
40+
41+
let conanArguments = ['config', 'install'];
42+
conanArguments = addExtraArguments(conanArguments, extraArguments);
43+
conanArguments.push('--type');
44+
conanArguments.push(configSourceType);
45+
conanArguments.push(configInstallItem);
46+
47+
conanutils
48+
.executeConanTask(conanArguments)
49+
.then(() => {
50+
setTaskResult(true);
51+
})
52+
.catch((err) => {
53+
console.error('Failed to execute Conan Task: ' + err.message);
54+
setTaskResult(false);
55+
});
56+
}
57+
58+
/**
59+
* Handle Conan Add Remote Command
60+
*/
61+
function handleAddRemoteCommand() {
62+
let remoteName = tl.getInput('remoteName', true);
63+
let artifactoryService = tl.getInput('artifactoryConnection', true);
64+
let artifactoryUrl = tl.getEndpointUrl(artifactoryService, false);
65+
let artifactoryUser = tl.getEndpointAuthorizationParameter(artifactoryService, 'username', true);
66+
let artifactoryPassword = tl.getEndpointAuthorizationParameter(artifactoryService, 'password', true);
67+
let artifactoryAccessToken = tl.getEndpointAuthorizationParameter(artifactoryService, 'apitoken', true);
68+
let conanRepo = tl.getInput('conanRepo', true);
69+
let purgeExistingRemotes = tl.getBoolInput('purgeExistingRemotes', true);
70+
71+
if (artifactoryAccessToken) {
72+
// Access token is not supported.
73+
console.error(
74+
'Access Token is not supported for authentication with Artifactory, please configure Artifactory service connection' +
75+
' to work with basic authentication.'
76+
);
77+
setTaskResult(false);
78+
return;
79+
}
80+
81+
let conanArguments = [
82+
'remote',
83+
'add',
84+
remoteName,
85+
utils.stripTrailingSlash(artifactoryUrl) + '/api/conan/' + conanRepo,
86+
'--index',
87+
'0',
88+
'--force',
89+
];
90+
91+
// Purge existing
92+
if (purgeExistingRemotes) {
93+
try {
94+
conanutils.purgeConanRemotes();
95+
} catch (err) {
96+
console.error('Failed to purge Conan Remotes: ' + err.message);
97+
setTaskResult(false);
98+
return;
99+
}
100+
}
101+
102+
// Add remote repo configuration
103+
conanutils
104+
.executeConanTask(conanArguments)
105+
.then(() => {
106+
// Add user credentials
107+
conanArguments = ['remote', 'login', '--password', artifactoryPassword, remoteName, artifactoryUser];
108+
conanutils.executeConanTask(conanArguments).then(() => {
109+
setTaskResult(true);
110+
});
111+
})
112+
.catch((err) => {
113+
console.error('Failed to execute Conan Task: ' + err.message);
114+
setTaskResult(false);
115+
});
116+
}
117+
118+
/**
119+
* Handle Conan Create Command
120+
*/
121+
function handleCreateCommand() {
122+
let createPath = tl.getPathInput('createPath', true, true);
123+
let extraArguments = tl.getInput('extraArguments', false);
124+
125+
let conanArguments = ['create'];
126+
conanArguments = addExtraArguments(conanArguments, extraArguments);
127+
conanArguments.push(createPath);
128+
129+
conanutils
130+
.executeConanTask(conanArguments)
131+
.then(() => {
132+
setTaskResult(true);
133+
})
134+
.catch((err) => {
135+
console.error('Failed to execute Conan Task: ' + err.message);
136+
setTaskResult(false);
137+
});
138+
}
139+
140+
/**
141+
* Handle Conan Install Command
142+
*/
143+
function handleInstallCommand() {
144+
let pathOrReference = tl.getInput('pathOrReference', true);
145+
let extraArguments = tl.getInput('extraArguments', false);
146+
147+
let conanArguments = ['install'];
148+
conanArguments = addExtraArguments(conanArguments, extraArguments);
149+
conanArguments.push(pathOrReference);
150+
151+
conanutils
152+
.executeConanTask(conanArguments)
153+
.then(() => {
154+
setTaskResult(true);
155+
})
156+
.catch((err) => {
157+
console.error('Failed to execute Conan Task: ' + err.message);
158+
setTaskResult(false);
159+
});
160+
}
161+
162+
/**
163+
* Handle Conan Upload Command
164+
*/
165+
function handleUploadCommand() {
166+
let patternOrReference = tl.getInput('patternOrReference', true);
167+
let extraArguments = tl.getInput('extraArguments', false);
168+
169+
let conanArguments = ['upload'];
170+
conanArguments = addExtraArguments(conanArguments, extraArguments);
171+
// Enforce --confirm option since the command runs in a non-interactive mode
172+
enforceArgumentOrOption(conanArguments, '-c', '--confirm');
173+
conanArguments.push(patternOrReference);
174+
175+
conanutils
176+
.executeConanTask(conanArguments)
177+
.then(() => {
178+
setTaskResult(true);
179+
})
180+
.catch((err) => {
181+
console.error('Failed to execute Conan Task: ' + err.message);
182+
setTaskResult(false);
183+
});
184+
}
185+
186+
/**
187+
* Handle Conan Custom Command
188+
*/
189+
function handleCustomCommand() {
190+
let customArguments = tl.getInput('customArguments', true);
191+
let conanArguments = customArguments.split(' ');
192+
193+
conanutils
194+
.executeConanTask(conanArguments)
195+
.then(() => {
196+
setTaskResult(true);
197+
})
198+
.catch((err) => {
199+
console.error('Failed to execute Conan Task: ' + err.message);
200+
setTaskResult(false);
201+
});
202+
}
203+
204+
/**
205+
* Add extra arguments to list of options and arguments
206+
*
207+
* @param conanArguments (Array) - Collection of options and arguments
208+
* @param extraArguments (String) - String containing the input of extra options and arguments
209+
*/
210+
function addExtraArguments(conanArguments, extraArguments) {
211+
if (extraArguments && extraArguments.trim().length > 0) {
212+
let extraArgumentsArray = extraArguments.split(' ');
213+
return conanArguments.concat(extraArgumentsArray);
214+
}
215+
return conanArguments;
216+
}
217+
218+
/**
219+
* Enforce the presence of an option or argument in the list of arguments
220+
*
221+
* @param conanArguments (Array) - Collection of options and arguments
222+
* @param shortVersion (string) - Short version of option or argument
223+
* @param longVersion (string) - Long version of option or argument
224+
*/
225+
function enforceArgumentOrOption(conanArguments, shortVersion, longVersion) {
226+
if (conanArguments.indexOf(shortVersion) < 0 && conanArguments.indexOf(longVersion) < 0) {
227+
conanArguments.push(longVersion);
228+
}
229+
}
230+
231+
/**
232+
* Set Task Result
233+
*
234+
* @param taskSuccessful (Boolean) - Flag with task result.
235+
* True: Task was Successful.
236+
* False: Task failed.
237+
*/
238+
function setTaskResult(taskSuccessful) {
239+
if (taskSuccessful) {
240+
tl.setResult(tl.TaskResult.Succeeded, 'Conan Task finished.');
241+
} else {
242+
tl.setResult(tl.TaskResult.Failed, 'Conan Task failed.');
243+
}
244+
}
245+
246+
run();

tasks/JFrogConanV2/conanUtils.d.ts

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// conanUtils.d.ts
2+
// eslint-disable-next-line @typescript-eslint/no-namespace
3+
declare namespace conan_utils {
4+
function getCliPartialsBuildDir(buildName: string, buildNumber: string): string;
5+
}
6+
export = conan_utils;

0 commit comments

Comments
 (0)