How to configure fail-fast strategy for Zuul CI jobs for a specific project? - zuul-ci

How can someone configure a specific project (repository) to use a fail-fast strategy for jobs running inside it?
fail-fast strategy on CI means that you want to cancel any running jobs as soon the first one that counts towards final result is failing (saving compute resources and providing a faster feedback).
Please note that I explicitly asked about a specific project as this option should not affect other project that may have different preferences.

The fail-fast option is already by design a per project (or per project-template) and pipeline setting [1].
e.g. from within an untrusted project:
- project:
check:
fail-fast: true
jobs:
- test foo
Or you can set it in a config project for a different project:
- project:
name: org/other-project
check:
fail-fast: true
[1] https://zuul-ci.org/docs/zuul/reference/project_def.html#attr-project.%3Cpipeline%3E.fail-fast

Related

Using Octopus to configure log4net.config in .NET Core 3.1 Web API project

I'm using Octopus as part of our deployment for a .NET Core 3.1 Web API project.
log4net.config exists in .\Utility\Logs.
I'm trying to follow the pattern here:
https://help.octopus.com/t/transformation-best-practice-log4net-config-or-any-non-web-app-config/9906/4
As I understand it, this consists of three parts:
Create Log4Net.DeploymentTransform.config, with the variables in #{name} format - this has been done.
Turn on the "Substitute variables in files" feature, and point at the Log4Net.DeploymentTransform.config transformation file (variable replacement happens before transformation). That would result in the #{LogFileLocation} variable being replaced with whatever value was set for your LogFileLocation variable in the current scope.
This is done and is working.when my app is deployed, Log4Net.DeploymentTransform.config is there as well and the variable has been successfully set in it.
You'd also turn on the configuration transforms feature, and fill out the additional transforms section in the configuration transforms feature to identify your transform file (e.g. Log4Net.DeploymentTransform.config => log4net.config).
This is not working, the content of Log4Net.DeploymentTransform.config is not being copied on top of log4net.config, though they are in the same folder upon deployment.
Here is what I did in our "deploy step"
Which sure looks like what the article is saying to do.
What else should I check? Any idea why step 3 isn't occurring?
Your syntax looks correct for the files - have you checked to ensure that you have the xdt attributes set?
In the example forum post you shared, the log4net and appender elements are tagged with xmlns:xdt, xdt:Transform and xdt:Match attributes that help the XDT layer determine how to transform the files.
A quick example - I created a Log4NetConfigTest package with two files -
Utility/Logs/log4net.config
Utility/Logs/log4net.trasnform.config
I used the same sample code from the forum post as well.
Here's the set up for my package deployment configurations:
With that set up (and my LogFileLocation project variable set), I was able to see the following in my task log for the deployment:
Deploying package: C:\Octopus\Files\Log4NetConfigTest#S1.0.0#20004C95A0E0094490814B5A365DDAD2.zip
Transforming 'C:\Octopus\Applications\Development\Log4NetConfigTest\1.0.0_1\Utility\Logs\log4net.config' using 'C:\Octopus\Applications\Development\Log4NetConfigTest\1.0.0_1\Utility\Logs\log4net.transform.config'.
No matching appSetting, applicationSetting, nor connectionString names were found in: C:\Octopus\Applications\Development\Log4NetConfigTest\1.0.0_1\Utility\Logs\log4net.config
The task log confirmed that Octopus did apply the transformations, and once deployed, I confirmed that my new test log location was present and correct in both the base configuration and the transformation file.

ARM Template globalization

I Have two ARM templates to deploy resources in DEV and QA separately. Now my requirement is to create only one template to deploy resources in DEV and QA based on selected environment.
Someone help me how to create ARM template to deploy resources based on select Environment like DEV or QA.
Per my understanding, you could use Logical functions for ARM templates to create Azure resources with conditional action. Use the condition element to specify whether the resource is deployed. The value for this element resolves to true or false. When the value is true, the resource is created. When the value is false, the resource isn't created. The value can only be applied to the whole resource.
For more information, read the tutorial: Use condition in ARM templates and this.

Azure pipeline with multiple environments

My dotnetcore app has one appsettings.json per environment (appsettings.json and appsettings.Development.json for example) and I would like to take advantage of this on my pipeline.
I see 2 options for the pipeline:
Build Artifact for Dev -> Deploy on Dev -> Build Artifact for Prod -> Deploy on Prod
or
Build Artifact -> Deploy on Dev -> Deploy on Prod
For the first option, I could set the environment as a parameter for the build.
For the second option, how could I build the App only once, and set the environment according to the current deployment step? Taking advantage of the multiple appsettings.json I have.
And finally, are these approaches aligned with the best practices? If not, what would be the best practices for pipelines with multiple environments?
Generally we can generate a single artifact, then deploy the artifact to different environments and perform the different transformations at any environment within it's own stage release phase. That means we can change and override the settings which defined in the appsettings.json in each release environment.
Please refer to File transforms and variable substitution reference on how to do the transformation with .json files.
Besides, we can try to install the Replace Tokens extension, then use Replace Tokens task to load and change the settings defined in the appsettings.json file in each release environment/stage.
You can also transform the settings or use File Creator to create a new appsettings.jsonfile to overwrite the existing one.
Below blogs for your reference:
Replace appsetting tokens in config files with Build & Release
Management in VSTS (TFS)
Transform configurations in a .NET Core 2.2 Web API using Azure
DevOps
Using custom appsettings.json with ASP.NET Core integration
tests
You could go with Azure AppConfiguration and add it as an extra source for the configuration. This way your building/releasing process stays extremely simple.
See this documentation: https://learn.microsoft.com/en-us/azure/azure-app-configuration/enable-dynamic-configuration-dotnet-core
It's very powerful: you can select only part of the configuration (through filters), you can have feature flags, and you can have secrets (from linked key vaults).

Can you have two or more types defined in different indexes for the same entity?

I’m using Elasticsearch 0.9 with FOSElasticaBundle 3.0.0.alpha6 and Symfony 2.5.10.
Will FOSElastica Listener keep all indexes updated? Can I define different listener services for each environment? I'm asking to see if I can use different indexes for the production, development and test environments.
Will FOSElastica Listener keep all indexes updated
Yes, if you will configure persistence section properly in your config file.
Can I define different listener services for each environment? I'm asking to see if I can use different indexes for the production, development and test environments.
If I understand you well, the solution for that is here.
You can just set other index name in each environment's config (prod, dev, test).
Or even better, you can use kernel.env parameter to dynamically change used indexes depending on current environment:
#app/config/config.yml
fos_elastica:
indexes:
app:
index_name: app_%kernel.env%

Spring Boot Environment-specific configurations

I have a spring boot application that uses the actuator, auto-configuration and JPA. I want to be able to use an in-memory DB in my test profile, a MySQL DB configuration during development and a separate production DB configuration when the app is deployed in production. Presumably from the java command line I should be able to specify the environment and the right configuration file or config block in application.properties (or .yml) will be picked up.
I have not found a good post with example describing how to do this switching so I thought I'd ask if anyone has a good example. My main aim is to pre-define the spring.datasource and spring.jpa properties at build time and then at run-time switch the app config per environment "dynamically" using the java command line argument. Secondary goal would be to do the same with the management configurations, etc.
Thank you.
Thanks to #Richard for the mention of spring.profiles.active JVM variable. Since my question was specific to the way Spring Boot does this and since there is much more to the answer, I am inclined to answer this myself and include all the details of how I arrived at the answer in the hopes that it will save others time.
First, you can indeed pick the correct profile on the java command line by adding -Dspring.profiles.active=profile_name when you are running your Spring Boot app. (this is assuming your deployment preference is an uber jar with embedded container - Tomcat in my case)
I wanted to leave MySQL datasource configurations under the default profile and put H2 in-memory datasource configuration under a test profile. However, the way Spring Boot picks the right datasource based on profile is not so obvious. Even though I had MySQL details under the default profile and I had the in-memory H2 datasource details under the test profile, it would still pick H2 as the datasource even when spring.profiles.active was omitted from the command line. This was contrary to my assumption that default profile will be picked, well, by default :-)
I ended up having to put H2 configuration under the default profile and then create a local profile that included the MySQL datasource configuration. Here's what I ended up with in my application.yml
spring:
profiles: default
spring:
datasource:
driverClassName: org.h2.Driver
url: jdbc:h2:mem:sampletest;MODE=MySQL
---
spring:
profiles: test
spring.jpa:
hibernate:
ddl-auto: create-drop
---
spring:
profiles: local
spring.datasource:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1/sampledev
username: sample
password: sample
spring.jpa:
hibernate:
dialect: org.hibernate.dialect.MySQLInnoDBDialect
ddl-auto: update
This worked. I was able to switch between default profiles and the local profile by omitting or adding the -Dspring.profiles.active=local on the java command line. Because test profile inherits from default it is also using H2
One more nuance: I added ddl-auto: create-drop to the test profile which uses the in-memory DB to facilitate automatic table creation / teardown for unit tests. But for the local profile which uses MySQL I changed it to update. Implication being that for the local profile I have to first create the database outside of the application.
this article shows how to use spring profiles, available in spring 3.1 and later. It will do exactly what you want.
http://chariotsolutions.com/blog/post/spring-3-1-environment-profiles-2/
set a JVM variable like this: spring.profiles.active=development
then in your configuration xml you can wrap environment specific xml with the profile tags
<beans profiles="development">
<bean id="dataSource" class="..."></bean>
<bean id="messagingProvider" class="..."></bean>
</beans>
You can also set the profile on annotation-driven classes with #Profile("development") at the beginning of the class. That class will only be autowired if the profile matches.
For unit tests you can set the active profile on a test class with #ActiveProfile(profiles = "test", "CI"), it will run using test and CI resources

Resources