Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add a parallelDockerUpdateCli shared pipeline combining the bui…
…ldDockerAndPublishImage and updatecli ones
- Loading branch information
1 parent
7ba9194
commit 0afc6fc
Showing
4 changed files
with
240 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
import org.junit.Before | ||
import org.junit.Test | ||
|
||
import mock.CurrentBuild | ||
|
||
import static org.junit.Assert.assertFalse | ||
import static org.junit.Assert.assertTrue | ||
|
||
class ParallelDockerUpdatecliStepTests extends BaseTest { | ||
static final String scriptName = 'vars/parallelDockerUpdatecli.groovy' | ||
static final String testImageName = 'myImage' | ||
static final String anotherMainBranchName = 'another' | ||
static final String anotherCronTriggerExpression = '@daily' | ||
static final String anotherContainerMemory = '512Mi' | ||
static final String anotherCredentialsId = 'another-github-token' | ||
|
||
@Override | ||
@Before | ||
void setUp() throws Exception { | ||
super.setUp() | ||
// Mocks of the shared pipelines we want to test | ||
helper.registerAllowedMethod('buildDockerAndPublishImage', [String.class, Map.class], { s, m -> s + m }) | ||
helper.registerAllowedMethod('updatecli', [Map.class], { m -> m }) | ||
|
||
// Default behavior is a build trigger by a timertrigger on the main branch (most frequent case) | ||
binding.setProperty('currentBuild', new CurrentBuild('SUCCESS', ['hudson.triggers.TimerTrigger'])) | ||
} | ||
|
||
@Test | ||
void itFailsWithDefault() throws Exception { | ||
def script = loadScript(scriptName) | ||
|
||
// when calling with the "parallelDockerUpdatecli" function with default configuration | ||
script.call() | ||
printCallStack() | ||
|
||
// Then we expect a failing build | ||
assertJobStatusFailure() | ||
|
||
// And the error message is shown | ||
assertTrue(assertMethodCallContainsPattern('echo', 'Error: no imageName provided.')) | ||
} | ||
|
||
@Test | ||
void itRunsSuccessfullyWithImageNameOnPrimaryBranch() throws Exception { | ||
def script = loadScript(scriptName) | ||
|
||
// when calling with the "parallelDockerUpdatecli" function with default configuration on the primary branch | ||
addEnvVar('BRANCH_IS_PRIMARY', 'true') | ||
script.call(imageName: testImageName) | ||
printCallStack() | ||
|
||
// Then we expect a successfull build | ||
assertJobStatusSuccess() | ||
|
||
// And the error message is not shown | ||
assertFalse(assertMethodCallContainsPattern('echo', 'Error: no imageName provided.')) | ||
|
||
// And the correct image name is passed to buildDockerAndPublishImage | ||
assertTrue(assertMethodCallContainsPattern('buildDockerAndPublishImage', testImageName)) | ||
|
||
// And updatecli(action: 'diff') is called | ||
assertTrue(assertMethodCallContainsPattern('updatecli', 'action=diff')) | ||
|
||
// And updatecli(action: 'apply') is called only if we are on the primary branch | ||
assertTrue(assertMethodCallContainsPattern('updatecli', 'action=apply')) | ||
} | ||
|
||
@Test | ||
void itRunsSuccessfullyWithImageNameNotOnPrimaryBranch() throws Exception { | ||
def script = loadScript(scriptName) | ||
|
||
// when calling with the "parallelDockerUpdatecli" function with default configuration not on the primary branch (env.BRANCH_IS_PRIMARY not set) | ||
script.call(imageName: testImageName) | ||
printCallStack() | ||
|
||
// Then we expect a successfull build | ||
assertJobStatusSuccess() | ||
|
||
// And the error message is not shown | ||
assertFalse(assertMethodCallContainsPattern('echo', 'Error: no imageName provided.')) | ||
|
||
// And the correct image name is passed to buildDockerAndPublishImage | ||
assertTrue(assertMethodCallContainsPattern('buildDockerAndPublishImage', testImageName)) | ||
|
||
// And updatecli(action: 'diff') is called | ||
assertTrue(assertMethodCallContainsPattern('updatecli', 'action=diff')) | ||
|
||
// And updatecli(action: 'apply') is called only if we are on the primary branch | ||
assertFalse(assertMethodCallContainsPattern('updatecli', 'action=apply')) | ||
} | ||
|
||
@Test | ||
void itRunsSuccessfullyWithImageNameWithoutRebuildImage() throws Exception { | ||
def script = loadScript(scriptName) | ||
|
||
// when calling with the "parallelDockerUpdatecli" function with rebuildImageOnPeriodicJob set to false | ||
script.call(imageName: testImageName, rebuildImageOnPeriodicJob: false) | ||
printCallStack() | ||
|
||
// Then we expect a successfull build | ||
assertJobStatusSuccess() | ||
|
||
// And the error message is not shown | ||
assertFalse(assertMethodCallContainsPattern('echo', 'Error: no imageName provided.')) | ||
|
||
// And buildDockerAndPublishImage is not called (default behavior set as a build trigger by a TimerTrigger) | ||
assertFalse(assertMethodCallContainsPattern('buildDockerAndPublishImage', testImageName)) | ||
|
||
// And updatecli(action: 'diff') is called | ||
assertTrue(assertMethodCallContainsPattern('updatecli', 'action=diff')) | ||
} | ||
|
||
@Test | ||
void itRunsSuccessfullyWithImageNameWithoutRebuildImageNorTimerTrigger() throws Exception { | ||
def script = loadScript(scriptName) | ||
|
||
// when calling with the "parallelDockerUpdatecli" function with rebuildImageOnPeriodicJob set to false, and the trigger is not a TimerTrigger | ||
binding.setProperty('currentBuild', new CurrentBuild('SUCCESS', ['hudson.triggers.NotATimerTrigger'])) | ||
script.call(imageName: testImageName, rebuildImageOnPeriodicJob: false) | ||
printCallStack() | ||
|
||
// Then we expect a successfull build | ||
assertJobStatusSuccess() | ||
|
||
// And the error message is not shown | ||
assertFalse(assertMethodCallContainsPattern('echo', 'Error: no imageName provided.')) | ||
|
||
// And buildDockerAndPublishImage is called (default behavior set as a build trigger which is not a timertrigger) | ||
assertTrue(assertMethodCallContainsPattern('buildDockerAndPublishImage', testImageName)) | ||
|
||
// And updatecli(action: 'diff') is called | ||
assertTrue(assertMethodCallContainsPattern('updatecli', 'action=diff')) | ||
} | ||
|
||
|
||
@Test | ||
void itRunsSuccessfullyWithCustomParameters() throws Exception { | ||
def script = loadScript(scriptName) | ||
|
||
// when calling with the "parallelDockerUpdatecli" function with custom parameters | ||
// Note: imageName & rebuildImageOnPeriodicJob have already been tested in other tests | ||
addEnvVar('BRANCH_IS_PRIMARY', 'true') | ||
script.call( | ||
imageName: testImageName, | ||
mainBranch: anotherMainBranchName, | ||
cronTriggerExpression: anotherCronTriggerExpression, | ||
containerMemory: anotherContainerMemory, | ||
credentialsId: anotherCredentialsId | ||
) | ||
printCallStack() | ||
|
||
// Then we expect a successfull build | ||
assertJobStatusSuccess() | ||
|
||
// And the error message is not shown | ||
assertFalse(assertMethodCallContainsPattern('echo', 'Error: no imageName provided.')) | ||
|
||
// And the correct image name is passed to buildDockerAndPublishImage | ||
assertTrue(assertMethodCallContainsPattern('buildDockerAndPublishImage', testImageName)) | ||
|
||
// And updatecli(action: 'diff') is called | ||
assertTrue(assertMethodCallContainsPattern('updatecli', 'action=diff')) | ||
|
||
// And the custom parameters are taken in account | ||
assertTrue(assertMethodCallContainsPattern('buildDockerAndPublishImage', 'mainBranch=' + anotherMainBranchName)) | ||
assertTrue(assertMethodCallContainsPattern('string', anotherCredentialsId)) | ||
assertTrue(assertMethodCallContainsPattern('updatecli', 'cronTriggerExpression=' + anotherCronTriggerExpression)) | ||
assertTrue(assertMethodCallContainsPattern('updatecli', 'containerMemory=' + anotherContainerMemory)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
def call(userConfig = [:]) { | ||
def defaultConfig = [ | ||
imageName: '', | ||
mainBranch: 'main', | ||
rebuildImageOnPeriodicJob: true, | ||
cronTriggerExpression: '@weekly', | ||
containerMemory: '128Mi', | ||
credentialsId: 'updatecli-github-token' | ||
] | ||
|
||
// Merging the 2 maps - https://blog.mrhaki.com/2010/04/groovy-goodness-adding-maps-to-map_21.html | ||
final Map finalConfig = defaultConfig << userConfig | ||
|
||
if (finalConfig.imageName == '') { | ||
echo 'Error: no imageName provided.' | ||
currentBuild.result = 'FAILURE' | ||
return | ||
} | ||
parallel( | ||
failFast: true, | ||
'docker-image': { | ||
// Do not rebuild the image when triggered by a periodic job if the config desactivate them | ||
if (finalConfig.rebuildImageOnPeriodicJob || (!finalConfig.rebuildImageOnPeriodicJob && !currentBuild.getBuildCauses().contains('hudson.triggers.TimerTrigger'))) { | ||
buildDockerAndPublishImage(finalConfig.imageName, [ | ||
mainBranch: finalConfig.mainBranch, | ||
automaticSemanticVersioning: true, | ||
gitCredentials: 'github-app-infra' | ||
]) | ||
} | ||
}, | ||
'updatecli': { | ||
withCredentials([string(credentialsId: finalConfig.credentialsId,variable: 'UPDATECLI_GITHUB_TOKEN')]) { | ||
updatecli(action: 'diff') | ||
if (env.BRANCH_IS_PRIMARY) { | ||
updatecli(action: 'apply', cronTriggerExpression: finalConfig.cronTriggerExpression, containerMemory: finalConfig.containerMemory) | ||
} | ||
} | ||
}, | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
This pipeline combines "buildDockerAndPublishImage" and "updatecli" shared pipelines. It lints, Builds, Tests and eventually Publishes a Docker image, and run in parallel updatecli. | ||
|
||
The following arguments are available for this function: | ||
- String **imageName**: (Mandatory) name of the image to built, usually referenced as the "Repository" part of a Docker image's name without any tag (Example: "builder" or "terraform"). | ||
- String **mainBranch**: (Optional - Default: "main") name of the main branch of the repository | ||
- String **rebuildImageOnPeriodicJob**: (Optional - Default: true) specify if the docker image has to be rebuilt and republished when triggered by a periodic job. | ||
- String **cronTriggerExpression**: (Optional - Default: "@weekly") Enable periodic updatecli execution by providing a cron-like expression. | ||
- String **containerMemory**: (Optional - Default: "128Mi") specify the amount of memory dedicated to the updatecli container. | ||
- String **credentialsId**: (Optional - Default: "updatecli-github-token") specify the credentials used by updatecli to interact with github. | ||
|
||
Examples: | ||
<code> | ||
// build and publish the docker image, and in parallel run "updatecli diff" command and also "updatecli apply" if the pipeline is on the main branch. | ||
parallelDockerUpdatecli([imageName: 'myDockerImage']) | ||
|
||
// build and publish the docker image only if there is a code change, and in parallel run "updatecli diff" command and also "updatecli apply" if the pipeline is on the main branch. | ||
parallelDockerUpdatecli([imageName: 'myDockerImage', rebuildImageOnPeriodicJob: false]) | ||
</code> |