I have a wscript which reads some files during the configure step and based on this sets some variabales.
How do I get waf to automatically re-configure the project, if one of the configuration files change, when running waf build instead of waf configure build?
Consider the following scenario:
waf configure
waf build
The content in configuration file a.config is changed
the user just runs waf build, instead of waf configure build.
--> How must the wscript look like, that it checks before running build if the configuration files have changed, and if so, the project is reconfigured before running build?
Example:
There is a file a.config and the wscript looks like this:
# wscript
def configure(conf):
a = conf.path.find_node('a.config')
conf.env.config = a.read()
def build(bld):
# check the configuration files are up to date.
# actual build
pass
configure is not really for that. You can use the same code but in build:
def build(bld):
a = bld.path.find_node('a.config')
bld.env.config = a.read()
bld(features = "myfeature", vars = ["config"], ...)
You can directly use configure with autoconfig:
from waflib import Configure
def options(opt):
Configure.autoconfig = True
def configure(conf):
conf.env.config = "my_value"
def my_processing(task):
print "Processing..."
def build(bld):
bld(rule = my_processing, vars = ["config"])
Any change to conf.env.config will trigger rebuild.
If you need to have separate config files, you can use load:
def configure(conf):
pass
def my_processing(task):
print "Processing..."
def build(bld):
bld.load("my_config", tooldir="my_config_dir")
bld(rule = my_processing, vars = ["config1", "config2"])
with a my_config_dir/my_config.py file like that:
def build(bld):
bld.env.config1 = "one"
bld.env.config2 = "two"
# ...
bld.load() will execute the build function in my_config.
Any change to config1 or config2 will trigger rebuild
Related
I am using a multibranch pipeline and would like to have branch specific configs. I currently have a default config which I would like to clone to a config with ID "${BRANCH_NAME}_config". I am using default jenkins file plugin so there is no jenkins code in the repository and using Config-file-provider-plugin for the config file handling and have made some progress.
I currently have the ability to create a global config with the following code:
configFileProvider([configFile(fileId: 'DEFAULT_JSON_CONFIG', variable: 'default_config_content')]) {
def instance = Jenkins.getInstance()
def provider = instance.getExtensionList('org.jenkinsci.plugins.configfiles.json.JsonConfig$JsonConfigProvider')[0]
def config = new org.jenkinsci.plugins.configfiles.json.JsonConfig("${BRANCH_NAME}_config", "Config for ${BRANCH_NAME}", "Branch config ${BRANCH_NAME}", "$default_config_content")
provider.save(config)
}
But need to create it in the job's (multipipeline) config folder
I was able to implement this with help from JENKINS-56305
def folder = Jenkins.instance.getItemByFullName('jobName');
def action = folder.getAction(org.jenkinsci.plugins.configfiles.folder.FolderConfigFileAction.class);
def store = action.getStore();
def config = new org.jenkinsci.plugins.configfiles.json.JsonConfig("XXXX_config", "Config for XXXX", "Branch config XXXX", "{A:B}");
// save the new config
store.save(config);
// get the new config
def jsonConfig = store.getById("XXXX_config");
// remove the config
store.remove("XXXX_config");
I am calling a shared library groovy script from my Jenkins pipeline.
Using the pwd() method I can properly get the workspace path and I can even see the required file in the exact same location in the Jenkins node.
Still I am getting following error:
java.io.FileNotFoundException: C:\Jenkins\workspace\Demo\test\target\site\xyz\abc.csv (No such file or directory)
I have the groovy-scripts/vars/generateHtml.groovy shared library which is being called from the pipeline as generateHtml(). The relevant code snippet:
def call() {
def ws = pwd()
echo "path ${ws}: generateHtml>start"
def targetPath = "${ws}\\target\\"
def resultFile = targetPath + 'site\\xyz\\abc.csv'
def data = parseCsv(new File(resultFile).getText('UTF-8'))
...
Reading a file in Jenkins Pipelines goes via readFile. Don't use plain groovy for I/O.
I want to use environment variable "WORKSPACE" in the active choice plugin groovy script.
I tried to retrieve it like this but it didnt work. WORKSPACE is not recognised.
${WORKSPACE}
Can anyone help me here?
Snippet:
def sout = new StringBuffer(), serr = new StringBuffer()
def proc ='/test/script.sh'.execute()
proc.consumeProcessOutput(sout, serr)
proc.waitForOrKill(1000)
println sout
Here instead of /test/script.sh i need to access the script as following:
def process='$workspace path/test/script.sh
It's not possible to get that "environment" variable. A better name would be "property". Those are dynamically generated by Jenkins when the build starts, not when the parameters are set.
You can get some environment variables with EnvVars when you're setting the parameters, but they are very few. This can be tested on the Jenkins Script Console with the following code:
import hudson.EnvVars
for (envVarName in EnvVars.masterEnvVars.keySet()) {
def envVarValue = EnvVars.masterEnvVars[envVarName]
println("${envVarName}=${envVarValue}")
}
Result:
_=/etc/alternatives/java
HOME=/home/jenkins
LANG=en_US.UTF-8
LOGNAME=jenkins
NLSPATH=/usr/dt/lib/nls/msg/%L/%N.cat
PATH=/sbin:/usr/sbin:/bin:/usr/bin
PWD=/
SHELL=/bin/bash
SHLVL=2
TERM=xterm-256color
USER=jenkins
XFILESEARCHPATH=/usr/dt/app-defaults/%L/Dt
WORKSPACE property has more to it. The directory may not exist when you launch the build, specially if it's the first time you are doing it. My recommendation, if it makes sense to you, is to place the script in userContent directory and work out the rest based on that.
I need to monitor what are the changes going with a job on jenkins(update the changes to a file). Need to list the env variables of a job. JOB_NAME,BUILD_NUMBER,BUILD_STATUS,GIT_URL for that build(all the builds of a job). I didn't find out a good example with the groovy. What is the best way to fetch all the info?
build.getEnvironment(listener) should get you what you need
Depending on what you would like to achieve there are at least several approaches to retrieve and save environment variables for:
current build
all past builds
Get environments variables for current build (from slave)
Execute Groovy script
// Get current environment variables and save as
// a file in $WORKSPACE.
new File(".",'env.txt').withWriter('utf-8') { writer ->
System.getenv().each { key, value ->
writer.writeLine("${key}:${value}")
}
}
Using Groovy Plug-in.
Get environment variables for current build (from master)
Execute system Groovy script
// Get current environment variables and save as
// a file in $WORKSPACE.
import hudson.FilePath
def path = "env-sys.txt"
def file = null
if (build.workspace.isRemote()) {
file = new FilePath(build.workspace.channel, build.workspace.toString() + "/" + path)
} else {
file = new FilePath(build.workspace.toString() + "/" + path)
}
def output = ""
build.getEnvironment(listener).each { key, value ->
output += "${key}:${value}\n"
}
file.write() << output
Using Groovy Plug-in.
Environment variables returned by Groovy scripts are kept in map. If you don't need all of them, you can access individual values using standard operators/methods.
Get environment variables for all past builds (from master)
This approach expecst that you have installed EnvInject Plug-in and have access to $JENKINS_HOME folder:
$ find . ${JENKINS_HOME}/jobs/[path-to-your-job] -name injectedEnvVars.txt
...
ps. I suspect that one could analyze EnvInject Plug-in API and find a way to extract this information directly from Java/Groovy code.
Using EnvInject Plug-in.
To look for only specific variables you can utilize find, grep and xargs tools .
You can use below script to get the Environment Variables
def thread = Thread.currentThread()
def build = thread.executable
// Get build parameters
def buildVariablesMap = build.buildVariables
// Get all environment variables for the build
def buildEnvVarsMap = build.envVars
String jobName = buildEnvVarsMap?.JOB_NAME // This is for JOB Name env variable.
Hope it helps!
I am using the grails-cdn-asset-pipline plugin. I've gone through the installation and configuration steps on GitHub and I reach the usage section which says
Add this command to your build process (usually before war generation and deployment).
// If all the settings are defined in your Config.groovy
grails asset-cdn-push
// Or
grails asset-cdn-push --provider=S3 --directory=my-bucket --gzip=true --storage-path=some-prefix --expires=365 --region=eu-west-1 --access-key=$MY_S3_ACCESS_KEY --secret-key=$MY_S3_SECRET_KEY
Where in my project do I put this command?
Is it something that I can do within the context of my project, or do I need to keep it separate in another build process and run it in an environment like Jenkins?
In _Events.groovy, I tried to invoke the script in the eventCreateWarStart, but I am having no luck there. (Code taken from this question)
eventCreateWarStart = { warName, stagingDir ->
def pluginManager = PluginManagerHolder.pluginManager
def plugin = pluginManager.getGrailsPlugin("cdn-asset-pipline")
def pluginDir = plugin.descriptor.file.parentFile
Map<String, String> env = System.getenv()
final processBuilder = new ProcessBuilder()
processBuilder.directory(new File("${cdnAssetPipelinePluginDir}/scripts"))
processBuilder.command([env['GRAILS_HOME']+"/bin/grails","cdn-asset-push"])
println processBuilder.directory()
Process proc = processBuilder.start()
proc.consumeProcessOutput(out, err)
proc.waitFor()
}
This link explains the run-script functionality which was merged into Grails 1.3.6. But I ran into the same problem of not knowing where to run it automatically.