Bazel: How to access workspace status variables in Skylark? - bazel

I'm using the --workspace_status_command with stable status variables similarly to the Kubernetes test-infra usage.
I would like to expose the STABLE_* variables to custom Skylark rules. How should I do that?

rules_docker supports stamping from the workspace status files. It looks like it uses ctx.info_file and ctx.version_file to access them: https://github.com/bazelbuild/rules_docker/blob/4d8ec6570a5313fb0128e2354f2bc4323685282a/container/layer_tools.bzl#L83
They aren't in the published docs but the Bazel source code seems to show that those are the right thing: https://github.com/bazelbuild/bazel/blob/0.12.0/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java#L987-L1011

Related

Difference between $(Build.Repository.LocalPath) and $(Build.SourcesDirectory) in TFS Build Online 2017

I am trying to figure out if there is a difference between the two pre-defined variables in TFS Online 2017: $(Build.Repository.LocalPath) and $(Build.SourcesDirectory). I have a build that uses these two variables and didn't know if I could use them interchangeably or not.
Looking at Microsoft's documentation the descriptions are as follows:
$(Build.SourcesDirectory): The local path on the agent where your source code files are downloaded. For example: c:\agent_work\1\s
By default, new build definitions update only the changed files. You can modify how files are downloaded on the Repository tab.
$(Build.Repository.LocalPath): The local path on the agent where your source code files are downloaded. For example: c:\agent_work\1\s
By default, new build definitions update only the changed files. You can modify how files are downloaded on the Repository tab.
Are these representing the same thing or am I missing something?
They're synonyms. Most standard templates and tasks use the $(Build.SourcesDirectory), so that is what I tend to use.
They often result in the same but not necessarily. As described in the docs:
If you check out multiple repositories, the behavior is as follows (and might differ from the value of the Build.SourcesDirectory variable):
The description for Build.SourcesDirectory on the same page contains a similar note.
Basically if you want to define a custom path for the self checkout and still not need to specify the extra dir, you specifically need Build.Repository.LocalPath.
For clarity, you can still use Build.SourcesDirectory to resolve to the full path if you have the usual
- checkout: self
path: s
and I'd recommend using it whenever possible if so. If you have something like
- checkout: self
path: main_project
then you'd need $(Agent.BuildDirectory)/main_project to reach the same.

Check out stream from AccuRev without workspace or reference tree

Since you can not delete a workspace or reference tree in AccuRev (only deactivate it), we want to create local copy of a streams contents, without using those.
I could ofcourse use something like accurev hist in combination with accurev cat, but that sounds like an awful workaround for such a basic functionality.
So, I wonder, is there an easy command to do this?
I only want to use this in my Jenkins CI environment to check the sources (compile, run tests, etcetera). I never have to push any changes back to AccuRev, so the AccuRev gurus would probably recommend using a reference tree.
However, I want to create these dynamically and they will only be used once.
It does not seem like a good idea to clutter the AccuRev server with thousands of unused reference trees.
You can use the accurev pop command to do exactly what you want. Within Jenkins, this is the equivalent of using the option of "Neither" a workspace or reference tree if you are using the AccuRev plug-in for Jenkins.
If you prefer to script this yourself, you can use accurev pop -R -v <stream-name> -L <some-directory-location> /./ where you substitute in your stream name and the directory location to which you want to write. The /./ in the command tells AccuRev to populate the depot root directory and -R is to recurse the entire contents below that. You can specify another directory below that level using its depot relative path.

aliasing jenkins artifact URLs

Jenkins artifact URLs allow abstracting the "last successful build", so that instead of
http://myjenkins.local/job/MyJob/38/artifact/build/MyJob-v1.0.1.zip
we can say
http://myjenkins.local/job/MyJob/lastSuccessfulBuild/artifact/build/MyJob-v1.0.1.zip
Is it possible to abstract this further? My artifacts have their version number in their filename, which can change from build to build. Ideally I'd like to have a some kind of "alias" URL that looks like this:
http://myjenkins.local/job/MyJob/lastSuccessfulBuild/artifact/build/MyJob-latest.zip
MyJob-latest.zip would then resolve to MyJob-v1.0.1.zip.
If Jenkins itself can't do this, perhaps there's a plugin?
Never seen any such plugin, but Jenkins already has a similar functionality built-in.
You can use /*zip*/filename.zip in your artifact path, where filename is anything you choose. It will take all found artifacts, and download them in a zipfile (you may end up with a zip inside a zip, if your artifact is already a zip file)
In your case, it will be:
http://myjenkins.local/job/MyJob/lastSuccessfulBuild/artifact/build/*zip*/MyJob-latest.zip
This will get you the contents of /artifact/build/ returned in zipped archive with name MyJob-latest.zip. Note that if you have more than just that zip file in that directory, other files will be returned too.
You can use wildcards in the path. A single * for a regular wildcard, a double ** for skipping any number of preceding directories.
For example, to get any file that starts with MyJob, ends with .zip, and to look for it in any artifact directory, you could use:
/lastSuccessfulBuild/artifact/**/MyJob*.zip/*zip*/MyJob-latest.zip
Edit:
You cannot do something like this without some form of a container (a zip in this case). With the container, you are telling the system:
Get any possible [undetermined count] wildcard match and place into this container, then give me the container. This is logical and possible, as there is only one single container, whether it is empty or not.
But you cannot tell the system:
Give me a link to a specific single file, but I don't know which one or how many there are. The system can't guarantee that your wildcards will match one, more than one, or none. This is simply impossible from a logic perspective.
If you need it for some script automation, you can unzip the first level zip and be still left with your desired zipped artifact.
If you need to provide this link to someone else, you need an alternative solution.
Alternative 1:
After your build is complete, execute a post-build step that will take your artifact, and rename it to MyJob-latest.zip, but you are losing versioning in the filename. You can also chose to copy instead of rename, but you end up with double the space used for storing these artifacts.
Alternative 2 (recommended):
As a post-build action, upload the artifact to a central repository. It can be Artifactory, or even plain SVN. When you upload it, it will be renamed MyJob-latest.zip and the previous one would be overwritten. This way you have a static link that will always have the latest artifact from lastSuccessfulBuild
There is actually a plugin to assign aliases to build you've run, and I have found it pretty handy: the Build Alias Setter Plugin.
You can use it for instance to assign an alias in the form of your own version number for a build, instead (or rather in addition) to the internal Jenkins-assigned build number.
I found that it is usually most practical to use it in conjunction with the EnvInject plugin (or your favorite variant): you would export an env variable (e.g. MY_VAR=xyz) with a value to the target version or moniker, and then use the form ${ENV,var="myvar"} in the "Token Macro alias" config that the plugin provides in your job config.
You can also use it to assign aliases in the form of "lastSuccesful" if you have such a need, which allows you to distinguish between different types of successful (or other state) builds.
Wait thee's more! You can also use the /*zip*/ trick in conjunction with the alias setter as well.

Using environment variables with Jenkins

I'm building a group of projects from the SVN. There is a possibility of changing the SVN location time to time. As there are bunch of projects I hope to give the repository url with a environment variable so i can change all the url's easily. Any idea how to do that??
In Subversion Source Code Management, you can use variable in the Repository URL, simply type:
http://my.svn.com/path/to/${VARIABLE}
${VARIABLE} is a job parameters that is defined earlier. Never heard of anyone wanting to use actual environment variables for this, but you can try with the same syntax.
By default, it will give you a red warning that this is not a valid URL. You can disable this warning by going to Manage Jenkins -> Configure System and look for Validate repository URLs up to the first variable name. Put a checkmark there and save.

How do I change Jenkins build folder? (SVN_REVISION instead of BUILD_ID)

How do I change the build folder Jenkins use? Jenkins uses BUILD_ID (timestamp) to create folders inside \builds\ so they look like "2012-12-14_10-17-15". Is there a way to use the SVN_REVISION instead?
Maybe I should just create a shortcut on C:\Builds\ using SVN_REVISION that points to jenkins\jobs\job_name\builds\build_id, but I wish there was another way to do this.
Instead of modifying Jenkins internals, you could add another step at the end of your project that dumps the SVN_REVISION and BUILD_ID information somewhere, maybe into a CSV file depending on what you are trying to do. You could even add a step to create shortcuts for you.

Resources