I switched from declerativ pipeline to scripted pipeline. Everything works fine only the Parameterized Scheduler Plugin makes problems. If i have one Trigger it works and the pipeline is scheduled. If i add another trigger only the second one works. May be it's a syntax problem but everything i tried doesn't work. Any ideas?
properties([
parameters([
booleanParam (defaultValue: true, description: 'test', name: 'test')
]),
pipelineTriggers([
parameterizedCron('15 20 * * * test=true'),
parameterizedCron('05 20 * * * test=false')
])
])//properties
according to official documentation your syntax is wrong, you are missing %. Also you can use one multiline parameterizedCron.
pipeline {
agent any
parameters {
string(name: 'PLANET', defaultValue: 'Earth', description: 'Which planet are we on?')
string(name: 'GREETING', defaultValue: 'Hello', description: 'How shall we greet?')
}
triggers {
cron('* * * * *')
parameterizedCron('''
# leave spaces where you want them around the parameters. They'll be trimmed.
# we let the build run with the default name
*/2 * * * * %GREETING=Hola;PLANET=Pluto
*/3 * * * * %PLANET=Mars
''')
}
stages {
stage('Example') {
steps {
echo "${GREETING} ${PLANET}"
script { currentBuild.description = "${GREETING} ${PLANET}" }
}
}
}
}
So in your case it should be
properties([
parameters([
booleanParam (defaultValue: true, description: 'test', name: 'test')
]),
pipelineTriggers([
parameterizedCron('''
15 20 * * * %test=true
05 20 * * * %test=false''')
])
])//properties
Also please note that there's this open issue, which indicates that for your trigger to register for the scripted, it would need to be run manually at least twice.
Related
triggers {
parameterizedCron('''0 */2 * * * %APPLICATION_ID=41''')
}
stages{
......
stage('pass cron variable to this stage') {
**????How to get my APPLICATION_ID here?????**
}
}
I want to pass the cron APPLICATION_ID from parameterizedCron to stage as mentiond above
The % sign needs to be separated:
triggers {
parameterizedCron('0 */2 * * * % APPLICATION_ID=41')
}
You need to have a parameter named APPLICATION_ID:
parameters {
string(name: 'APPLICATION_ID', defaultValue: '1', description: 'Application ID')
}
You can then address the parameter as params.APPLICATION_ID. This will be string. If you need to make an int out of it, you need to convert it into int.
I want to get a chained job from start to the end. But these jobs are also needed for separate execution.
I want a scheduled build and need those jobs chained.
When running manually, not running the Jobs in cascaded mode.
I don't want to click configure, remove downstream run and re-add the downstream in case of manual execution.
What is the best solution for this?
Thanks in advance.
So this can be done, however I do recommend putting the functions I have outlined below in a Jenkins Shared Library. Doing it this way will cause at least 4 sandbox security approvals, which will require your jenkins administrator to approve. 1 of which warns it is a security vulnerability.... so assess the impact for your environment and your risk profile.
#!groovy
List jobparameters = [
booleanParam(name: 'CHECKBOX', defaultValue: true, description: 'Tick a checkbox'),
string(name: 'STRING', defaultValue: 'stringhere', description: 'Enter a string')
]
properties([
pipelineTriggers([cron('''TZ=Australia/Victoria
H 1 * * *''')]),
buildDiscarder(logRotator(numToKeepStr: '20')),
parameters(jobparameters),
])
stage('Stage') {
node {
// do something always
echo(params.STRING)
}
}
if ( hasAutomatedCauses() ) {
stage('folder1/reponame/branch') {
//do something conditionally
build(job: "folder1/reponame/branch", parameters: jobparameters, propagate: true)
}
} else {
stage('folder1/reponame/branch') {
node {
echo("Not running downstream job")
}
}
}
/**
* Checks if job causes contain automated causes
* Return true if automated cause found
*
* #return boolean
*/
boolean hasAutomatedCauses() {
List automatedCauses = ['UpstreamCause', 'TimerTriggerCause']
List intersection = []
intersection = automatedCauses.intersect(getCauses())
// if no automated causes are found means intersection is empty and then return false
return !intersection.isEmpty()
}
/**
* Retrieves list of causes that generated job execution
*
* #return list
*/
List getCauses() {
return currentBuild.rawBuild.getCauses().collect { it.getClass().getCanonicalName().tokenize('.').last() }
}
I've looked for some example of user input parameters using Jenkins declarative pipeline, however all the examples are using the scripted pipelines. Here is a sample of code I'm trying to get working:
pipeline {
agent any
stages {
stage('Stage 1') {
steps {
input id: 'test', message: 'Hello', parameters: [string(defaultValue: '', description: '', name: 'myparam')]
sh "echo ${env}"
}
}
}
}
I can't seem to work out how I can access the myparam variable, it would be great if someone could help me out.
Thanks
When using input, it is very important to use agent none on the global pipeline level, and assign agents to individual stages. Put the input procedures in a separate stage that also uses agent none. If you allocate an agent node for the input stage, that agent executor will remain reserved by this build until a user continues or aborts the build process.
This example should help with using the Input:
def approvalMap // collect data from approval step
pipeline {
agent none
stages {
stage('Stage 1') {
agent none
steps {
timeout(60) { // timeout waiting for input after 60 minutes
script {
// capture the approval details in approvalMap.
approvalMap = input
id: 'test',
message: 'Hello',
ok: 'Proceed?',
parameters: [
choice(
choices: 'apple\npear\norange',
description: 'Select a fruit for this build',
name: 'FRUIT'
),
string(
defaultValue: '',
description: '',
name: 'myparam'
)
],
submitter: 'user1,user2,group1',
submitterParameter: 'APPROVER'
}
}
}
}
stage('Stage 2') {
agent any
steps {
// print the details gathered from the approval
echo "This build was approved by: ${approvalMap['APPROVER']}"
echo "This build is brought to you today by the fruit: ${approvalMap['FRUIT']}"
echo "This is myparam: ${approvalMap['myparam']}"
}
}
}
}
When the input function returns, if it only has a single parameter to return, it returns that value directly. If there are multiple parameters in the input, it returns a map (hash, dictionary), of the values. To capture this value we have to drop to groovy scripting.
It is good practice to wrap your input code in a timeout step so that build don't remain in an unresolved state for an extended time.
Currently I have this webpack (Angular2 seed) project. With this project I have some css which depends on which client opens the page (multi brand platform).
As of now I'm generating css files using the ExtractTextPlugin, this works pretty well except for now my images etc. are all dumped in the dist root, but I can probably solve those things.
What bothers me slightly is that this also generates a "cssentrypoint.js" and "cssentrypoint.map.js". I guess it's the default behaviour but does anyone know if there is a simple solution to just generate the sass in the build script (so it still watches for changes) and not the JS?
I'll share my webpack.common config which applies to all, the out is configured to be something like [name].[chunkhash].js
/**
* #author: #AngularClass
*/
const webpack = require('webpack');
const helpers = require('./helpers');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
/*
* Webpack Plugins
*/
// problem with copy-webpack-plugin
var CopyWebpackPlugin = (CopyWebpackPlugin = require('copy-webpack-plugin'), CopyWebpackPlugin.default || CopyWebpackPlugin);
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin;
const HtmlElementsPlugin = require('./html-elements-plugin');
var glob = require('glob');
/*
* Webpack Constants
*/
const METADATA = {
title: 'Prepaid Service Provider',
baseUrl: '/',
isDevServer: helpers.isWebpackDevServer()
};
/*
* Webpack configuration
*
* See: http://webpack.github.io/docs/configuration.html#cli
*/
module.exports = {
/*
* Static metadata for index.html
*
* See: (custom attribute)
*/
metadata: METADATA,
/*
* Cache generated modules and chunks to improve performance for multiple incremental builds.
* This is enabled by default in watch mode.
* You can pass false to disable it.
*
* See: http://webpack.github.io/docs/configuration.html#cache
*/
//cache: false,
/*
* The entry point for the bundle
* Our Angular.js app
*
* See: http://webpack.github.io/docs/configuration.html#entry
*/
entry: {
'polyfills': './src/polyfills.browser.ts',
'vendor': './src/vendor.browser.ts',
'main': './src/main.browser.ts',
'eneco': './src/style/css/someclient.scss',
'nuon': './src/style/css/someotherclient.scss'
},
/*
* Options affecting the resolving of modules.
*
* See: http://webpack.github.io/docs/configuration.html#resolve
*/
resolve: {
/*
* An array of extensions that should be used to resolve modules.
*
* See: http://webpack.github.io/docs/configuration.html#resolve-extensions
*/
extensions: ['', '.ts', '.js', 'scss'],
// Make sure root is src
root: helpers.root('src'),
// remove other default values
modulesDirectories: ['node_modules'],
alias: {
// legacy imports pre-rc releases
'angular2': helpers.root('node_modules/#angularclass/angular2-beta-to-rc-alias/dist/beta-17')
},
},
/*
* Options affecting the normal modules.
*
* See: http://webpack.github.io/docs/configuration.html#module
*/
module: {
/*
* An array of applied pre and post loaders.
*
* See: http://webpack.github.io/docs/configuration.html#module-preloaders-module-postloaders
*/
preLoaders: [
/*
* Tslint loader support for *.ts files
*
* See: https://github.com/wbuchwalter/tslint-loader
*/
// { test: /\.ts$/, loader: 'tslint-loader', exclude: [ helpers.root('node_modules') ] },
/*
* Source map loader support for *.js files
* Extracts SourceMaps for source files that as added as sourceMappingURL comment.
*
* See: https://github.com/webpack/source-map-loader
*/
{
test: /\.js$/,
loader: 'source-map-loader',
exclude: [
// these packages have problems with their sourcemaps
helpers.root('node_modules/rxjs'),
helpers.root('node_modules/#angular'),
]
}
],
/*
* An array of automatically applied loaders.
*
* IMPORTANT: The loaders here are resolved relative to the resource which they are applied to.
* This means they are not resolved relative to the configuration file.
*
* See: http://webpack.github.io/docs/configuration.html#module-loaders
*/
loaders: [
/*
* Typescript loader support for .ts and Angular 2 async routes via .async.ts
*
* See: https://github.com/s-panferov/awesome-typescript-loader
*/
{
test: /\.ts$/,
loader: 'awesome-typescript-loader',
exclude: [/\.(spec|e2e)\.ts$/]
},
/*
* Json loader support for *.json files.
*
* See: https://github.com/webpack/json-loader
*/
{
test: /\.json$/,
loader: 'json-loader'
},
/* Raw loader support for *.html
* Returns file content as string
*
* See: https://github.com/webpack/raw-loader
*/
{
test: [/\.html$/],
loader: 'raw-loader',
exclude: [helpers.root('src/index.html')]
},
{
test: [/\.jpg$/, /\.jpeg$/, /\.png$/],
loader: 'file-loader'
},
{
test: /\.scss$/i, loader:
ExtractTextPlugin.extract(['css!sass'])
},
{
test: /\.woff(2)?(\?v=.+)?$/,
loader: "url?limit=10000&mimetype=application/font-woff&name=./fonts/[hash].[ext]"
},
{
test: /\.(ttf|eot|svg)(\?v=.+)?$/,
loader: 'file?name=./fonts/[hash].[ext]'
},
]
},
/*
* Add additional plugins to the compiler.
*
* See: http://webpack.github.io/docs/configuration.html#plugins
*/
plugins: [
/*
* Plugin: ForkCheckerPlugin
* Description: Do type checking in a separate process, so webpack don't need to wait.
*
* See: https://github.com/s-panferov/awesome-typescript-loader#forkchecker-boolean-defaultfalse
*/
new ForkCheckerPlugin(),
/*
* Plugin: OccurenceOrderPlugin
* Description: Varies the distribution of the ids to get the smallest id length
* for often used ids.
*
* See: https://webpack.github.io/docs/list-of-plugins.html#occurrenceorderplugin
* See: https://github.com/webpack/docs/wiki/optimization#minimize
*/
new webpack.optimize.OccurenceOrderPlugin(true),
/*
* Plugin: CommonsChunkPlugin
* Description: Shares common code between the pages.
* It identifies common modules and put them into a commons chunk.
*
* See: https://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin
* See: https://github.com/webpack/docs/wiki/optimization#multi-page-app
*/
new webpack.optimize.CommonsChunkPlugin({
name: ['polyfills', 'vendor'].reverse()
}),
/*
* Plugin: CopyWebpackPlugin
* Description: Copy files and directories in webpack.
*
* Copies project static assets.
*
* See: https://www.npmjs.com/package/copy-webpack-plugin
*/
new CopyWebpackPlugin([{
from: 'src/assets',
to: 'assets'
}]),
new ExtractTextPlugin("assets/css/[name].css", {allChunks: false}) ,
/*
* Plugin: HtmlWebpackPlugin
* Description: Simplifies creation of HTML files to serve your webpack bundles.
* This is especially useful for webpack bundles that include a hash in the filename
* which changes every compilation.
*
* See: https://github.com/ampedandwired/html-webpack-plugin
*/
new HtmlWebpackPlugin({
template: 'src/index.html',
chunksSortMode: 'dependency'
}),
/*
* Plugin: HtmlHeadConfigPlugin
* Description: Generate html tags based on javascript maps.
*
* If a publicPath is set in the webpack output configuration, it will be automatically added to
* href attributes, you can disable that by adding a "=href": false property.
* You can also enable it to other attribute by settings "=attName": true.
*
* The configuration supplied is map between a location (key) and an element definition object (value)
* The location (key) is then exported to the template under then htmlElements property in webpack configuration.
*
* Example:
* Adding this plugin configuration
* new HtmlElementsPlugin({
* headTags: { ... }
* })
*
* Means we can use it in the template like this:
* <%= webpackConfig.htmlElements.headTags %>
*
* Dependencies: HtmlWebpackPlugin
*/
new HtmlElementsPlugin({
headTags: require('./head-config.common')
})
],
/*
* Include polyfills or mocks for various node stuff
* Description: Node configuration
*
* See: https://webpack.github.io/docs/configuration.html#node
*/
node: {
global: 'window',
crypto: 'empty',
module: false,
clearImmediate: false,
setImmediate: false
}
};
Update
In addition webpack generates those JS files and also embeds them, this includes css files which I want to optionally show...
I have a problem with swift mailer and monolog on Symfony 3.0.2:
FatalThrowableError in appDevDebugProjectContainer.php line 4963:
Type error: Argument 1 passed to SymfonyBundleMonologBundleSwiftMailerMessageFactory_0000000079e53f2b00000001716bb61a50d0bc982eb9e83148fbcc469ab36a58::__construct() must be an instance of Swift_Mailer, instance of Closure given, called in /Users/Romain/Sites/var/cache/dev/appDevDebugProjectContainer.php on line 4043
# Swiftmailer Configuration config.yml
swiftmailer:
transport: "%mailer_transport%"
host: "%mailer_host%"
username: "%mailer_user%"
password: "%mailer_password%"
spool: { type: memory }
#Monolog config_prod.yml
monolog:
handlers:
main:
type: fingers_crossed
action_level: critical
handler: grouped
grouped:
type: group
members: [streamed, buffered]
streamed:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
buffered:
type: buffer
handler: swift
swift:
type: swift_mailer
from_email: no-reply#email.com
to_email: email#email.com
subject: "Subject"
level: debug
An extract appDevDebugProjectContainer.php on line 4963
/**
* {#inheritDoc}
*/
public function __construct(\Swift_Mailer $mailer, $fromEmail, $toEmail, $subject, $contentType = null)
{
static $reflection;
if (! $this->valueHolder56d41e956b1f5441039037) {
$reflection = $reflection ?: new \ReflectionClass('Symfony\\Bundle\\MonologBundle\\SwiftMailer\\MessageFactory');
$this->valueHolder56d41e956b1f5441039037 = $reflection->newInstanceWithoutConstructor();
\Closure::bind(function (\Symfony\Bundle\MonologBundle\SwiftMailer\MessageFactory $this) {
unset($this->mailer, $this->fromEmail, $this->toEmail, $this->subject, $this->contentType);
}, $this, 'Symfony\\Bundle\\MonologBundle\\SwiftMailer\\MessageFactory')->__invoke($this);
}
$this->valueHolder56d41e956b1f5441039037->__construct($mailer, $fromEmail, $toEmail, $subject, $contentType);
}
An extract appDevDebugProjectContainer.php on line 4043
/**
* Gets the 'monolog.handler.swift.mail_message_factory' service.
*
* This service is shared.
* This method always returns the same instance of the service.
*
* This service is private.
* If you want to be able to request this service from the container directly,
* make it public, otherwise you might end up with broken code.
*
* #param bool $lazyLoad whether to try lazy-loading the service with a proxy
*
* #return \Symfony\Bundle\MonologBundle\SwiftMailer\MessageFactory A Symfony\Bundle\MonologBundle\SwiftMailer\MessageFactory instance.
*/
public function getMonolog_Handler_Swift_MailMessageFactoryService($lazyLoad = true)
{
if ($lazyLoad) {
return $this->services['monolog.handler.swift.mail_message_factory'] = new SymfonyBundleMonologBundleSwiftMailerMessageFactory_0000000057f95edf000000015dd8d44e50d0bc982eb9e83148fbcc469ab36a58(
function (&$wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface $proxy) {
$wrappedInstance = $this->getMonolog_Handler_Swift_MailMessageFactoryService(false);
$proxy->setProxyInitializer(null);
return true;
}
);
}
return new \Symfony\Bundle\MonologBundle\SwiftMailer\MessageFactory($this->get('swiftmailer.mailer.default'), 'contact#domaine.com', array(0 => 'error#domaine.com'), 'Une erreur critique est survenue', NULL);
}
Sends him of e-mail with swiftmailer only work.
I already have this configuration with the same environment but symfony 2.7 and that works.
And this configuration works on a wamp (php7) but not on my environement OSX and server Linux ...
Thank you for your help
fix with symfony 3.0.3 and monolog 1.18