How do you specify that an activity should not be parameterised in an exported ARM template, or ensure the parameter default value is whatever is already specified?
I have an ADF pipeline which contains a WebActivity. This WebActivity URL is set by an expression which concatenates some text with some pipeline parameters:
#concat(pipeline().parameters.URL,'path/',pipeline().parameters.ANOTHER_PARAMETER,'/morePath/', pipeline().parameters.YET_ANOTHER_PARAMETER,'/lastBitOfPath')
When I export the ADF template through the UI, there are some parameters added which look like: PIPELINE_NAME_properties_0_typeProperties, are type String, but are blank. These appear to correspond to the WebActivity URL fields in various activities.
If I then import that ARM template and parameter file into a new Data Factory, the WebActivity URL is blank. This means I need to override the parameter as normal, fine, but why....? I don't need a new parameter to specify a value that is already set by parameters... how do I ensure that this activity is imported with the same expression? It seems mad that to use a WebActivity means you have to parameterise the expression. I want the ARM Template > Export ARM Template to export what I've got, not add redundant parameters that I do not need.
I have also tried editing the pipeline JSON to add a default and defaultValue attribute for the URL activity, but they are removed and have no effect.
It seems the reason for this is that the parameterization template has been modified to include:
"Microsoft.DataFactory/factories/pipelines": {
"properties": {
...
"activities": [{
"typeProperties": {
"url": "-::string"
}
}
]
}
},
Which removes the default for all URL properties of all activities.
https://learn.microsoft.com/en-gb/azure/data-factory/continuous-integration-deployment#use-custom-parameters-with-the-resource-manager-template
This applies to all activites so it seems the only alternative is to specify
"url": "=::string"
Which will parameterise the URL (so any existing parameterization will continue to function) but keep the original value by default. Care must then be taken to override any other activity url properties that I do not wish to move.
Related
"inputs":[
{
"name":"PathtoPublish",
"type":"string",
"label":"Path to publish",
"defaultValue":"$(Build.ArtifactStagingDirectory)",
"required":true,
"helpMarkDown":"The folder or file path to publish.",
"visibleRule":"CommandType = Upload"
},
in this custom task i created, Path to publish will always be $(Build.ArtifactStagingDirectory), so what I'm trying to do is to hide this so it doesn't show up in the task. I'm not sure if there is an attribute to HIDE IT, i tried adding HideInput: true
"inputs":[
{
"name":"PathtoPublish",
"type":"string",
"label":"Path to publish",
"defaultValue":"$(Build.ArtifactStagingDirectory)",
"required":true,
"helpMarkDown":"The folder or file path to publish.",
"visibleRule":"CommandType = Upload",
"HideInput": true
},
According to the task.json schema, there isn't such an attribute to hide the input string $(Build.ArtifactStagingDirectory).
We can only use the visibleRule property to control the full visibility of the input label.
In your scenario, you have set "visibleRule":"CommandType = Upload", that means the input Path to publish will be displayed only when the Upload command type is selected.
Another related thread for your reference : Azure DevOps extension custom UI. Hope that helps.
I am trying to create an extension using node api which publishes a path variable on completion.
I did set outputVariables in task.json and tried to use both
tl.setVariable('outVar1', 'outVal1'))
tl.setTaskVariable('outVar1', 'outVal1'))
task.json (only outvariable section):
"OutputVariables": [
{
"name": "outVar1",
"description": "This publish a output variable."
}
],
I tried printing it in the subsequent steps in the same job using all the recomended constructs
$(taskName.outVar1)
$taskName.outVar1
$outVar1
$(outVar1)
But the variable is not visible. I also printed all the environment variables and the variable is not present there.
Is someone able to create an extension which outputs a variable successfully?
You don't need to declare an output variable fro this purpose.
Just set the variable:
tl.setVariable("varNamr","varValue", false);
The fasle indicate that is not a secret variable.
In the enxt steps you can use the variable wirh $(varName).
I'm struggling to figure out a way to populate a parameter for a downstream, freestyle project based on a value generated during my pipeline run.
A simplified example would probably best serve to illustrate the issue:
//other stuff...
stage('Environment Creation') {
steps {
dir(path: "${MY_DIR}") {
powershell '''
$generatedProps = New-Instance #instancePropsSplat
$generatedProps | Export-Clixml -Depth 99 -Path .\\props.xml
'''
stash includes: 'props.xml', name: 'props'
}
}
}
//...later
stage('Cleanup') {
unstash props
// either pass props.xml
build job: 'EnvironmentCleanup', wait: false, parameters: [file: ???]
// or i could read the xml and then pass as a string
powershell '''
$props = Import-Clixml -Path props.xml
# how to get this out of this powershell script???
'''
}
I create some resources in one stage, and then in a subsequent stage I want to kick off a job using those resources as a parameter. I can modify the downstream job however I want, but I am struggling to figure out how to do this.
Things I've tried:
File Parameter (just unstashing and passing through)
Apparently do not work with pipelines
Potential Paths:
EnvInject: may not be safe to use and apparently doesn't work with pipelines?
Defining a "global" variable like here, but I'm not sure how powershell changes that
So, what's the best way of accomplishing this? I have a value that is generated in one stage of a pipeline, and I then need to pass that value (or a file containing that value) as a parameter to a downstream job.
So here's the approach I've found that works for me.
In my stage that depends on the file created in a previous stage, I am doing the following:
stage ("Environment Cleanup') {
unstash props
archiveArtifacts "props.xml"
build job: 'EnvironmentCleanup', parameters: [string(name: "PROJECT", value: "${JOB_NAME}")], wait: false
}
Then in my dependent job (freestyle), I copy the "props.xml" file from the triggering build and using the job name passed in as a parameter, then execute my powershell to deserialize the xml to an object, and then read the properties I need.
The last, and most confusing, part I was missing was in the options for my triggering pipeline project I needed to grant copy permission to the downstream job:
options {
copyArtifactPermission('EnvironmentCleanup') // or just '*' if you want
}
This now works like a charm and I will be able to use it across my pipelines that follow this same workflow.
I'm developing an extension to VSTS. The tasks are written in JavaScript.
In the extension, there is a string input field. In this input, the user can enter a path in his file system. The user can use the agent's environment variables, such as ${'Build.SourcesDirectory'}. During the task, I read the input variable by getInput() function of vsts-task-lib/task library.
The problem: I need to get the raw string input in order to process it during the task. For example, instead of c:\agent\_work\1\s i'd prefer to get ${'Build.SourcesDirectory'}.
This is the input field in
task.json:
{
"name": "myName",
"type": "multiLine",
"label": "My Label",
"required": true,
"properties": {
"resizable": "true",
"rows": "10",
"maxLength": "10000"
}
}
The variable value is replaced by the system as soon as the build start. So getInput() method can only get its value rather than the original string. If you do want that strings, call the Rest API to parse the build definition settings.
I have created an AEM Dialog which prompts the user for a set of links and labels.
These links and labels are stored in a jcr node and are used to generate a menu.
To avoid having to create a custom xtype, I am using the acs-commons multifieldpanel solution, which enables me to nest children under the fieldConfig node.
This works great with only 1 Label/Link pair, but when I add a second one - the property cannot be fetched anymore, since instead of a String, it returns the String hashcode.
The property generated by the multifieldpanel in the jcr node is of type String and is filled correctly when inspecting in CRXDE. The problem occurs when I try to fetch the value from within a Sightly HTML file.
Code
Dialog:
Definitions.js:
"use strict";
use(function () {
var CONST = {
PROP_URLS: "definitions",
};
var json = granite.resource.properties[CONST.PROP_URLS];
log.error(json);
return {
urls: json
};
});
Log output
1 element in multifieldpanel
jcr node variable content
definitions: {"listText": "facebook", "listPath": "/content/en"}
log output
{"linkText":"facebook","linkPath":"/content/en"}
Multiple elements in multifieldpanel
jcr node variable content
definitions: {"listText": "facebook", "listPath": "/content/en"},{"listText": "google", "listPath": "/content/en"}
log output
[Ljava.lang.String;#7b086b97
Conclusion
Once the multifieldpanel has multiple components and stores it, when accessing the property the node returns the String hashcode instead of the value of the property.
A colleague has pointed out that I should use the MultiFieldPanelFunctions class to access the properties, but we are using HTML+Sightly+js and are trying to avoid .jsp files at all cost. In JavaScript, this function is not available. Does anyone have any idea how to solve this issue?
That is because, when there is a single item in the multifield, it returns a String, where as it returns a String[] when there is more than a single item configured.
Use the following syntax to read the property as a String array always.
var json = granite.resource.properties[CONST.PROP_URLS] || [];
Additionally, you can also use TypeHints to make sure your dialog saves the value as String[] always, be it single item or multiple items that is configured.
Don't forget that the use() in JS is compiled into Java Byte code and if you are reading Java "primitives", make sure you convert them to JS types. It's part of the Rhino subtleties.
On another note, I tend to not use the granite.* because they are not documented no where, I use the Sightly global objects instead https://docs.adobe.com/content/docs/en/aem/6-0/develop/sightly/global-objects.html
To access properties, I use properties.get("key")
Hope this help.