I am writing a simple Bazel rule that uses ctx.actions.run. Unfortunately, I have a hard time understanding inputs param of run action.
The doc says inputs is "a list or depset of the input files of the action". What if my action just runs an executable and passes a few file paths as its arguments ? Suppose I specify the arguments as arguments parameter of the run action. Do I still need to add these file paths to the inputs parameter ? Why ?
The inputs parameter tells Bazel what files to make available to the executable of the action when Bazel runs it. This parameter is important for a few reasons:
It tells Bazel what other actions need to be run to produce the input files for the given action. If you have Action1 <- Artifact <- Action2, where Action2 produces Artifact, and Action1 takes Artifact as an input, Bazel knows to run Action2 before Action1.
It tells Bazel what files to make available in the action sandbox. Otherwise the action won't be able to find any of its input files.
It tells Bazel what files to upload to remote execution workers, if remote execution is being used. Otherwise the file won't be available on the remote machine for the action to read.
The arguments parameter of ctx.actions.run tells Bazel what the command line for the executable of the action is. If your executable takes flags like --input and --output, you'd use arguments to construct a command line like --input artifact1 --input artifact2 --output artifact3.
See this example: https://github.com/bazelbuild/examples/blob/master/rules/actions_run/execute.bzl
Related
I have added an annotation processor as a java_plugin and have added this into the plugins section of my java_library rule. I was wondering what are the bazel options to step through the annotation processor code and the javac compiler's code?
One way to do this is to run bazel build with --subcommands. Bazel will then print out all the commands it executes during a build. You can then find the javac invocation you're interested in, copy the command line (including the cd part so you're in the correct directory), modify the command line to include the debugging options, and run it manually. Then you can debug it like you would any java program.
One thing to note is that bazel will print only the commands that it actually runs in that build, so if the action you're interested in is already up-to-date, you may have to delete one of its outputs (e.g. the jar output of that library) to get bazel to re-run the action.
We're considering migrating to Bazel from Make. To make the transition easier I would like to have bazel test (no flags / options) run the current directory's tests, if any.
So instead of bazel test my_tests bazel test would find the current directory's BUILD file, find any *_test rules and run those.
If you want to do exactly as you said then you can use your own script.
When you run “bazel” it actually looks to see if there is a script named “bazel” under tools directory of the current workspace. So if you have an executable under “$workspace/tools/bazel” bazel will run that instead of the bazel binary itself.
This means you can write a script that checks if the only argument is “test” and if so calls “bazel-real test :all”
It can also check the exit code to see if there were no tests (it’s a specific error code) and return 0 instead
You can use the all target pattern to match all targets in the current package: bazel test :all
You can read more about it here: https://docs.bazel.build/versions/master/user-manual.html#target-patterns
Note however that if there are no test targets in the current package, bazel will give an error: "ERROR: No test targets were found, yet testing was requested.". In this case bazel will give an exit code of 4: https://docs.bazel.build/versions/master/user-manual.html#what-exit-code-will-i-get
I recommend creating a alias called bazel-test to bazel test :all.
I am new to Jenkins and even though I found a few similar questions, none of the solutions seemed to work for me the way I need it to. It might look like a basic problem to some but for me it's a very big deal that I'm struggling with.
Basically, I built a project that executes Java Selenium code, which displays session ID in Jenkins' Console Output and that's what I need to add to environment variables to be used in the projects triggered after completion of this one.
I tried some Groovy scripts but I don't think I understand enough how to work with it and so whatever I was given, wasn't what I hoped to get.
Has anyone done something similar to provide some tips on how to achieve that?
Many thanks
There are two options (in theory, one of them doesn't work, see 2. below) depending on whether the printing is under your control or not.
Printing is under your control:
Write the session ID to a properties file, e.g. from-build-log.properties:
sessionId=...
Add post-build action → Trigger parameterized build on other projects →
This plugin triggers builds on other projects, with parameters that are predefined, or supplied by the finished build.
Every parameter will be passed to the target project(s), even if the target is not parameterized, or if no property of that name is defined.
Add parameters → Parameters from properties file
Use properties from file: from-build-log.properties
Printing is not under your control:
Add post-build action → Post build task → :
This feature allows you to associate shell or a batch scripts that perform some tasks on Hudson depending on the build log output. If the log text matches somewhere in the build log file, the script will execute. [...]
Java Regex are allowed, and groups can be used as script parameters. If the text is "Last Build : #(\d+)" and the script is "script.sh", then if the log contains a line "Last Build : #4", the script "script.sh 4" will be called.
Tasks → Script → :
[...] References %1, .. %n are allowed, and will be replaced by the groups matched by the Regex. %0 is the whole match.
Unfortunately this doesn't to work since there is an issue known since 2013: [JENKINS-17268] Post build task plugin: Passing arguments does not work as documented.
Build → Execute Windows batch command → Command:
#echo( & echo CMD: sessionId=123456789
Post build task → Tasks:
Log text: sessionId=(\d+)
Script:
#echo( & echo sessionId='%1'(!) of '%0'
Console Output:
...
[Freestyle-project] $ cmd /c call C:\Windows\TEMP\hudson4684581005071706054.bat
CMD: sessionId=123456789
C:\Program Files (x86)\Jenkins\workspace\Freestyle-project>exit 0
Performing Post build task...
Match found for :sessionId=(\d+) : True
Logical operation result is TRUE
Running script : #echo( & echo sessionId='%1'(!) of '%0'
[Freestyle-project] $ cmd /c call C:\Windows\TEMP\hudson1525182929053902824.bat
sessionId=''(!) of 'C:\Windows\TEMP\hudson1525182929053902824.bat'
C:\Program Files (x86)\Jenkins\workspace\Freestyle-project>exit 0
POST BUILD TASK : SUCCESS
END OF POST BUILD TASK : 0
Finished: SUCCESS
%0 is not the "the whole match" but the script's name, as usual with Windows command line. %1 is empty.
A workaround is:
Add build step → Execute shell → Command:
sed -En 's/.*(sessionId=[0-9]+)/\1/p' \
../../jobs/${JOB_NAME}/builds/${BUILD_NUMBER}/log > from-build-log.properties
Add post-build action → Trigger parameterized build on other projects
Add parameters → Parameters from properties file
Use properties from file: from-build-log.properties
I have inherited a system which uses Jenkins Job DSL to build the jobs for all our projects, I have little experience with configuring Jenkins and none at all with Jenkins Job DSL, so please be gentle.
Some of these projects are Gradle projects. There is a function, createGradleJob() which creates the gradle job. In this function we build the task list for the job, as a string, based upon some features of the project. e.g. if it is being built from the master branch we append the 'publish' task. All of these conditional tasks are currently appended based upon the projects branch name, or the presence , or absence of certain files in the projects repo.
I would like to now add a new task into this task list conditional upon the contents of some of these files. Specifically if certain keywords are detected in the projects build.gradle file then certain tasks need to be appended to the task list.
So, is there a way in Jenkins Job DSL to check the contents of a file and use that as a conditional expression?
I have found that I can execute arbitrary shell commands using the shell function, so I thought I could just grep the file, but I can't locate the documentation for this function, so I'm not clear how I can able to access the output of the commands, so as to use them in a conditional expression.
I have found the textFinder function, but this appears to only allow you to fail (or mark as unstable) the build as a result of finding or failing to find, the text, not use the result as a conditional expression.
It sounds like you want to readFileFromWorkspace. It returns the contents of the file as a string. Simply read your file and parse the string as needed using the Groovy and/or Java string utils.
It's not quite clear from your question, but if you're talking about reading files out of the repo to be checked out by the job you're generating, this function won't help. But if the file is already somewhere in the workspace (i.e. it's one of the files checked out by the seed job), you'll be fine.
The shell command you found adds an "Execute Shell Script" build step to the job being generated. It doesn't actually execute the script there and then, it just copies the contents of the parameter verbatim into the build step ready to be executed when Jenkins runs the job.
For your continued sanity, here is a link to the Job DSL API Documentation
While troubleshooting a problem with apache-ivy, I want to call an ant target named -ivy-info defined in my build.xml. My -ivy-info target calls the ivy:info task and the ivy:buildnumber task and calculates the next revision number.
Problem is the ant command-line interprets the -ivy-info as a command-line option then fails with: Unknown argument: -ivy-info
One workaround I have found is to change the default target to -ivy-info via the first line of build.xml: <project name="my.project" default="-ivy-info"> and then run ant with no arguments, which works fine.
Other options are to rename the -ivy-info target so it does not start with a '-' character, or to create a new empty target with a name not starting with '-' and that includes -ivy-info as a dependency.
However I still want to know if there is any way that doesn't involve first editing build files?
Anything starting with a "-" will be interpreted into an command-line argument, not a target. For example, there are usages like ant -f build-actual.xml or ant -Dproperty=value -- they are all Ant's command-line arguments. If you pass -ivy-info from command-line, of course, it is treated as an argument.
There's no way to run -ivy-info directly from command-line due to the argument parsing; and specifying it as the default target works because it is parsed by the xml parser, not command-line argument parser.
With this, when writing a build file, one can use "-" to prevent a target from being called directly from command-line (just like private methods in OO-languages). If the build file is not written by you, then the author doesn't want you to run it directly from command-line.
If you are sure that the target can be called directly from command-line, just rename it.