I've been struggling in building automated build using Jenkins with symfony 3.4.
How to properly set environment variables in Jenkins that symfony can find it.
here's my pipeline.
node {
def app
stage('composer install') {
sh 'export $(cat env/env_vars | xargs)'
sh 'composer install --optimize-autoloader'
}
stage('yarn install') {
sh 'yarn install'
}
stage ('build assets') {
sh 'yarn encore production'
}
stage('Clone repository') {
// clone
}
stage('Build image') {
// build here
}
stage('Push image') {
// push here
}
}
then after I run my build.
I always got this message
....
Creating the "app/config/parameters.yml" file
Some parameters are missing. Please provide them.
database_host ('%env(DATABASE_HOST)%'): Script Incenteev\ParameterHandler
\ScriptHandler::buildParameters handling the symfony-scripts event terminated with an exception
[Symfony\Component\Console\Exception\RuntimeException]
Aborted
....
I already used some jenkins plugin like EnvInjector and something similar. But still symfony can't find my environment variables.
You can probably solve this like this:
stage('composer install') {
sh 'export $(cat env/env_vars | xargs) && composer install --optimize-autoloader'
}
This will make the environment variables available in the same shell session.
Related
I work on a Symfony 6.0.9 website with EasyAdmin to handle the administration panel.
I've got an entity ProfessionalExperience with some of its properties that are dates. Its CRUD controller for EasyAdmin looks like this :
class ProfessionalExperienceCrudController extends AbstractCrudController
{
public static function getEntityFqcn(): string
{
return ProfessionalExperience::class;
}
public function configureCrud(Crud $crud): Crud
{
...
}
public function configureFields(string $pageName): iterable
{
return [
...
DateTimeField::new('start')
->setFormat('Y-MM-dd'),
DateTimeField::new('stop')
->setFormat('Y-MM-dd'),
...
];
}
}
It works just fine in my dev env and the build and deploy on Heroku works fine too.
But when I try to click to access this part of the administration panel in the deployed website, I've got this error in Heroku's logs :
[critical] Uncaught PHP Exception LogicException: "When using date/time fields in EasyAdmin backends, you must install and enable the PHP Intl extension, which is used to format date/time values." at /app/vendor/easycorp/easyadmin-bundle/src/Field/Configurator/DateTimeConfigurator.php line 37
I don't understand, because in my Dockerfile, I've got this :
RUN set -eux; \
apk add --no-cache --virtual .build-deps \
$PHPIZE_DEPS \
icu-dev \
libzip-dev \
zlib-dev \
; \
\
docker-php-ext-configure zip; \
docker-php-ext-install -j$(nproc) \
intl \
zip \
; \
Thanks for helping me ! ;)
You could try adding the extension in your composer.json.
You can see in the heroku documentation that you can add optionnal extension to install by adding them in your composer.json.
{
"require": {
"ext-intl": "*",
}
}
Don't forget to run composer update and commit your lock file.
I am running this following pipeline which has stage "Build + Sonarscanner Analysis" for dotnetcore 2.2
The stage is set as follows
I have installed the tool in Global Configuration as suggested by
Sonarqube Documentation
Defined the tool in the environment as following
// Tools
MSBUILD_SQ_SCANNER_HOME = tool name: 'Scanner_for_MSBuild_4.7', type: 'hudson.plugins.sonar.MsBuildSQRunnerInstallation'
Pipeline Stage
stage ('Build + SonarQube analysis') {
agent {
docker {
image 'mcr.microsoft.com/dotnet/core/sdk:2.2'
}
}
steps {
dir ("app") {
withSonarQubeEnv('local') {
sh "dotnet ${MSBUILD_SQ_SCANNER_HOME}/SonarScanner.MSBuild.dll begin /k:\"Testing-Local\""
sh "dotnet build ${env.DotnetProjectName}"
sh "dotnet ${MSBUILD_SQ_SCANNER_HOME}/SonarScanner.MSBuild.dll end"
}
}
}
}
Result
I am getting the SonarScanner.MSBuild.dll is not executable as seen below
Verfication
The dll exists and the permissions is assigned to Jenkins
The dll is executable
The dll when run manually in that path - it runs
Directly added the path for the dll, It has the same result
stage ('Build + SonarQube analysis') {
agent {
docker {
image 'mcr.microsoft.com/dotnet/core/sdk:2.2'
}
}
steps {
dir ("app") {
withSonarQubeEnv('local') {
sh "dotnet /var/lib/jenkins/tools/hudson.plugins.sonar.MsBuildSQRunnerInstallation/Scanner_for_MSBuild_4.7/SonarScanner.MSBuild.dll begin /k:\"Testing-Local\""
sh "dotnet build ${env.DotnetProjectName}"
sh "dotnet var/lib/jenkins/tools/hudson.plugins.sonar.MsBuildSQRunnerInstallation/Scanner_for_MSBuild_4.7/SonarScanner.MSBuild.dll end"
}
}
}
}
Thanks for the help in advance.
I was able to solve this,
1. Installed the SonarScanner for dotnetcore in Jenkins Tools
The path for the sonarscanner will be the same as before
Default Path
/var/lib/jenkins/tools/hudson.plugins.sonar.MsBuildSQRunnerInstallation/Scanner_for_MSBuild_4.7/SonarScanner.MSBuild.dll
2. Initialize the tool in Jenkinsfile
// Tools
MSBUILD_SQ_SCANNER_HOME = tool name: 'Scanner_for_MSBuild_4.7', type: 'hudson.plugins.sonar.MsBuildSQRunnerInstallation'
stage ('Build + SonarQube analysis')
agent {
docker {
image 'mcr.microsoft.com/dotnet/core/sdk:2.2'
args '-v ${MSBUILD_SQ_SCANNER_HOME}:/opt/sonarscanner'
}
}
steps {
dir ("app") {
withSonarQubeEnv('local') {
sh "dotnet /opt/sonarscanner/SonarScanner.MSBuild.dll begin /k:\"Testing-Local\""
sh "dotnet build ${env.DotnetProjectName}"
sh "dotnet /opt/sonarscanner/SonarScanner.MSBuild.dll end"
}
}
}
}
How it works?
I am mounting the sonarscanner to the official docker image at the path /opt/sonarscanner/
With the mounted file as an argument for docker container during initialization, now the dll is avaliable for the docker dotnet command
SBT is silently failing when it can't download a plugin via SSH from a Git repository.
This is the output of SBT when it's trying to download the repository:
[info] Updating ProjectRef(uri("ssh://git#repository.com/plugin.git"), "plugin")...
# (nothing after that line)
And it just terminates after that with no explanation. This is very likely a bug with SBT's downloading of plugins via SSH from a Git repository.
When downloading the plugin succeeds, this line is printed:
[info] Done updating.
So for some reason, SBT isn't stating what's wrong, even when executed like this:
sbt -Xdebug test
Here are the relevant configuration files:
# project/build-properties
sbt.version=1.1.5
# project/plugins.sbt
lazy val buildPlugin = RootProject(uri("ssh://git#repository.com/plugin.git"))
lazy val root = (project in file(".")).dependsOn(buildPlugin)
Questions:
1. How can I get SBT to print more debugging information?
2. Where in the SBT code could I fix this bug?
3. How can I build and use my own version of SBT?
How can I get SBT to print more debugging information?
Using the latest launching script available from https://www.scala-sbt.org/download.html (1.2.1 as of August, 2018), you can run:
$ sbt -debug
Where in the SBT code could I fix this bug?
See my answer here https://github.com/sbt/sbt/issues/1120#issuecomment-415553592:
Here are some of the relevant code:
Load.builtinLoader - https://github.com/sbt/sbt/blob/v1.2.1/main/src/main/scala/sbt/internal/Load.scala#L480-L488
RetrieveUnit - https://github.com/sbt/sbt/blob/v1.2.1/main/src/main/scala/sbt/internal/RetrieveUnit.scala
Resolvers.git - https://github.com/sbt/sbt/blob/v1.2.1/main/src/main/scala/sbt/Resolvers.scala#L82-L101
Resolvers.creates - https://github.com/sbt/sbt/blob/v1.2.1/main/src/main/scala/sbt/Resolvers.scala#L145-L155
val git: Resolver = (info: ResolveInfo) => {
val uri = info.uri.withoutMarkerScheme
val localCopy = uniqueSubdirectoryFor(uri.copy(scheme = "git"), in = info.staging)
val from = uri.withoutFragment.toASCIIString
if (uri.hasFragment) {
val branch = uri.getFragment
Some { () =>
creates(localCopy) {
run("git", "clone", from, localCopy.getAbsolutePath)
run(Some(localCopy), "git", "checkout", "-q", branch)
}
}
} else
Some { () =>
creates(localCopy) {
run("git", "clone", "--depth", "1", from, localCopy.getAbsolutePath)
}
}
}
....
def creates(file: File)(f: => Unit) = {
if (!file.exists)
try {
f
} catch {
case NonFatal(e) =>
IO.delete(file)
throw e
}
file
}
How can I build and use my own version of SBT?
https://github.com/sbt/sbt/blob/1.x/CONTRIBUTING.md#build-from-source
For this, you just need sbt/sbt, and publishLocal.
I need to move a file out of the way before one of my Grunt tasks run, and then put it back after the task has completed.
How do I do this with GruntJS?
Basically I want to run this command:
# move node-webkit out of the way
mv app/node-webkit ./tmp
# run grunt task
# move node-webkit back
mv ./tmp/node-webkit ./app/
Yeah, have a look at grunt-shell. In your init config:
shell: {
move: {
command: 'mv app/node-webkit ./tmp'
},
moveback: {
command: 'mv ./tmp/node-webkit ./app/'
}
}
Then, register a function that runs the move command before the other tasks you want to run, then run the moveback task.
module.exports = function(grunt) {
'use strict';
grunt.registerTask('mytask', [
'shell:move',
'othertaskshere',
'shell:moveback'
]);
};
I'm very new to Symfony and I'm trying to automate the deploy process with rsync, while keeping both the local and remote installs of Symfony working.
What I've done so far:
installed Cygwin on my local machine (Windows 7+Apache2.2+PHP 5.3+MySQL 5.1)
done a basic Symfony install on my local machine from shell with the command
php composer.phar create-project symfony/framework-standard-edition [path]/ 2.2.1
set up a remote LAMP Ubuntu server with php-fpm (fastcgi)
set up two different configuration files for local and remote in the app/config/ dir, parameters.yml and parameters.yml.remote
created an app/config/rsync_exclude.txt file containing a list of files not to rsync to the remote server (as suggested in this page)
created a deploy shell script that I run from Cygwin (see below)
The deploy script issues the commands:
rsync -avz /cygdrive/c/[path]/ user#server:[remote-path]/ --exclude-from=/cygdrive/c/[path]/app/config/rsync_exclude.txt
ssh user#server 'cd [remote-path]/ && php app/console --env=prod cache:clear && php app/console cache:clear'
ssh user#server 'mv [remote-path]/app/config/parameters.yml.remote ~/[remote-path]/app/config/parameters.yml'
The rsync, ssh and mv commands work, but the deployed site shows always a HTTP 500 error (both app.php and app_dev.php).
Looking at server error log the error is:
Fatal error: Class 'Composer\\Autoload\\ClassLoader' not found in /[remote-path]/vendor/composer/autoload_real.php on line 23
Any clue would be more than welcome.
Edit - here is my vendor/composer/autoload_real.php file (sorry for the making the question longer!):
<?php
// autoload_real.php generated by Composer
class ComposerAutoloaderInit9d50f07556e53717271b583e52c7de25
{
private static $loader;
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit9d50f07556e53717271b583e52c7de25', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
// ^^^^^^ this is line 23 and gives the error ^^^^^^^^^^^
spl_autoload_unregister(array('ComposerAutoloaderInit9d50f07556e53717271b583e52c7de25', 'loadClassLoader'));
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->add($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
$loader->register(true);
require $vendorDir . '/kriswallsmith/assetic/src/functions.php';
require $vendorDir . '/swiftmailer/swiftmailer/lib/swift_required.php';
return $loader;
}
}
If there is an error with the autoloader generated by composer, performing ...
composer update
... will update your dependencies and create a new one.
You should invoke the command with the -o flag if you are deploying to a production system.
This way composer generates a classmap autoloader ( which performs way better ) instead of the classic autoloader.
composer update -o
I guess re-generating the autoloader will solve the issue :)