TeamCity :: How can I access teamcity build ID in Java - java

Teamcity Build ID (which is different from BUILD_NUMBER) is used in various URLs. I want to send an email having path of a build's artifacts/ overview etc.
In Java, we can get currently running teamcity build number as follows:
String tc_BuildNumber = System.getenv("BUILD_NUMBER");
This is because TC provides an environment variable namely BUILD_NUMBER.
But unfortunately, there is no environment variable corresponding to BUILD_ID.
TeamCity does provide Configuration parameters (like teamcity.build.id) and System property (like system.teamcity.auth.userId) but I don't know how to access these using Java. I want to read the value of teamCity.build.id jusy like we can read environment variables names mentioned in How to fetch the Value of Teamcity Configuration in java?

Are you executing the java code using a build runner?
If so, then you should be able to pass %system.teamcity.build.id% to the runner, and make it available to your code.
i.e. If you're using the command line runner
java -Dbuild_id=%system.teamcity.build.id%
which you can then access as system arguments
Or if you're using gradle, you can do something like
if (project.hasProperty("teamcity")) {
version = project.teamcity["teamcity.build.id"]
}
and pass 'version' to the java command line.
In maven, you can just access it using:
${teamcity.build.id}
in your pom.xml
(I could do with a little more info about how you're running java to answer this specifically)

I've noticed that lots of people want to know the answer to this question.
Fortunately with the help of comment from #Jayan I was able to do solve my exact problem which was how to get URL for build artifacts.
As mentioned in link https://confluence.jetbrains.com/display/TCD10/Patterns+For+Accessing+Build+Artifacts, by default, TeamCity uses Internal Build ID for the path that can be used to access build artifacts:
/repository/download/BUILD_TYPE_EXT_ID/BUILD_ID:id/ARTIFACT_PATH
Accessing build Id could be difficult in the runtime(That is the reason of this question), but we can also use Build Number to access artifacts
/repository/download/BUILD_TYPE_EXT_ID/BUILD_NUMBER/ARTIFACT_PATH
And as shown in my question build number can be accessed as
String BUILD_NUMBER= System.getenv("BUILD_NUMBER");
and
String BUILD_TYPE_EXT_ID = System.getenv("TEAMCITY_BUILDCONF_NAME");

Yes, but you can create env var with value "%system.teamcity.buildType.id%" and read it in build. After that you can do an api request like:
$APIURL = "${API_BaseUrl}/httpAuth/app/rest/builds/?locator=buildType:${API_BuildType},state:running,count:1"
$APIXML = (Invoke-RestMethod -Headers $API_CredentialsHeader -Credential $API_Credentials -Uri $APIURL -Method GET -ContentType "application/xml" -TimeoutSec 20)
# Here you build id.
$APIXML.builds.build.id
This is PS example. But idea the same. In Java that might be more easy.

A link to a TeamCity build can use build number instead of buildID. But, it requires buildTypeId as well (can be seen in build configuration page URL).
A sample of such link is:
https://buildserver/viewLog.html?buildTypeId=Project_Trunk&buildNumber=46523
Hope this helps someone.

Related

Get dynamically build number of Intellij IDEA (maven)

I'm using maven to build and run my project on Intellij IDEA.
For tracking purposes I would like to be able to get/fetch the build number associated on VCS/Localhistory directly into my java code. Rather than get the number, if I was able to create my own and set the build number on local history it should be ok.
Like you see on that picture, I would like to get 6826bed7 or 40cfe86c like this :
public static void main(...) {
// Stuff like this
String buildNumber = IntellijInternalApi.getThisBuildNumber();
// this should print 6826bed7 in my example
System.out.println(builNumber);
}
Any idea or solution ?
Forget about it, 1) most probably you do not want to have intellij api in your application classpath
2) you dont have git information in runtime, this is the property of your working copy, not binary distribution.
You have to create this information on build stage, and write to properties file, then just simply read the value. You can do this either using git rev-parse HEAD or git decribe using maven exec-plugin, or use maven-git-commit-id-plugin
Actually, your question is duplicate of Injecting current git commit id into Java webapp

How to buld a Maven project with a specified java home property in eclipse?

I want to build a maven integrated project with a given java home property. At exactly i want to write a code in java that sets the java home property for an InvocationRequest object. The main goal is to build a project with the runtime given(by an algorithm) java home. So i would call getInvoker().execute(request); to execute maven goals where request is an InvocationRequest object.
I tried to set the request java.home property with properties.setProperty(Goals.JAVA_HOME, javaHomePath); and call the method executeGoals(pom, new String[] { Goals.INSTALL, Goals.CLEAN }, properties); . This executeGoals(...) method contains getInvoker().execute(request) call and the request object definition too.
Output is: Missing: 1) com.sun:tools:jar:1.5.0 #Solved
EDIT: solved the output problem, but a new one appeared:
class file has wrong version 50.0, should be 49.0. Maybe i changed the jre home, so i think i'm compiling with a newer version of java than i'm running with.
Reminder: i want to build with a specified java home property = i want to change the compiler java home(or version) to the specified one. (In eclipse)
I would appreciate any help.
I dont think it is configurable. It is part of the Maven Core to use the JAVA_HOME environment variable. Please see the accepted answer of:
How to set specific java version to Maven
Also it is not possible to set or change environment variables (not system properties) within a Java process (for the current process). If you create another process from within your Java process, there will be methods to specify environment variables for this sub process.
Maybe the solution will be to execute a Maven command e.g. "mvn clean install" with a specific JAVA_HOME variable set as sub process (this requires, that Maven is installed and mvn is available as command). Use the ProcessBuilder to switch into the working directory, where the pom.xml of the target project is located and set the appropriate environment variable(s) before starting the process.
If Maven should not be installed at the enviroment your application is running on, you could also distribute a Maven installation with your application (maybe in a separate directory). Then you could run against the mvn.bat or mvn.sh of this distribution (depending on the os).
When using Eclipse, Build in Run as Configuration, go to the Environment tab and add the new JAVA_HOME variable.
Do not forget to check the Replace native environment ..... option.
This will override your default OS variable. No need to change at the OS level.

How do I modify a Jenkins plugin to stop it from putting a link on build pages?

I'm trying to modify the existing EnvInject plugin so that the Environment Variables link it puts on a build's page is hidden. If I'm understanding the Jenkins API correctly, I should be able to do this by finding where the Action interface is implemented and having getIconFileName() return null.
I found that method implemented in EnvInjectAction.java and modified it to return null, but this had no effect--the link is still visible on build pages. I even tried modifying getDisplayName() and getUrlName() to also return null, but this also had no effect. Here is the modified method:
public String getIconFileName() {
return null;
}
I've taken care to follow the instructions for deploying a custom build of a core plugin from the Jenkins plugin tutorial, and I've also tried rebooting the machine that Jenkins is running on, all to no avail.
I'm clearly missing something vital, but I can't figure out what it could be. What else do I need to do to make the plugin not display the Environment Variables link?
Why do you want to do that? To hide sensitive information?
Are you aware of that even if you remove the link the variables can be displayed via:
http://jenkins/job/YourJob/1/injectedEnvVars?
Or according to the EnvInjectPlugin-VariablesTraceability:
"You can also get build environment variables by the following
HTTP GET URL: <jenkins_url>/job/<job_name>/<build_number>/injectedEnvVars/export"
However, if it's just to remove the link and modifying the plugin is not a must add the following to Jenkins' run/jenkins/war/css/style.css:
a[href*='/injectedEnvVars'] {
display: none;
}
Make a backup copy of the adapted style.css since it might get overwritten with a:
$ sudo service jenkins --full-restart
UPDATE
You can use a custom CSS with the following:
Manage Jenkins → Configure System → Theme → URL of theme CSS: ...
As answer to overcome comment limitations.
I looked into the source of the plugin and I can say that I'd chosen EnvInjectAction.java's getDisplayName() to apply the changes, as well. Since it contains return "Environment Variables"; and is the only file in the entire project that contains exactly that string.
I noticed that EnvIinjectAction is deprecated but that shouldn't do any harm anyway.
Have you tried to return an empty or an arbitrary string for testing rather than null. Maybe Jenkins itself doesn't like null being returned by this method. (But the next question is, why does it still display the original string of the plugin then.)
I even downloaded the jenkins-1.585 core sources and searched for invocations of getDisplayName() to check what is done with the value returned but there are 332 of them in src/main/java. I'm still trying to find the proper one.
Did you try the changed plugin on a local Jenkins on your machine? Maybe something went wrong while installing the plugin on the servers that are not maintained by yourself.
Have you considered contacting the maintainer Gregory Boissinot?

Want to know which Jenkins job is executing now, in java

I have 3 Jenkins job. Below are the name of those Jenkins job:
test_existing_api
test_others_api
test_new_api
I have a config file in java project which have 3 different configuration. I want to pick the configuration depend upon Jenkins job. So first I want to check which Jenkins job is executing and then I will take configuration according to that job. That configuration will further require in java code.
Please help me to understand how can I check which Jenkins job is executing now in Java.
Assuming you want to get this data within the job that is executing, see manual entry:
Jenkins Set Environment Variables
When a Jenkins job executes, it sets some environment variables that you may use in your shell script, batch command, Ant script or
Maven POM 1. The following table contains a list of all of these
environment variables.
Environment Variable Description
BUILD_NUMBER The current build number, such as "153"
BUILD_ID The current build id, such as "2005-08-22_23-59-59" (YYYY-MM-DD_hh-mm-ss)
BUILD_URL The URL where the results of this build can be found (e.g. http://buildserver/jenkins/job/MyJobName/666/)
NODE_NAME The name of the node the current build is running on. Equals 'master' for master node.
JOB_NAME Name of the project of this build. This is the name you gave your job when you first set it up. It's the third column of the Jenkins Dashboard main page.
BUILD_TAG String of jenkins-${JOB_NAME}-${BUILD_NUMBER}. Convenient to put into a resource file, a jar file, etc for easier identification.
JENKINS_URL Set to the URL of the Jenkins master that's running the build. This value is used by Jenkins CLI for example
EXECUTOR_NUMBER The unique number that identifies the current executor (among executors of the same machine) that's carrying out this build. This is the number you see in the "build executor status", except that the number starts from 0, not 1.
JAVA_HOME If your job is configured to use a specific JDK, this variable is set to the JAVA_HOME of the specified JDK. When this variable is set, PATH is also updated to have $JAVA_HOME/bin.
WORKSPACE The absolute path of the workspace.
SVN_REVISION For Subversion-based projects, this variable contains the revision number of the module. If you have more than one module specified, this won't be set.
CVS_BRANCH For CVS-based projects, this variable contains the branch of the module. If CVS is configured to check out the trunk, this environment variable will not be set.
GIT_COMMIT For Git-based projects, this variable contains the Git hash of the commit checked out for the build (like ce9a3c1404e8c91be604088670e93434c4253f03) (all the GIT_* variables require git plugin)
GIT_URL For Git-based projects, this variable contains the Git url (like git#github.com:user/repo.git or https://github.com/user/repo.git)\\
GIT_BRANCH For Git-based projects, this variable contains the Git branch that was checked out for the build (normally origin/master)
Sorry about bad formatting (SO doesn't support nice tables), but you should be able to retrieve these variables with System.getEnv(). This means you don't need to add anything to your Jenkins configuration, just read from java what it already sets.
http://<Jenkins_server>/job/<Job_name>/lastBuild/api/xml?depth=1
Above url will give you the xml structured data, in which you can check <building>false</building> tag value from your java code by parsing the xml.
If value is true than jenkins job is running at the time.
To check which of given three job is running, you can check the status of each job by parsing xml in java code for each job and get configuration file of running job.
P.S. : Replace the place holders in url with applicable data. <Jenkins_server> and <Job_name>
You could pass a system property from the job to the JVM when launching the project:
...whatever... -Dconfig=test_existing_api
and retrieve it in your classes with:
System.getProperty("config")

Jenkins not filtering global passwords for Maven build

Using the EnvInject plugin, I have added a password to the Global Passwords list, like so:
Within the job, I enable global passwords, like so:
I was under the assumption that using the name as an environment variable within the Maven build goal would work just fine, like so:
Unfortunately, I see this in the build output:
.../my-project/pom.xml clean install -Dwhatever.password=${qa.password}
What am I missing? I've been toying around with config for a while, but this seems like it should work for what I'm trying to accomplish.
For the sake of the question, the reasoning for utilizing a password as a maven option is out of the context of this question.
I think a dot is not a valid character in an environmental variable. Maybe try renaming the variable to 'qa_password' or something?

Categories