Pulling a file from another job before building in Jenkins? - hudson

Hope you can help me on this one. I have a job called "Template" that generates a template.xml file. I have several other jobs that use this template.xml file. However, before they build, i wanted that they could pull the latest template.xml from the "Template" job workspace.

In your "template" job, under Post-Build Actions, choose to artifact your xml file using the archive option.
You can then use the "Copy Artifact Plugin" to copy it over to all other jobs.
Jenkins Job Setup for Artifact Generator Project:
Jenkins Job Setup for Artifact User Project:

In your Template job, you can archive the template.xml file as an artifact, then it will be available to your other jobs at a URL similar to the following:
http://myserver/jenkins/job/myjob/lastSuccessfulBuild/artifact/template.xml

I used Copy Artifacts plugin with Jenkinsfile. Here an example:
In the job that is producing the artifact you should do something like:
pipeline {
options {
copyArtifactPermission ‘*’ //Here you can specify the job name also
}
stages {
stage(“Run") {
...
archiveArtifacts artifacts: “my_artifact.yaml"
}
}
}
In the job that is consuming the artifact you can use something like:
stage("Consumer") {
steps {
script {
copyArtifacts filter: “my_artifact.yaml", projectName: 'PRODUCER_JOB',
selector: lastSuccessful()
}
}
}

In my end I use a pretty strainghforward approach. I run jenkins in a usual layout (ubuntu 16.04 server) and I need call the checkstyle maven plugin using the same checkstyle.xml config file residing inside a dev-resources job:
Than I call mvn checkstyle:
Hope it can be useful for someone else.

Related

How can I add and compile local copy of a library into Android React Native module?

How Can I add to native module, external library source code.
In the case, I want to add a local copy of ExoPlayer to react-native-video module.
I want to "git clone" the original source of the ExoPlayer
inside react-native-video/android-exoplayer ,make some modifications on it and test it.
Currently the depencies of /react-native-video/android-exoplayer/build.gradle are:
dependencies {
//noinspection GradleDynamicVersion
provided "com.facebook.react:react-native:${safeExtGet('reactNativeVersion', '+')}"
compile 'com.google.android.exoplayer:exoplayer:2.7.3'
compile('com.google.android.exoplayer:extension-okhttp:2.7.3') {
exclude group: 'com.squareup.okhttp3', module: 'okhttp'
}
compile 'com.squareup.okhttp3:okhttp:3.9.1'
}
current file structure:
build
build.gradle
ExoPlayer
/src
This directory "ExoPlayer" I got with "git clone" and want to use instead of
compile 'com.google.android.exoplayer:exoplayer:2.7.3'
I found the solution:
In the root Project settings.gradle should add this:
gradle.ext.exoplayerRoot = '../node_modules/react-native-video/android-exoplayer/ExoPlayer-r2.7.3'
gradle.ext.exoplayerModulePrefix = 'exoplayer-'
apply from: new File(gradle.ext.exoplayerRoot, 'core_settings.gradle')
In react-native-video/android-exoplayer/build.gradle dependencies section add this:
implementation project(':exoplayer-library-core')
implementation project(':exoplayer-library-hls')
implementation project(':exoplayer-library-smoothstreaming')
implementation project(':exoplayer-library-dash')
implementation project(':exoplayer-library-ui')
implementation project(':exoplayer-extension-okhttp')
and remove all rows started with "compile"

How to enable autocomplete for Google Apps Script in locally-installed IDE

I'm trying to build GAS projects locally using clasp.
Any locally-installed IDE is a huge improvement over Google's Script Editor, so the tool looks very promising. Unfortunately, the autocomplete feature for GAS services doesn't seem to be included in the package.
The documentation says:
The Apps Script CLI uses TypeScript to provide autocompletion and linting when developing. Use an IDE like Visual Studio Code for TypeScript autocompletion.
After going through the steps and installing all required dependencies, I'm still unable to get the autocomplete feature to work. When I execute the clasp pull command for the existing project, it converts the ".gs" extension to ".js". The autocomplete suggestions are simply the result of parsing existing code.
For example, if I call sheet.getRange() somewhere in my code, then the getRange() method will pop up in suggestions, but I can't list available options for, say, PropertiesService, unless it's already used in my code.
Has anybody had any luck with enabling autocomplete feature for Google Apps Script?
I found the solution that partially works, but it may not be applicable to other software. The steps below are for Visual Studio Code:
Install the NPM package containing type definitions for GAS using
https://www.npmjs.com/package/#types/google-apps-script
In your locally-saved script, create a '.js' file and type
import 'google-apps-script';
This answer is a minor variation on the accepted one for IDEs/extensions which support Typescript auto completion based on tsc/tsserver:
Install TypeScript and #types/google-apps-script
https://www.npmjs.com/package/typescript
https://www.npmjs.com/package/#types/google-apps-script
Create a jsconfig.json file in your local project directory:
{
"compilerOptions": {
"checkJs": true
}
}
Alternatively, If you're using typescript along with javascript, then create a tsconfig.json:
{
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"types": ["google-apps-script"]
}
}
Include both filenames in .claspignore, if you're using clasp and if the file is in your local directory.
You can also use any of this config globally, if the config is in your home/parent directory, as tsc searches for this config from project/local folder to root(in which case, you don't need to include it in .claspignore).
If you are using any JetBrains IDE:
Go to Languages & Frameworks -> JavaScript -> Libraries -> Download... and download the library google-apps-script.
Try including the file name, import.js in .claspignore (docs).
This should save some trouble deleting the file before each push every time.
This is an answer provided by Google developers in the "TU17: Enhancing the Google Apps Script Developer Experience with clasp and TypeScript" video.
Add a JavaScript file to your project like "appscript.js" and, in that file, add:
import "google-apps-script";
Save that file but make sure to ignore it when pushing files back to your project using a .claspignore file.

How to validate JSON in Gradle build

I have a Gradle build where a large JSON configuration is bundled into a package for later upload onto a server. Sometimes when changes are made to the file, the file is not valid any more and thus fails to upload on the server.
I would like to find this earlier by adding a validate-step in the Gradle build.
When looking around I could not find a documented way to do this, I saw the project gradle-json-validator which looks promising, but there is no documentation whatsoever, so I am not sure how this can be used...
Any hint on gradle-json-validator or any other way to validate a JSON file as part of the Gradle build steps?
From source, it would seem, the usage would be:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'cz.alenkacz.gradle:json-validator:0.9.9'
}
}
apply plugin: 'cz.alenkacz.gradle.jsonvalidator'
The plugin doesn't seem to have an extension to do configuration. But seems to use jsonSchema and targetJsonFile as input schema and file-to-validate. I would try setting them at the root level of build.gradle
validateJson.jsonSchema = new File('/path/to/schema')
validateJson.targetJsonFile = new File('/path/to/jsonFile')
and the task to run is:
gradle validateJson
I have improved the readme file in the repository with proper usage example.
Hope that helps. https://github.com/alenkacz/gradle-json-validator

Unable to update file in appDataFolder using Google Drive REST API V3 on Android

This is the code i'm using to update the file.
File metadata = generateFileMetadata(fileId, thumbnail, properties);
return mService.files().update(fileId, metadata, generateFileContents())
.setFields("id, name, appProperties")
.execute();
This code generates a
java.lang.IllegalArgumentException.
at com.google.api.client.repackaged.com.google.common.base.Preconditions.checkArgument(Preconditions.java:111)
at com.google.api.client.util.Preconditions.checkArgument(Preconditions.java:37)
at com.google.api.client.googleapis.media.MediaHttpUploader.setInitiationRequestMethod(MediaHttpUploader.java:872)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.initializeMediaUpload(AbstractGoogleClientRequest.java:237)
at com.google.api.services.drive.Drive$Files$Update.<init>(Drive.java:3163)
at com.google.api.services.drive.Drive$Files.update(Drive.java:3113)
Using breakpoints I could see that the String passed to the setInitiationRequestMethod is PATCH (not POST or PUT):
public MediaHttpUploader setInitiationRequestMethod(String initiationRequestMethod) {
Preconditions.checkArgument(initiationRequestMethod.equals(HttpMethods.POST)
|| initiationRequestMethod.equals(HttpMethods.PUT));
this.initiationRequestMethod = initiationRequestMethod;
return this;
}
this is what i have in my build.gradle
compile 'com.google.android.gms:play-services-identity:8.4.0'
compile('com.google.api-client:google-api-client-android:1.21.0') {
exclude group: 'org.apache.httpcomponents'
}
compile('com.google.apis:google-api-services-drive:v3-rev11-1.21.0') {
exclude group: 'org.apache.httpcomponents'
}
if I remove the file content (generateFileContents()) I'm able to update the metadata just fine.
How do I solve this?
I ran into this bug while writing a Drive REST API integration for an Android app (with Android Studio/Gradle). Since I'm not particularly experienced with Android's build system, resolving the issue cost me a few hours. Maybe this helps somebody with the same problem:
Clone the google-api-java-client repo from GitHub https://github.com/google/google-api-java-client
Install Maven https://maven.apache.org/run-maven/ (e.g. brew install maven on OSX)
On the command line, change into the google-api-client sub dir of the repo you cloned above
Run mvn clean install
This will produce a subdir called target in the google-api-client directory
In there, find google-api-client-1.22.0-SNAPSHOT.jar, rename it to google-api-client-1.21.00.jar (the renaming is probably not needed)
Drop the .jar in the libs folder of your android project
Tell Gradle to ignore the google-api-client dependency of the libraries you use, in my case this was:
compile('com.google.api-client:google-api-client-android:1.21.0') {
exclude group: 'org.apache.httpcomponents'
exclude module: 'google-api-client'
}
compile('com.google.apis:google-api-services-drive:v3-rev14-1.21.0') {
exclude group: 'org.apache.httpcomponents'
exclude module: 'google-api-client'
}
Add the Jackson dependency again, in case you miss it now. Do the same with other google-api-java-client dependencies if you need them.
compile('com.google.http-client:google-http-client-jackson2:1.21.0'){
exclude group: 'org.apache.httpcomponents'
}
Build your project, update(...) should now work.
Make a note to scrap these changes once Google has updated the library.
Take a look at the current commit of the google-api-java-client.
Unfortunately the fix was not released yet (fix on 21 Nov 2015 vs release on 19 Nov 2015), so you may have to build locally the project (with maven for instance)
The MediaHttpUploader javadocs suggests that it will only be used for HttpMethods#POST, and HttpMethods#UPDATE. Using update, based on the Files resource, indicates its using a PATCH method - leading to the IllegalArgumentException.
The overridden update method should only be used if you're uploading media content.
I have the same exception in a Desktop application.
Instead, using the Drive Api V2, the update goes well.

Configure or Create hudson job automatically

Is there any way to create new Hudson job by one more Hudson job based one previous Jobs?
For example if I need to create new bunch of jobs one by one, Automatically create 4 jobs with similar configuration with different parameter
Basically steps like this
create SVN branch I can call svn cp command and make it parametrized using script
Create some build based on new svnbranch name
Later tag it
Or other word, I need to clone the previous job and give the new branch name where ever $ Branch comes in new job.
Thanks
You can try the Hudson Remote API for this kind of task (setting up an Hudson project).
See this tutorial for instance, and remember you can display the help quite easily:
java -jar hudson-cli.jar -s http://your_Hudson_server/ help
So, to copy a job:
java -jar hudson-cli.jar -s http://your_Hudson_server/ copy-job myjob copy-myjob
You could use groovy system script like this :
def jenkins = hudson.model.Hudson.instance
def template = jenkins.getItem("MyTemplate")
def job = jenkins.copy(template,"MyNewJob")
job.scm = new hudson.scm.SubversionSCM("http://base/branches/mybranche")
job.save()
Kind of already covered in the other answers, but for an easy way to copy the config.xml over:
curl --user USER:PASS -H "Content-Type: text/xml" -s
--data-binary "#config.xml" "http://hudsonserver:8080/createItem?name=newjobname"
There seems to be a plugin for jenkins.
https://wiki.jenkins-ci.org/display/JENKINS/Job+DSL+Plugin
I have not tested the plug-in yet. But if the plugin works, it should alleviate some of human errors from straight copying a job and modifying variables/values.
def jenkins = hudson.model.Hudson.instance
def template = jenkins.getItem("MyTemplate")
def job = jenkins.copy(template,"MyNewJob")
job.save()
I used this now I have to change the parameter values of MyNewJob using Groovy how will I do that?
ex I have a parameter called "Build_BranchName" and the default is //perforce/mybranch
I have to change it to
//perforce/mynewbranch
You have the option that VonC just gave you (which is probably the safest way but you can also go a different rout by just creating a new directory in {Hudson_Home}\jobs (the directory name will be the job name) and copy a modified config.xml in there. The modification will basically just be the SVN URL. You should check out the xml from the job that you are copying. You need to find out how you change the xml file via script, but this is a secondary problem.
Unfortunately, you have to either restart Hudson, or force a reload of the configuration. (visit the page http://:/reload to reload the config).
In case you're willing to use GIT (like I do, mirroring the main SVN repo, onto the Hudson/Jenkins server, and it works great)....
..you could try Stephen Haberman's post-receive-hudson:
This hook creates new jobs for each
branch in the Hudson continuous
integration tool. Besides creating the
job if needed, the user who pushed is
added to the job's email list if they
were not already there.
In any case, that script can give you new hints on how to remote control Jenkins(Hudson).