├── .gitignore ├── LICENSE.md ├── README.md ├── check_for_changelog.rb ├── ci └── seed.groovy ├── docs ├── Illegal_JENKINS24754.png ├── More_than_1_gitBuild_data.png ├── SoW │ ├── branch-context.md │ └── pipeline-job-compliance.md ├── flow_diagram.png ├── flow_diagram.xml ├── flow_diagram_readme.txt ├── legal_JENKINS24754.png └── scripted-pipelines.md ├── git-work-flows-scripts ├── integrating-branch-head.sh ├── multiple-branch-heads.sh ├── readme.md ├── steps-corret-work-flow-accummulated.sh ├── steps-corret-work-flow-squash.sh ├── steps-fail-accummulated.sh ├── steps-fail-squash.sh ├── steps-merge-flow-squash.sh └── steps-normal-merge.sh ├── jenkins-pipeline ├── Jenkinsfile └── pipeline.groovy ├── pom.xml ├── settings.xml └── src ├── main ├── java │ └── org │ │ └── jenkinsci │ │ └── plugins │ │ └── pretestedintegration │ │ ├── AbstractSCMBridge.java │ │ ├── IntegrationStrategy.java │ │ ├── IntegrationStrategyDescriptor.java │ │ ├── PretestedIntegrationJobDslExtension.java │ │ ├── PretestedIntegrationPostCheckout.java │ │ ├── SCMBridgeDescriptor.java │ │ ├── exceptions │ │ ├── BranchDeletionFailedException.java │ │ ├── CommitFailedException.java │ │ ├── EstablishingWorkspaceFailedException.java │ │ ├── IntegrationFailedException.java │ │ ├── IntegrationUnknownFailureException.java │ │ ├── NothingToDoException.java │ │ ├── PushFailedException.java │ │ └── UnsupportedConfigurationException.java │ │ └── scm │ │ └── git │ │ ├── AccumulatedCommitStrategy.java │ │ ├── FindCommitAuthorCallback.java │ │ ├── FindCommitMessageCallback.java │ │ ├── GetAllCommitsFromBranchCallback.java │ │ ├── GetCommitCountFromBranchCallback.java │ │ ├── GitBridge.java │ │ ├── GitIntegrationStrategy.java │ │ ├── GitMessages.java │ │ ├── IntegrationStrategyAsGitPluginExt.java │ │ ├── PretestTriggerCommitAction.java │ │ ├── PretestedIntegrationAsGitPluginExt.java │ │ ├── PretestedIntegrationGitUtils.java │ │ ├── PretestedIntegrationSCMTrait.java │ │ ├── RepositoryListenerAwareCallback.java │ │ └── SquashCommitStrategy.java └── resources │ ├── index.jelly │ └── org │ └── jenkinsci │ └── plugins │ └── pretestedintegration │ ├── PretestedIntegrationBuildWrapper │ ├── config.jelly │ ├── global.jelly │ ├── help-stageRepositoryUrl.html │ └── index.jelly │ ├── PretestedIntegrationPostCheckout │ └── config.jelly │ └── scm │ └── git │ ├── AccumulatedCommitStrategy │ ├── config.jelly │ └── help.html │ ├── GitBridge │ ├── config.jelly │ ├── help-branch.html │ └── help-repoName.html │ ├── PretestedIntegrationAsGitPluginExt │ ├── config.jelly │ ├── help-integrationBranch.html │ └── help-repoName.html │ └── SquashCommitStrategy │ ├── config.jelly │ └── help.html └── test ├── java └── org │ └── jenkinsci │ └── plugins │ └── pretestedintegration │ ├── credentials │ └── CredentialsTest.java │ ├── integration │ └── scm │ │ └── git │ │ ├── AccumulatedCommitMessageIT.java │ │ ├── AccumulatedCommitStrategyIT.java │ │ ├── BuildResultValidator.java │ │ ├── ChangelessBranchFailsBuildIT.java │ │ ├── CommitMessagesWithSpecialCharsIT.java │ │ ├── CustomIntegrationBranchIT.java │ │ ├── EnvVarsIT.java │ │ ├── FastForwardSingleCommitsIT.java │ │ ├── GHI97_SupportChecksIT.java │ │ ├── GHI98_SupportForCredentialsIT.java │ │ ├── GeneralBehaviourIT.java │ │ ├── GetCommitCountFromBranchCallbackIT.java │ │ ├── GitSubmoduleInteractionIT.java │ │ ├── IntegrationBranchNameRestrictions_IT.java │ │ ├── JENKINS_24754_IT.java │ │ ├── JobDSLIT.java │ │ ├── MatrixProjectBuilder.java │ │ ├── MatrixProjectCompatibilityTestIT.java │ │ ├── NothingToDoFailsBuild.java │ │ ├── PipAsGitExtensionIT.java │ │ ├── SquashCommitStrategyIT.java │ │ ├── StaticGitRepositoryTestBase.java │ │ ├── TestCommit.java │ │ ├── TestUtilsFactory.java │ │ ├── TwoBranchHeadsIT.java │ │ ├── UniqueBranchGenerator.java │ │ └── UseAuthorOfLastCommitIT.java │ └── unit │ ├── AbstractSCMBridgeTest.java │ ├── DummyBridge.java │ ├── DummyIntegrationStrategy.java │ ├── DummySCM.java │ └── GitIntegrationStrategyTest.java └── resources ├── EndUserTesting ├── Jenkinsfile ├── JenkinsfileDeclCheckoutSCM ├── JenkinsfileDeclPreSCM ├── JenkinsfileScriptedCheckoutSCM ├── JenkinsfileScriptedPreSCM ├── README.md ├── createRepoForIntegrationSituations.sh └── jobs │ ├── test-FsExtAcc │ └── config.xml │ ├── test-FsExtSq │ └── config.xml │ ├── test-MuExtAcc │ └── config.xml │ ├── test-MuExtSq │ └── config.xml │ ├── test-MultiBranchPipePreSCM │ └── config.xml │ ├── test-MvnExtAcc │ └── config.xml │ ├── test-MxExtAcc │ └── config.xml │ ├── test-MxExtSq │ └── config.xml │ ├── test-PipeDeclCheckoutSCM │ └── config.xml │ ├── test-PipeDeclPreSCM │ └── config.xml │ ├── test-PipeDeclScript │ └── config.xml │ ├── test-PipeScriptedCheckoutSCM │ └── config.xml │ ├── test-PipeScriptedPreSCM │ └── config.xml │ └── test-PipeScriptedScript │ └── config.xml ├── JENKINS-28640.md ├── JENKINS-28640.zip ├── commitMessagesWithDoubleQuotes.md ├── commitMessagesWithDoubleQuotesSingleQuotesMade.md ├── commitMessagesWithDoubleQuotesSingleQuotesMade_linux-repo_description.log ├── commitMessagesWithDoubleQuotesSingleQuotesMade_linux.sh ├── commitMessagesWithDoubleQuotesSingleQuotesMade_linux.zip ├── commitMessagesWithDoubleQuotesSingleQuotesMade_windows-repo_description.log ├── commitMessagesWithDoubleQuotesSingleQuotesMade_windows.bat ├── commitMessagesWithDoubleQuotesSingleQuotesMade_windows.zip ├── commitMessagesWithDoubleQuotes_linux-repo_description.log ├── commitMessagesWithDoubleQuotes_linux.sh ├── commitMessagesWithDoubleQuotes_linux.sh.log ├── commitMessagesWithDoubleQuotes_linux.zip ├── commitMessagesWithDoubleQuotes_windows.bat ├── commitMessagesWithDoubleQuotes_windows.bat.log ├── commitMessagesWithDoubleQuotes_windows.zip ├── customIntegrationBranch-repo_description.log ├── customIntegrationBranch.md ├── customIntegrationBranch.sh ├── customIntegrationBranch.zip ├── howtoTestUsingStaticGitRepos.md ├── useAuthorOfLastCommit-repo_description.log ├── useAuthorOfLastCommit.md ├── useAuthorOfLastCommit.sh └── useAuthorOfLastCommit.zip /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | /target 3 | /work 4 | 5 | # Package Files # 6 | *.jar 7 | *.war 8 | *.ear 9 | 10 | *.swp 11 | *~ 12 | # Eclipse files # 13 | .classpath 14 | .project 15 | .settings/ 16 | 17 | # idea files # 18 | .idea/ 19 | *.iml 20 | 21 | # testing # 22 | /src/test/resources/keys/* 23 | **/*.git 24 | /test-*/ 25 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Praqma 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /check_for_changelog.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # encoding: utf-8 3 | require 'open3' 4 | require 'docopt' 5 | require "pp" 6 | require 'fileutils' 7 | require 'rubygems' 8 | require 'nokogiri' 9 | require 'open-uri' 10 | 11 | 12 | doc = <2.2.3-SNAPSHOT 18 | ... 19 | 20 | then there must be a changelog entry on URL (could be https://wiki.jenkins-ci.org/display/JENKINS/Pretested+Integration+Plugin): 21 | 22 | ... 23 | h5. Version 2.2.3 24 | ... 25 | 26 | Script could of course be improved to to take regexp to look for etc. 27 | 28 | Usage: 29 | #{__FILE__} URL 30 | #{__FILE__} -h 31 | 32 | example: 33 | ./check_for_changelog.rb https://wiki.jenkins-ci.org/display/JENKINS/Pretested+Integration+Plugin 34 | 35 | Arguments: 36 | URL URL to look for changelog entry "h5. Version %VERSION", where %VERSION matches version in pom xml 37 | 38 | Options: 39 | -h --help show this help message and exit 40 | 41 | DOCOPT 42 | 43 | 44 | if __FILE__ == $0 45 | begin 46 | params = Docopt::docopt(doc) 47 | pp params 48 | 49 | version = "none" 50 | result = false 51 | found = false 52 | filename="pom.xml" 53 | max_lines_to_check = 30 # only check first 30 lines, and the project version is there 54 | File.open(filename, "r").each_line do |line| 55 | if (max_lines_to_check < 0) then 56 | break 57 | end 58 | if mymatch = line.match('([0-9]+\.[0-9]+\.[0-9]+)-SNAPSHOT') then 59 | # matchdata returned: 60 | #pp mymatch[0] # matches the hole line 61 | #pp mymatch[1] # matches the grouping around the version number 62 | if mymatch[1].match(/[0-9]+\.[0-9]+\.[0-9]+/) then ## extra check 63 | # This how the plugin need the environment variables 64 | found = true 65 | version = mymatch[1] 66 | pp "Found version number in pom to be: #{ version }" 67 | break 68 | end 69 | #pp line 70 | max_lines_to_check = max_lines_to_check - 1 71 | end 72 | end 73 | 74 | 75 | 76 | 77 | # https://blog.engineyard.com/2010/getting-started-with-nokogiri 78 | page = Nokogiri::HTML(open(params["URL"])) 79 | # Find all "a" tags with a parent tag whose name is "h5" 80 | # as we know h3 is the version number headers in the changelog 81 | #
Version 2.2.3
82 | 83 | page.xpath('//h5/a').each do |node| 84 | # nodes look like this: 85 | # #(Element:0x10970bc { 86 | # name = "a", 87 | # attributes = [ 88 | # #(Attr:0x1096d4c { 89 | # name = "name", 90 | # value = "PretestedIntegrationPlugin-Version2.2.3" 91 | # })] 92 | # }) 93 | 94 | # node["name"] will look like: PretestedIntegrationPlugin-Version2.2.3 95 | if mymatch = /PretestedIntegrationPlugin-Version([\d|\.]+.*)/.match(node["name"]) then 96 | if mymatch[1] == version then 97 | pp "Found match with version and changelog entry on web page - great job!" 98 | result = true 99 | end 100 | end 101 | end 102 | 103 | if not result then 104 | abort("Could find any changelog entry on the url - please create a changelog") 105 | end 106 | 107 | rescue Docopt::Exit => e 108 | puts "ERROR - #{ __FILE__ } - wrong usage.\n" << e.message 109 | abort() # needed for non zero exit code 110 | end 111 | end 112 | -------------------------------------------------------------------------------- /ci/seed.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | 1. Mask passwords plugin must be isntalled. 3 | 2. Two environment variables must be available for the release and beta release jobs 4 | A) PWFORPRAQMAMVNUSER - The password for your jenkins-ci.org account (Artifactory) 5 | B) PW_HTTPS_RELEASE_PRAQMA - Https password for your GitHub user account 6 | */ 7 | 8 | def pretestedGitUrl = "https://github.com/Praqma/pretested-integration-plugin.git" 9 | def credentialsId = "github" 10 | def pipJobName = "pretested-integration-plugin-verify" 11 | def devBranchPattern = "master" 12 | def integrationBranchName = "master" 13 | 14 | def descriptionForPipJob = """

Pretested Integration Plugin

15 |

Requires a volume pretested-integration-plugin-volume which is mounted to the .m2 directory of the docker image

16 |

This is done to avoid having to download dependencies every time

17 | """ 18 | job(pipJobName) { 19 | description("Runs pretested integration for Pretested Integration ") 20 | parameters { 21 | stringParam("BRANCH") 22 | } 23 | scm { 24 | git { 25 | branch("\${BRANCH}") //TODO: Switch to ready when done 26 | remote { 27 | name("origin") 28 | url(pretestedGitUrl) 29 | credentials(credentialsId) 30 | } 31 | } 32 | } 33 | 34 | steps { 35 | shell("docker run -w /usr/src/mymaven --rm -t -v \$(pwd):/usr/src/mymaven -v pretested-integration-plugin-volume:/root/.m2 maven:3.5.2-jdk-8 /bin/bash -c 'git config --global user.email \"release@praqma.net\" && git config --global user.name \"Praqma Release User\" && mvn -B -DdryRun=true clean release:clean release:prepare'") 36 | } 37 | 38 | publishers { 39 | archiveJunit('**/target/failsafe-reports/TEST*.xml') 40 | /* pretestedIntegrationPublisher() */ 41 | buildPipelineTrigger('pretested-integration-plugin-release, pretested-integration-plugin-release-beta') { 42 | parameters { 43 | gitRevision() 44 | } 45 | } 46 | } 47 | } 48 | 49 | job("pretested-integration-plugin-release-beta") { 50 | scm { 51 | git { 52 | branch(integrationBranchName) 53 | remote { 54 | name("origin") 55 | url(pretestedGitUrl) 56 | credentials(credentialsId) 57 | } 58 | } 59 | } 60 | wrappers { 61 | 62 | maskPasswords() 63 | injectPasswords { 64 | injectGlobalPasswords() 65 | maskPasswordParameters() 66 | } 67 | } 68 | steps { 69 | //run -v ~/.m2:/var/maven/.m2 -v $(pwd):/usr/app -w /usr/app -t --rm -u 1000:1000 -e MAVEN_CONFIG=/var/maven/.m2 70 | //shell("docker run -w /usr/src/mymaven --rm -t -v \$(pwd):/usr/src/mymaven -v pretested-integration-plugin-volume:/root/.m2 -e PWFORPRAQMAMVNUSER=${PWFORPRAQMAMVNUSER} maven:3.5.2-jdk-8 /bin/bash -c \"git config --global user.email \\\"release@praqma.net\\\" && git config --global user.name \\\"Praqma Release User\\\" && mvn -s settings.xml -B -Dusername=ReleasePraqma -Dpassword=${PW_HTTPS_RELEASE_PRAQMA} clean release:clean release:prepare release:perform\"") 71 | //shell("docker run -w /usr/src/app -u 1000:1000 --rm -t -v \$(pwd):/usr/src/app -v ~/.m2:/var/maven/.m2 -e PWFORPRAQMAMVNUSER=${PWFORPRAQMAMVNUSER} -e MAVEN_CONFIG=/var/maven/.m2 maven:3.5.2-jdk-8 /bin/bash -c \"git config --global user.email \\\"release@praqma.net\\\" && git config --global user.name \\\"Praqma Release User\\\" && mvn -s settings.xml -B -Dusername=ReleasePraqma -Dpassword=${PW_HTTPS_RELEASE_PRAQMA} -Duser.home=/var/maven clean release:clean release:prepare release:perform\"") 72 | } 73 | } 74 | 75 | job("pretested-integration-plugin-release") { 76 | scm { 77 | git { 78 | remote { 79 | name("origin") 80 | url(pretestedGitUrl) 81 | credentials(credentialsId) 82 | } 83 | } 84 | } 85 | steps { 86 | shell("echo 'Hello world! from pretested-integration-plugin-release-beta'") 87 | } 88 | } 89 | 90 | job("pretested-integration-plugin-sync") { 91 | triggers { 92 | upstream("pretested-integration-plugin-release") 93 | } 94 | } 95 | 96 | 97 | buildPipelineView("pretested-integration-plugin-build-pipeline-view") { 98 | title("Pretested Integration Build Pipeline View") 99 | selectedJob(pipJobName) 100 | } 101 | -------------------------------------------------------------------------------- /docs/Illegal_JENKINS24754.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/pretested-integration-plugin/16c04bae14e55fec1a785c4b27f056a3479391cb/docs/Illegal_JENKINS24754.png -------------------------------------------------------------------------------- /docs/More_than_1_gitBuild_data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/pretested-integration-plugin/16c04bae14e55fec1a785c4b27f056a3479391cb/docs/More_than_1_gitBuild_data.png -------------------------------------------------------------------------------- /docs/SoW/branch-context.md: -------------------------------------------------------------------------------- 1 | # Branch Context for PIP - statement of Work 2 | 3 | ## Problem 4 | 5 | When an integration is not successful the only place to find information is in the relevant Jenkins build. If the failures are not noticed and handled immediately you can easily loose the overview of the state of all the ready branches when you only look at the branches in your DVCS. Are the ready branches there because they failed, or are they waiting in queue? To see the status you would have to visit the Jenkins server, but it might have been easier to detect the problem in context of some branch naming conventions. 6 | 7 | ## Solution 8 | We propose a solution where we supply information about the integration process as a branch context by renaming the ready branches processed. 9 | The context is applied as follows to a ready-branch pushed to `ready/my-feature` 10 | * When processing it is renamed `wip/my-feature` 11 | * When successfully integrated the branch is deleted 12 | * If integration fails due og merge failure it is left renamed as `merge-failed/my-feature` 13 | * If build fails (build steps, or any other reason) the branch is left renamed as `build-failed/my-feature` 14 | 15 | When the problem is solved, we support that the developer just pushes to the same ready-branch (`ready/my-feature`). 16 | The plugin cleans up automatically all branches used in the workflow, meaning if success all ``*/my-feature` is deleted. 17 | 18 | **Renamed means the original ready/my-feature branch is deleted.** 19 | 20 | **Branch context support layers of branch prefixes, so it will also work with ready-branches called `rel-1.0.0/ready/my-feature`.** 21 | For example a merge failure end in `rel-1.0.0/merged-failed/my-feature`, and when again successful all branches matchin `rel-1.0.0/*/my-feature` is cleaned. 22 | 23 | ## Implementation 24 | This new branch context feature will be backwards compatible, and will be available as a configuration choice. We will not include support to configure the renaming patterns, but we can decide the naming patterns together before implementation. 25 | 26 | ## Deliveries 27 | New public release with branch context support and updated documentation for this feature. 28 | 29 | ## Work load 30 | The workload for this piece of work is estimated to about 40 hours. 31 | -------------------------------------------------------------------------------- /docs/SoW/pipeline-job-compliance.md: -------------------------------------------------------------------------------- 1 | # Pipeline job compliance - statement of work 2 | 3 | ## Problem 4 | The easiest way to implement the automation in Jenkins for the [Git Phlow](https://github.com/Praqma/git-phlow ) is to use the Pretested Integration Plugin (PIP), but it can not be used in [Pipeline jobs](https://jenkins.io/doc/book/pipeline/) described with neither [Declarative Pipeline or Scripted Pipeline syntax](https://jenkins.io/doc/book/pipeline/syntax/). It only works in the other popular alternative for scripted jobs, namely Jenkins Job DSL. 5 | In addition the plugin restricts it use to only the Freestyle job type in Jenkins, not allowing for more creative job setups and the Matrix job types because the pretesting part (get changes, merge and run build step) is not possible to separate from the integration step where we push changes after a successful build 6 | 7 | ## Solution 8 | We will implement support for using PIP in Pipeline jobs, both supporting Declarative Pipeline and Scripted Pipeline syntax. 9 | The plugin will still support Jenkins Job DSL as well. 10 | We will support separation of the pretesting part from the integration part, so more creative job construction can be used allowing the user to control these steps on their own. 11 | Officially we will still only support Freestyle jobs and now Pipeline jobs. 12 | 13 | ## Implementation 14 | To support the solution the plugin will be changed to a Git Plugin extension instead. The integration part where we push the changes will be available as an independent post-build step in Jenkins. 15 | The plugin will _not_ be backwards compatible. 16 | 17 | ## Deliveries 18 | New public release with support for both Pipeline job syntax and Jenkins job DSL syntax. Updated documentation, and examples of all three scripted job types. 19 | An example of how to use it with Matrix job type, or explanation of outstanding issues for this to work and possible work-arounds. 20 | 21 | ## Work load 22 | The work is estimated to about 60 hours of work. 23 | -------------------------------------------------------------------------------- /docs/flow_diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/pretested-integration-plugin/16c04bae14e55fec1a785c4b27f056a3479391cb/docs/flow_diagram.png -------------------------------------------------------------------------------- /docs/flow_diagram.xml: -------------------------------------------------------------------------------- 1 | 1Vpdm6I2FP41XjKPCKh7OWNndi667bZ22u7VPFEi8CwSN+I49tfvCZwDgej4hWi9kRzy+Z73fCSh44zm758lW4RfhM/jTq/rv3ecXzq9nu3ZDvwpySaXDLxuLghk5OciTTCO/uPYkqSryOdLlOWiVIg4jRZV4VQkCZ+mFRmTUqyr1WYixlFRsGABjogDKsF4ymKaRyn9J/LTMJcOe/1S/syjIKSR7f6n/M2ETb8HUqwSHK/Tc2bZL389Z9RXNq7zCCBKIaAb9TR/H/FYAVnF6GnH22KSkic4kT0NcPrLdEML5T6sG4tCpqEIRMLix1L6kC2Gqx66UArTeQyPNjyao+OElmIlp9g/lDPlMRlwrOXlIjWy1gxn/JmLOU/lBipIHrM0eqtqhKFig6JeuV54wCVvXz7O5Y3FK+x0DPNKTUziGHim1q6tdhmyhXq/VE2gXareL2IWJVYgGdD8YQat/kaYdmLzxmXKyUy2r5veIjPRgqi4LunooijUmEiyc3CyBwZQ38AY26YO8kSnDvK3feo4OBkNkt/ELSCCbmcvIkgqq3s3GHronA9GKevuXiqalxUWIkrSjBU42lcl0IbqeWhwxOB+Pv8S8rzLWnPqX8xmS1hlXUnFmg7TGzLm5vRG5nyM4uxPuJrLKo70VOot50ubejPNbRwlAahChfz5PAIUnzq9fgz/DxMJT4F6MhQrQzGfrGBiD+swSvl4wTKVrCFpqaoxd+RSabhpP265NThpcZontyk90l35sAlXPrwJV4681Q0AY8wR/HcHlGQdx/9LuRYzSirXspeTV8AaSXAM1q1ECLtbNQ2nW8lf24kQyKnrRogtSjshQritqK0eH66hNTOsj1iiNnpsmVozIddM+mq7xQHP/2+o6PXNpP9yoQINoUXWowetsB5z0/ZTfNOdP20jU5GAHECpAhyFyBVp5VS3ki65XZ1WdBCi04rodw6sLum9PVphuLssrZqJeN7gA995gl80070/+YTBWcZlaTtRwzVAVCO00HFGG0ylvLxFpqLLvUWm1nfvTTPVTLvGP1ZsGZaO9paJ6thVdNolKqZ5LRKVktEbZGrdZzRNVFp69dg48StJwSW4uoF5iHUjJ8lX9Ko2TbeE7/ckVrOLVMJeQEfIjf94uR8/kxh6L95kgEo4eA+g9V7AW3UHPUrKiYMmwMVNkw4wJWZnAWxea3wI8P1o9PLl5df7vx6havFaB7pplBsjsoEz7XtawRndnYbzI9zyHXV5xBP/CldH3hY6XuruyDXZSDTyozfVeRwFSfai/2OlLj4fYj5TaSmWiGqBylWLPZc1z7jqZuXX+TJQMisRlrpYzZ8ov4VqqqbkzN+8jp/vTRbnXRf1t/fNVhBFoUnZF0lMoyhMKFviDlMhDiQi0/9BlpPR43w+9Pr7sxVniHuHxjeApt2YRpP4EKTBRyh4kprx+JAVFpFTFb6yNOVSkQiW3XXPyWGIrntzGA2pbQcwJDv1ZBoV5XSxCR0A2Ri5qYt8PdhKv+mvd+RVOyqSJOooB8Ho6IT8iA4dNf3WbBeM1BJ5SKoaZhmcdkeYGzIbl7Shhxu6YdzGhrPMxrwCa9xsABq5+RfjTlb4pgp3niq+R6l6pVqr5/LNqUd7RJQbsTXLHaLqUL0W7UmPNTbLJRJQT4NaTw1am3nyfU58nYZ8+l2s8rC5P2ZKOkyCyrAWDoaWRiJ5nUiWTGHrviPSVgY5vN0OB5Lw9esHM739cGz1wfoqbp529Lpjoa80dOrbeNVynmcxT7ov6Fnu4FhNdy7nuxYygVNuONtyLR46gOLjrZNdC7WkXP4wz3L8wTR94USUHOSUbOoUxTXP++pGvqTzv4890U1bskNhu2LJWKfpFIFyvGulCDsBPOUDtZYs06mdIDh4Wni8ZTpddDqUHdIHIWcHfSiW3wTn1cuvrJ3Hnw== -------------------------------------------------------------------------------- /docs/flow_diagram_readme.txt: -------------------------------------------------------------------------------- 1 | XML can be loaded and edited at https://www.draw.io/ 2 | -------------------------------------------------------------------------------- /docs/legal_JENKINS24754.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/pretested-integration-plugin/16c04bae14e55fec1a785c4b27f056a3479391cb/docs/legal_JENKINS24754.png -------------------------------------------------------------------------------- /docs/scripted-pipelines.md: -------------------------------------------------------------------------------- 1 | # Generating scripted pipelines in Jenkins 2 | Jenkins has a syntax generator that can aide in generating scripted pipeline 3 | 4 | #### The syntax generator 5 | The syntax generator can generate the PiP setup for us, just follow these points: 6 | - In the `sample step` choose `checkout: General SCM` 7 | - use `Git` as `SCM` 8 | - Fill in the url to your repository - Github, bitbucket, gitlab etc. 9 | - Choose the set of credentials you use with your repo 10 | - In `Branches to build` choose the `branch specifier` to be `*/ready/**` 11 | - In `Additional Behaviours` choose `Use Pretested Integration`, that should give two extra options. 12 | - As `integration branch` choose the name of your integration branch, normally it is `master` 13 | - As `repository name` it should be `origin` 14 | - Click `Generate Pipeline Script` 15 | 16 | This should output a long line in the text field which you will use as the first step in the scripted pipeline. To push you changes add `pretestedIntegration()` after the end of your job 17 | 18 | 19 | ### Simple pipeline script example 20 | This is an example of a pipeline script with a single pipeline job that does Pretested Integration, a mvn install and pushes the changes to the integration branch after the previous steps are successful. 21 | 22 | ``` groovy 23 | node { 24 | checkout([$class: 'GitSCM', branches: [[name: '*/ready/**']], doGenerateSubmoduleConfigurations: false, extensions: [pretestedIntegration(pretestedIntegration: squash(), integrationBranch: 'master', repoName: 'origin')], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'GitHub', url: 'https://github.com/Praqma/phlow-test.git']]]) 25 | sh 'mvn install' 26 | pretestedIntegrationPublisher() 27 | } 28 | ``` 29 | -------------------------------------------------------------------------------- /git-work-flows-scripts/integrating-branch-head.sh: -------------------------------------------------------------------------------- 1 | rm -rf mytest mytest2 mytest3 mytest4 2 | 3 | BDIR=`pwd` 4 | 5 | # First create tw repos, and shows that branches are listed in what seems to be alpha-numeric order: 6 | 7 | git init mytest 8 | cd mytest/ 9 | date +%N> date.log 10 | git add date.log 11 | git commit -m "date log 1" 12 | git checkout -b ready/bue-dev 13 | date +%N>> date.log 14 | git add date.log 15 | git commit -m "date log 2 lines" 16 | date +%N>> date.log 17 | git add date.log 18 | git commit -m "date log 3 lines" 19 | git checkout -b team-frontend/dev 20 | git log 21 | LAST_SHA=`git rev-parse HEAD` 22 | git branch --contains $LAST_SHA 23 | git checkout ready/bue-dev 24 | git branch --contains $LAST_SHA 25 | git checkout master 26 | git branch --contains $LAST_SHA 27 | 28 | git checkout master 29 | git merge --squash ready/bue-dev 30 | git commit -C ready/bue-dev 31 | 32 | 33 | cd $BDIR 34 | git init mytest2 35 | cd mytest2 36 | date +%N> date.log 37 | git add date.log 38 | git commit -m "date log 1" 39 | git checkout -b feature/team-dev 40 | date +%N>> date.log 41 | git add date.log 42 | git commit -m "date log 2 lines" 43 | date +%N>> date.log 44 | git add date.log 45 | git commit -m "date log 3 lines" 46 | git checkout -b ready/bue-dev 47 | git log 48 | LAST_SHA=`git rev-parse HEAD` 49 | git branch --contains $LAST_SHA 50 | git checkout feature/team-dev 51 | git branch --contains $LAST_SHA 52 | git checkout master 53 | git branch --contains $LAST_SHA 54 | 55 | git checkout master 56 | git merge --squash ready/bue-dev 57 | git commit -C ready/bue-dev 58 | 59 | 60 | cd $BDIR 61 | 62 | echo ------------------------- 63 | 64 | git init mytest3 65 | cd mytest3/ 66 | date +%N> date.log 67 | git add date.log 68 | git commit -m "date log 1" 69 | git checkout -b ready/bue-dev 70 | date +%N>> date.log 71 | git add date.log 72 | git commit -m "date log 2 lines" 73 | date +%N>> date.log 74 | git add date.log 75 | git commit -m "date log 3 lines" 76 | git checkout -b team-frontend/dev 77 | git log 78 | LAST_SHA=`git rev-parse HEAD` 79 | git branch --contains $LAST_SHA 80 | git checkout ready/bue-dev 81 | git branch --contains $LAST_SHA 82 | git checkout master 83 | git branch --contains $LAST_SHA 84 | 85 | git checkout master 86 | git merge -m "accumulated commit merge" ready/bue-dev --no-ff 87 | 88 | 89 | 90 | cd $BDIR 91 | 92 | git init mytest4 93 | cd mytest4 94 | date +%N> date.log 95 | git add date.log 96 | git commit -m "date log 1" 97 | git checkout -b feature/team-dev 98 | date +%N>> date.log 99 | git add date.log 100 | git commit -m "date log 2 lines" 101 | date +%N>> date.log 102 | git add date.log 103 | git commit -m "date log 3 lines" 104 | git checkout -b ready/bue-dev 105 | git log 106 | LAST_SHA=`git rev-parse HEAD` 107 | git branch --contains $LAST_SHA 108 | git checkout feature/team-dev 109 | git branch --contains $LAST_SHA 110 | git checkout master 111 | git branch --contains $LAST_SHA 112 | 113 | git checkout master 114 | git merge -m "accumulated commit merge" ready/bue-dev --no-ff 115 | -------------------------------------------------------------------------------- /git-work-flows-scripts/multiple-branch-heads.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #If two branch heads points to same commit, the build data from git have two branches for the same commit. 4 | # 5 | #The "wrong" branch may be integrated and deleted. 6 | # 7 | #Prested uses the first branch given from the git plugin, which seems to be the last branch name added for the commit. 8 | # 9 | # 10 | #The following workflow shows it a given repository, and a jenkins job configured to use pretested integration with branch specifier "origin/ready/**" and destination "master". 11 | # 12 | # 13 | #git checkout master 14 | #git fetch --prune 15 | # 16 | #git checkout -b my-dev 17 | #echo "text" > text.text 18 | #git add text.text 19 | #git commit -m "A test file" 20 | # 21 | #git checkout master 22 | #git push origin my-dev:ready/my-dev 23 | #git push origin my-dev:ready/alpha-dev 24 | # 25 | #--- 26 | # 27 | #The above will integrate and delete alpha-dev, and vice verse if the last to push were in reverse order. 28 | # 29 | #Both branches respect the branch specifier, so both need to be integrated, so we need to make a decision which one is the correct branch? 30 | #Further - what to do with the other branch? 31 | # 32 | #https://trello.com/c/MFzaEMDz 33 | 34 | RB=" 35 | alpha-dev 36 | ready/alpha-dev 37 | ready/my-dev 38 | team-dev 39 | " 40 | NO="6" 41 | OLD="5" 42 | 43 | echo "**********" 44 | git fetch --prune 45 | git checkout master 46 | git pull origin master 47 | echo "**********" 48 | 49 | git branch -a 50 | 51 | git branch -D my-dev 52 | echo "**********" 53 | 54 | for b in $RB 55 | do 56 | git push origin :$b-$NO 57 | git push origin :$b-$OLD 58 | done 59 | 60 | echo "**********" 61 | 62 | git checkout -b my-dev-$NO 63 | 64 | echo "NANO SECS COMMIT" >> text.txt 65 | date +%N >> text.text 66 | git add text.txt 67 | git commit -m "NANO SECS COMMIT" 68 | git branch -a 69 | echo "**********" 70 | 71 | LAST_SHA=`git rev-parse HEAD` 72 | 73 | echo "contain commit" 74 | git branch --contains $LAST_SHA 75 | git branch --contains $LAST_SHA 76 | 77 | echo "**********" 78 | 79 | git checkout master 80 | 81 | git push origin my-dev-$NO:alpha-dev-$NO 82 | git push origin my-dev-$NO:ready/my-dev-$NO 83 | git push origin my-dev-$NO:ready/alpha-dev-$NO 84 | git push origin my-dev-$NO:team-dev-$NO 85 | 86 | echo "**********" 87 | 88 | -------------------------------------------------------------------------------- /git-work-flows-scripts/readme.md: -------------------------------------------------------------------------------- 1 | These script just explain some the work flows we have investigated, or tried. 2 | 3 | Some correct, some shows what not to do. 4 | -------------------------------------------------------------------------------- /git-work-flows-scripts/steps-corret-work-flow-accummulated.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | BDIR=`pwd` 4 | 5 | echo "*******************************************************************************" 6 | echo "* Cleaning up, by removing dirs from last run " 7 | echo "*******************************************************************************" 8 | set -x 9 | rm -rf repo.git repo adams-repo jenkins-repo 10 | set +x 11 | 12 | echo "*******************************************************************************" 13 | echo "* Creating repo, and doing initial commit on master branch" 14 | echo "*******************************************************************************" 15 | set -x 16 | git init --bare repo.git 17 | git clone repo.git 18 | cd repo 19 | echo "# Readme" > readme.md 20 | git add readme.md && git commit -m "Initial commit - readme file" 21 | git push origin master 22 | set +x 23 | 24 | echo "*******************************************************************************" 25 | echo "* Adams first workflow:" 26 | echo " 1. cloning repo" 27 | echo " 2. creating branch adam" 28 | echo " 3. adding lines to file" 29 | echo " 4. pushing to ready/adam branch" 30 | echo "*******************************************************************************" 31 | 32 | set -x 33 | cd $BDIR 34 | git clone repo.git adams-repo 35 | cd adams-repo/ 36 | 37 | git checkout -b adam 38 | echo "" >> readme.md 39 | echo "This is Adam's line" >> readme.md 40 | git add readme.md && git commit -m "My first line added to readme file" 41 | git push origin adam:ready/adam 42 | set +x 43 | 44 | 45 | echo "*******************************************************************************" 46 | echo "* Jenkins Pretested Integration workflow" 47 | echo "*******************************************************************************" 48 | 49 | set -x 50 | cd $BDIR 51 | rm -rf jenkins-repo/ 52 | git clone repo.git jenkins-repo 53 | cd jenkins-repo/ 54 | git checkout master 55 | git pull origin master 56 | git merge --squash origin/ready/adam 57 | git commit -m "Integrated origin/ready/adam" 58 | git push origin master 59 | git push origin :ready/adam 60 | set +x 61 | 62 | # ... that worked, next time it will fail: 63 | 64 | 65 | echo "*******************************************************************************" 66 | echo "* Adams second workflow:" 67 | echo " ... re-using repo and branch, requires some work" 68 | echo "*******************************************************************************" 69 | 70 | set -x 71 | cd $BDIR 72 | cd adams-repo 73 | git fetch --prune 74 | git checkout master 75 | git merge origin/master 76 | 77 | git checkout adam 78 | git merge master --no-edit 79 | 80 | echo "# Readmy" > readme.md 81 | echo "" >> readme.md 82 | echo "This is Eve's line" >> readme.md 83 | git add readme.md && git commit -m "Another commit, changed lines" 84 | git push origin adam:ready/adam 85 | set +x 86 | 87 | 88 | echo "*******************************************************************************" 89 | echo "* Jenkins Pretested Integration workflow" 90 | echo "*******************************************************************************" 91 | 92 | set -x 93 | cd $BDIR 94 | rm -rf jenkins-repo/ 95 | git clone repo.git jenkins-repo 96 | cd jenkins-repo/ 97 | git checkout master 98 | git pull origin master 99 | git pull origin master 100 | git merge origin/ready/adam --no-ff --no-edit 101 | #git commit -m "Integrated origin/ready/adam" 102 | #git push origin master 103 | #git push origin :ready/adam 104 | set +x 105 | 106 | 107 | 108 | # FAIL 109 | -------------------------------------------------------------------------------- /git-work-flows-scripts/steps-corret-work-flow-squash.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | BDIR=`pwd` 4 | 5 | echo "*******************************************************************************" 6 | echo "* Cleaning up, by removing dirs from last run " 7 | echo "*******************************************************************************" 8 | set -x 9 | rm -rf repo.git repo adams-repo jenkins-repo 10 | set +x 11 | 12 | echo "*******************************************************************************" 13 | echo "* Creating repo, and doing initial commit on master branch" 14 | echo "*******************************************************************************" 15 | set -x 16 | git init --bare repo.git 17 | git clone repo.git 18 | cd repo 19 | echo "# Readme" > readme.md 20 | git add readme.md && git commit -m "Initial commit - readme file" 21 | git push origin master 22 | set +x 23 | 24 | echo "*******************************************************************************" 25 | echo "* Adams first workflow:" 26 | echo " 1. cloning repo" 27 | echo " 2. creating branch adam" 28 | echo " 3. adding lines to file" 29 | echo " 4. pushing to ready/adam branch" 30 | echo "*******************************************************************************" 31 | 32 | set -x 33 | cd $BDIR 34 | git clone repo.git adams-repo 35 | cd adams-repo/ 36 | 37 | git checkout -b adam 38 | echo "" >> readme.md 39 | echo "This is Adam's line" >> readme.md 40 | git add readme.md && git commit -m "My first line added to readme file" 41 | git push origin adam:ready/adam 42 | set +x 43 | 44 | 45 | echo "*******************************************************************************" 46 | echo "* Jenkins Pretested Integration workflow" 47 | echo "*******************************************************************************" 48 | 49 | set -x 50 | cd $BDIR 51 | rm -rf jenkins-repo/ 52 | git clone repo.git jenkins-repo 53 | cd jenkins-repo/ 54 | git checkout master 55 | git pull origin master 56 | git merge --squash origin/ready/adam 57 | git commit -m "Integrated origin/ready/adam" 58 | git push origin master 59 | git push origin :ready/adam 60 | set +x 61 | 62 | # ... that worked, next time it will fail: 63 | 64 | 65 | echo "*******************************************************************************" 66 | echo "* Adams second workflow:" 67 | echo " ... re-using repo and branch, requires some work" 68 | echo "*******************************************************************************" 69 | 70 | set -x 71 | cd $BDIR 72 | cd adams-repo 73 | git fetch --prune 74 | git checkout master 75 | git merge origin/master 76 | 77 | git checkout adam 78 | git merge master --no-edit 79 | 80 | echo "# Readmy" > readme.md 81 | echo "" >> readme.md 82 | echo "This is Eve's line" >> readme.md 83 | git add readme.md && git commit -m "Another commit, changed lines" 84 | git push origin adam:ready/adam 85 | set +x 86 | 87 | 88 | echo "*******************************************************************************" 89 | echo "* Jenkins Pretested Integration workflow" 90 | echo "*******************************************************************************" 91 | 92 | set -x 93 | cd $BDIR 94 | rm -rf jenkins-repo/ 95 | git clone repo.git jenkins-repo 96 | cd jenkins-repo/ 97 | git checkout master 98 | git pull origin master 99 | git merge --squash origin/ready/adam 100 | #git commit -m "Integrated origin/ready/adam" 101 | #git push origin master 102 | #git push origin :ready/adam 103 | set +x 104 | 105 | 106 | 107 | # FAIL 108 | -------------------------------------------------------------------------------- /git-work-flows-scripts/steps-fail-accummulated.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | BDIR=`pwd` 4 | 5 | echo "*******************************************************************************" 6 | echo "* Cleaning up, by removing dirs from last run " 7 | echo "*******************************************************************************" 8 | set -x 9 | rm -rf repo.git repo adams-repo jenkins-repo 10 | set +x 11 | 12 | echo "*******************************************************************************" 13 | echo "* Creating repo, and doing initial commit on master branch" 14 | echo "*******************************************************************************" 15 | set -x 16 | git init --bare repo.git 17 | git clone repo.git 18 | cd repo 19 | echo "# Readme" > readme.md 20 | git add readme.md && git commit -m "Initial commit - readme file" 21 | git push origin master 22 | set +x 23 | 24 | echo "*******************************************************************************" 25 | echo "* Adams first workflow:" 26 | echo " 1. cloning repo" 27 | echo " 2. creating branch adam" 28 | echo " 3. adding lines to file" 29 | echo " 4. pushing to ready/adam branch" 30 | echo "*******************************************************************************" 31 | 32 | set -x 33 | cd $BDIR 34 | git clone repo.git adams-repo 35 | cd adams-repo/ 36 | 37 | git checkout -b adam 38 | echo "" >> readme.md 39 | echo "This is Adam's line" >> readme.md 40 | git add readme.md && git commit -m "My first line added to readme file" 41 | git push origin adam:ready/adam 42 | set +x 43 | 44 | 45 | echo "*******************************************************************************" 46 | echo "* Jenkins Pretested Integration workflow" 47 | echo "*******************************************************************************" 48 | 49 | set -x 50 | cd $BDIR 51 | rm -rf jenkins-repo/ 52 | git clone repo.git jenkins-repo 53 | cd jenkins-repo/ 54 | git checkout master 55 | git pull origin master 56 | git merge --squash origin/ready/adam 57 | git commit -m "Integrated origin/ready/adam" 58 | git push origin master 59 | git push origin :ready/adam 60 | set +x 61 | 62 | # ... that worked, next time it will fail: 63 | 64 | 65 | echo "*******************************************************************************" 66 | echo "* Adams second workflow:" 67 | echo " 1. re-using repo and branch, DOES NOT pull first - he is the only one working" 68 | echo " 3. adding lines to file - we know not will merge with last commit" 69 | echo " 4. pushing to ready/adam branch" 70 | echo "*******************************************************************************" 71 | 72 | set -x 73 | cd $BDIR 74 | cd adams-repo 75 | echo "# Readmy" > readme.md 76 | echo "" >> readme.md 77 | echo "This is Eve's line" >> readme.md 78 | git add readme.md && git commit -m "Another commit, changed lines" 79 | git push origin adam:ready/adam 80 | set +x 81 | 82 | 83 | echo "*******************************************************************************" 84 | echo "* Jenkins Pretested Integration workflow" 85 | echo "*******************************************************************************" 86 | 87 | set -x 88 | cd $BDIR 89 | rm -rf jenkins-repo/ 90 | git clone repo.git jenkins-repo 91 | cd jenkins-repo/ 92 | git checkout master 93 | git pull origin master 94 | git merge origin/ready/adam --no-ff 95 | #git commit -m "Integrated origin/ready/adam" 96 | #git push origin master 97 | #git push origin :ready/adam 98 | set +x 99 | 100 | 101 | 102 | # FAIL 103 | -------------------------------------------------------------------------------- /git-work-flows-scripts/steps-fail-squash.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | BDIR=`pwd` 4 | 5 | echo "*******************************************************************************" 6 | echo "* Cleaning up, by removing dirs from last run " 7 | echo "*******************************************************************************" 8 | set -x 9 | rm -rf repo.git repo adams-repo jenkins-repo 10 | set +x 11 | 12 | echo "*******************************************************************************" 13 | echo "* Creating repo, and doing initial commit on master branch" 14 | echo "*******************************************************************************" 15 | set -x 16 | git init --bare repo.git 17 | git clone repo.git 18 | cd repo 19 | echo "# Readme" > readme.md 20 | git add readme.md && git commit -m "Initial commit - readme file" 21 | git push origin master 22 | set +x 23 | 24 | echo "*******************************************************************************" 25 | echo "* Adams first workflow:" 26 | echo " 1. cloning repo" 27 | echo " 2. creating branch adam" 28 | echo " 3. adding lines to file" 29 | echo " 4. pushing to ready/adam branch" 30 | echo "*******************************************************************************" 31 | 32 | set -x 33 | cd $BDIR 34 | git clone repo.git adams-repo 35 | cd adams-repo/ 36 | 37 | git checkout -b adam 38 | echo "" >> readme.md 39 | echo "This is Adam's line" >> readme.md 40 | git add readme.md && git commit -m "My first line added to readme file" 41 | git push origin adam:ready/adam 42 | set +x 43 | 44 | 45 | echo "*******************************************************************************" 46 | echo "* Jenkins Pretested Integration workflow" 47 | echo "*******************************************************************************" 48 | 49 | set -x 50 | cd $BDIR 51 | rm -rf jenkins-repo/ 52 | git clone repo.git jenkins-repo 53 | cd jenkins-repo/ 54 | git checkout master 55 | git pull origin master 56 | git merge --squash origin/ready/adam 57 | git commit -m "Integrated origin/ready/adam" 58 | git push origin master 59 | git push origin :ready/adam 60 | set +x 61 | 62 | # ... that worked, next time it will fail: 63 | 64 | 65 | echo "*******************************************************************************" 66 | echo "* Adams second workflow:" 67 | echo " 1. re-using repo and branch, DOES NOT pull first - he is the only one working" 68 | echo " 3. adding lines to file - we know not will merge with last commit" 69 | echo " 4. pushing to ready/adam branch" 70 | echo "*******************************************************************************" 71 | 72 | set -x 73 | cd $BDIR 74 | cd adams-repo 75 | echo "# Readmy" > readme.md 76 | echo "" >> readme.md 77 | echo "This is Eve's line" >> readme.md 78 | git add readme.md && git commit -m "Another commit, changed lines" 79 | git push origin adam:ready/adam 80 | set +x 81 | 82 | 83 | echo "*******************************************************************************" 84 | echo "* Jenkins Pretested Integration workflow" 85 | echo "*******************************************************************************" 86 | 87 | set -x 88 | cd $BDIR 89 | rm -rf jenkins-repo/ 90 | git clone repo.git jenkins-repo 91 | cd jenkins-repo/ 92 | git checkout master 93 | git pull origin master 94 | git merge --squash origin/ready/adam 95 | #git commit -m "Integrated origin/ready/adam" 96 | #git push origin master 97 | #git push origin :ready/adam 98 | set +x 99 | 100 | 101 | 102 | # FAIL 103 | -------------------------------------------------------------------------------- /git-work-flows-scripts/steps-merge-flow-squash.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | BDIR=`pwd` 4 | 5 | echo "*******************************************************************************" 6 | echo "* Cleaning up, by removing dirs from last run " 7 | echo "*******************************************************************************" 8 | set -x 9 | rm -rf repo.git repo adams-repo jenkins-repo 10 | set +x 11 | 12 | echo "*******************************************************************************" 13 | echo "* Creating repo, and doing initial commit on master branch" 14 | echo "*******************************************************************************" 15 | set -x 16 | git init --bare repo.git 17 | git clone repo.git 18 | cd repo 19 | echo "# Readme" > readme.md 20 | git add readme.md && git commit -m "Initial commit - readme file" 21 | git push origin master 22 | set +x 23 | 24 | echo "*******************************************************************************" 25 | echo "* Adams first workflow:" 26 | echo " 1. cloning repo" 27 | echo " 2. creating branch adam" 28 | echo " 3. adding lines to file" 29 | echo " 4. pushing to ready/adam branch" 30 | echo "*******************************************************************************" 31 | 32 | set -x 33 | cd $BDIR 34 | git clone repo.git adams-repo 35 | cd adams-repo/ 36 | 37 | git checkout -b adam 38 | echo "" >> readme.md 39 | echo "This is Adam's line" >> readme.md 40 | git add readme.md && git commit -m "My first line added to readme file" 41 | git push origin adam:ready/adam 42 | set +x 43 | 44 | 45 | echo "*******************************************************************************" 46 | echo "* Jenkins Pretested Integration workflow" 47 | echo "*******************************************************************************" 48 | 49 | set -x 50 | cd $BDIR 51 | rm -rf jenkins-repo/ 52 | git clone repo.git jenkins-repo 53 | cd jenkins-repo/ 54 | git checkout master 55 | git pull origin master 56 | git merge --squash origin/ready/adam 57 | git commit -m "Integrated origin/ready/adam" 58 | git push origin master 59 | git push origin :ready/adam 60 | set +x 61 | 62 | # ... that worked, next time it will fail: 63 | 64 | 65 | echo "*******************************************************************************" 66 | echo "* Adams second workflow:" 67 | echo " 1. re-using repo and branch, BUT MERGES IN MASTER before doing changes" 68 | echo " 3. adding lines to file - we know not will merge with last commit" 69 | echo " 4. pushing to ready/adam branch" 70 | echo "*******************************************************************************" 71 | 72 | set -x 73 | cd $BDIR 74 | cd adams-repo 75 | git pull origin master --no-edit 76 | echo "# Readmy" > readme.md 77 | echo "" >> readme.md 78 | echo "This is Eve's line" >> readme.md 79 | git add readme.md && git commit -m "Another commit, changed lines" 80 | git push origin adam:ready/adam 81 | set +x 82 | 83 | 84 | echo "*******************************************************************************" 85 | echo "* Jenkins Pretested Integration workflow" 86 | echo "*******************************************************************************" 87 | 88 | set -x 89 | cd $BDIR 90 | rm -rf jenkins-repo/ 91 | git clone repo.git jenkins-repo 92 | cd jenkins-repo/ 93 | git checkout master 94 | git pull origin master 95 | git merge --squash origin/ready/adam 96 | #git commit -m "Integrated origin/ready/adam" 97 | #git push origin master 98 | #git push origin :ready/adam 99 | #set +x 100 | 101 | 102 | 103 | # FAIL 104 | -------------------------------------------------------------------------------- /git-work-flows-scripts/steps-normal-merge.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | BDIR=`pwd` 4 | 5 | echo "*******************************************************************************" 6 | echo "* Cleaning up, by removing dirs from last run " 7 | echo "*******************************************************************************" 8 | set -x 9 | rm -rf repo.git repo adams-repo jenkins-repo 10 | set +x 11 | 12 | echo "*******************************************************************************" 13 | echo "* Creating repo, and doing initial commit on master branch" 14 | echo "*******************************************************************************" 15 | set -x 16 | git init --bare repo.git 17 | git clone repo.git 18 | cd repo 19 | echo "# Readme" > readme.md 20 | git add readme.md && git commit -m "Initial commit - readme file" 21 | git push origin master 22 | set +x 23 | 24 | echo "*******************************************************************************" 25 | echo "* Adams first workflow:" 26 | echo " 1. cloning repo" 27 | echo " 2. creating branch adam" 28 | echo " 3. adding lines to file" 29 | echo " 4. pushing to ready/adam branch" 30 | echo "*******************************************************************************" 31 | 32 | set -x 33 | cd $BDIR 34 | git clone repo.git adams-repo 35 | cd adams-repo/ 36 | 37 | git checkout -b adam 38 | echo "" >> readme.md 39 | echo "This is Adam's line" >> readme.md 40 | git add readme.md && git commit -m "My first line added to readme file" 41 | git push origin adam:ready/adam 42 | set +x 43 | 44 | 45 | echo "*******************************************************************************" 46 | echo "* A normal merge workflow" 47 | echo "*******************************************************************************" 48 | 49 | set -x 50 | cd $BDIR 51 | rm -rf jenkins-repo/ 52 | git clone repo.git jenkins-repo 53 | cd jenkins-repo/ 54 | git checkout master 55 | git pull origin master 56 | git merge origin/ready/adam --no-edit 57 | git push origin master 58 | git push origin :ready/adam 59 | set +x 60 | 61 | # ... that worked, next time it will fail: 62 | 63 | 64 | echo "*******************************************************************************" 65 | echo "* Adams second workflow:" 66 | echo " 1. re-using repo and branch, DOES NOT pull first - he is the only one working" 67 | echo " 3. adding lines to file - we know not will merge with last commit" 68 | echo " 4. pushing to ready/adam branch" 69 | echo "*******************************************************************************" 70 | 71 | set -x 72 | cd $BDIR 73 | cd adams-repo 74 | echo "# Readmy" > readme.md 75 | echo "" >> readme.md 76 | echo "This is Eve's line" >> readme.md 77 | git add readme.md && git commit -m "Another commit, changed lines" 78 | git push origin adam:ready/adam 79 | set +x 80 | 81 | 82 | echo "*******************************************************************************" 83 | echo "* A normal merge workflow" 84 | echo "*******************************************************************************" 85 | 86 | set -x 87 | cd $BDIR 88 | rm -rf jenkins-repo/ 89 | git clone repo.git jenkins-repo 90 | cd jenkins-repo/ 91 | git checkout master 92 | git pull origin master 93 | git merge origin/ready/adam --no-edit 94 | #git commit -m "Integrated origin/ready/adam" 95 | #git push origin master 96 | #git push origin :ready/adam 97 | set +x 98 | 99 | 100 | 101 | # FAIL 102 | -------------------------------------------------------------------------------- /jenkins-pipeline/Jenkinsfile: -------------------------------------------------------------------------------- 1 | properties([parameters([booleanParam(defaultValue: false, description: '', name: 'isRelease')])]) 2 | 3 | node("dockerhost1") { 4 | 5 | stage("checkout") { 6 | checkout scm 7 | } 8 | 9 | stage("build") { 10 | buildMaven() 11 | archiveArtifacts 'target/*.hpi' 12 | } 13 | 14 | stage("changelog") { 15 | pac() 16 | } 17 | 18 | stage("release") { 19 | if(!params?.isRelease) { 20 | echo "Release build is not enabled" 21 | } else { 22 | echo "Release build enabled. Running release." 23 | releaseMaven() 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /jenkins-pipeline/pipeline.groovy: -------------------------------------------------------------------------------- 1 | multibranchPipelineJob("Pretested Integration Jenkins Plugin") { 2 | 3 | factory { 4 | workflowBranchProjectFactory { 5 | scriptPath('jenkins-pipeline/Jenkinsfile') 6 | } 7 | } 8 | 9 | branchSources { 10 | git { 11 | credentialsId("github") 12 | remote("https://github.com/Praqma/pretested-integration-plugin.git") 13 | } 14 | } 15 | 16 | configure { 17 | def traitBlock = it / 'sources' / 'data' / 'jenkins.branch.BranchSource' / 'source' / 'traits' 18 | traitBlock << 'jenkins.plugins.git.traits.CloneOptionTrait' { 19 | extension(class: 'hudson.plugins.git.extensions.impl.CloneOption') { 20 | shallow(false) 21 | noTag(false) 22 | reference() 23 | depth(0) 24 | honorRefspec(false) 25 | } 26 | } 27 | 28 | traitBlock << 'jenkins.plugins.git.traits.BranchDiscoveryTrait' { } 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /settings.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | praqma 8 | mavenrelease 9 | 10 | 11 | 12 | maven.jenkins-ci.org 13 | praqma 14 | ${env.PWFORPRAQMAMVNUSER} 15 | 16 | 17 | 18 | 19 | 20 | 21 | jenkins 22 | 23 | true 24 | 25 | 26 | 27 | repo.jenkins-ci.org 28 | https://repo.jenkins-ci.org/public/ 29 | 30 | 31 | 32 | 33 | repo.jenkins-ci.org 34 | https://repo.jenkins-ci.org/public/ 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/pretestedintegration/AbstractSCMBridge.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration; 2 | 3 | import hudson.DescriptorExtensionList; 4 | import hudson.EnvVars; 5 | import hudson.ExtensionPoint; 6 | import hudson.Launcher; 7 | import hudson.model.*; 8 | import jenkins.model.Jenkins; 9 | import org.jenkinsci.plugins.pretestedintegration.exceptions.IntegrationFailedException; 10 | import org.jenkinsci.plugins.pretestedintegration.exceptions.IntegrationUnknownFailureException; 11 | import org.jenkinsci.plugins.pretestedintegration.exceptions.NothingToDoException; 12 | import org.jenkinsci.plugins.pretestedintegration.exceptions.UnsupportedConfigurationException; 13 | 14 | import java.io.IOException; 15 | import java.util.ArrayList; 16 | import java.util.List; 17 | import java.util.logging.Logger; 18 | 19 | /** 20 | * Abstract class representing an SCM bridge. 21 | */ 22 | public abstract class AbstractSCMBridge implements Describable, ExtensionPoint { 23 | private static final Logger LOGGER = Logger.getLogger(AbstractSCMBridge.class.getName()); 24 | 25 | 26 | /** 27 | * Information about the result of the integration (Unknown, Conflict, Build, Push). 28 | * @return the integration branch name 29 | */ 30 | protected abstract String getIntegrationBranch(); 31 | 32 | /** 33 | * The integration strategy. 34 | * This is the strategy applied to merge pretested commits into the integration integrationBranch. 35 | */ 36 | public final IntegrationStrategy integrationStrategy; 37 | 38 | protected final static String LOG_PREFIX = "[PREINT] "; 39 | 40 | /** 41 | * Constructor for the SCM bridge. 42 | * 43 | * @param integrationStrategy The integration strategy to apply when merging commits. 44 | */ 45 | public AbstractSCMBridge(IntegrationStrategy integrationStrategy ) { 46 | this.integrationStrategy = integrationStrategy; 47 | } 48 | 49 | /** 50 | * Validates the configuration of the Jenkins Job. 51 | * Throws an exception when the configuration is invalid. 52 | * 53 | * @param project The Project 54 | * @throws UnsupportedConfigurationException Mismatch in job configuration 55 | */ 56 | public void validateConfiguration(AbstractProject project) throws UnsupportedConfigurationException { 57 | } 58 | 59 | /** 60 | * @return all the SCM Bridge Descriptors 61 | */ 62 | public static DescriptorExtensionList> all() { 63 | return Jenkins.getInstance().>getDescriptorList(AbstractSCMBridge.class); 64 | } 65 | 66 | /** 67 | * @return all the Integration Strategy Descriptors 68 | */ 69 | public static List> getBehaviours() { 70 | List> behaviours = new ArrayList<>(); 71 | for (IntegrationStrategyDescriptor behaviour : IntegrationStrategy.all()) { 72 | behaviours.add(behaviour); 73 | } 74 | return behaviours; 75 | } 76 | 77 | /** 78 | * {@inheritDoc} 79 | */ 80 | @Override 81 | public Descriptor getDescriptor() { 82 | return (SCMBridgeDescriptor) Jenkins.getInstance().getDescriptorOrDie(getClass()); 83 | } 84 | 85 | /** 86 | * @return all the SCM Bridge Descriptors 87 | */ 88 | public static List> getDescriptors() { 89 | List> descriptors = new ArrayList<>(); 90 | for (SCMBridgeDescriptor descriptor : all()) { 91 | descriptors.add(descriptor); 92 | } 93 | return descriptors; 94 | } 95 | 96 | /** 97 | * @param environment environment 98 | * @return The Integration Branch name as variable expanded if possible - otherwise return integrationBranch 99 | */ 100 | public String getExpandedIntegrationBranch(EnvVars environment) { 101 | return environment.expand(getIntegrationBranch()); 102 | } 103 | 104 | /*** 105 | * @return The required result 106 | */ 107 | public static Result getRequiredResult() { 108 | return Result.SUCCESS; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/pretestedintegration/IntegrationStrategy.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration; 2 | 3 | import hudson.DescriptorExtensionList; 4 | import hudson.ExtensionPoint; 5 | import hudson.Launcher; 6 | import hudson.model.*; 7 | import jenkins.model.Jenkins; 8 | import org.jenkinsci.plugins.pretestedintegration.exceptions.*; 9 | 10 | /** 11 | * Abstract class representing a strategy to apply when merging pretested commits into the integration integrationBranch. 12 | */ 13 | public abstract class IntegrationStrategy implements Describable, ExtensionPoint { 14 | 15 | /** 16 | * {@inheritDoc} 17 | */ 18 | @Override 19 | public Descriptor getDescriptor() { 20 | return (IntegrationStrategyDescriptor) Jenkins.getInstance().getDescriptorOrDie(getClass()); 21 | } 22 | 23 | /** 24 | * @return All Integration Strategy descriptors 25 | */ 26 | public static DescriptorExtensionList> all() { 27 | return Jenkins.getInstance().>getDescriptorList(IntegrationStrategy.class); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/pretestedintegration/IntegrationStrategyDescriptor.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration; 2 | 3 | import hudson.model.Descriptor; 4 | import net.sf.json.JSONObject; 5 | import org.kohsuke.stapler.StaplerRequest; 6 | 7 | /** 8 | * Abstract class representing a Descriptor of an Integration Strategy 9 | * 10 | * @param The Integration Strategy of this Descriptor 11 | */ 12 | public abstract class IntegrationStrategyDescriptor extends Descriptor { 13 | 14 | /** 15 | * @param bridge The SCM Bridge 16 | * @return Whether or not the Strategy is applicable 17 | */ 18 | public abstract boolean isApplicable(Class bridge); 19 | 20 | /** 21 | * {@inheritDoc} 22 | */ 23 | 24 | 25 | @Override 26 | public IntegrationStrategy newInstance(StaplerRequest staplerRequest, JSONObject formData) throws FormException { 27 | if (staplerRequest != null) { 28 | return staplerRequest.bindJSON(IntegrationStrategy.class, formData); 29 | } 30 | return null; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/pretestedintegration/PretestedIntegrationJobDslExtension.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration; 2 | 3 | import hudson.Extension; 4 | import javaposse.jobdsl.dsl.RequiresPlugin; 5 | import javaposse.jobdsl.dsl.helpers.publisher.PublisherContext; 6 | import javaposse.jobdsl.dsl.helpers.scm.GitExtensionContext; 7 | import javaposse.jobdsl.dsl.helpers.wrapper.WrapperContext; 8 | import javaposse.jobdsl.plugin.ContextExtensionPoint; 9 | import javaposse.jobdsl.plugin.DslExtensionMethod; 10 | import org.jenkinsci.plugins.pretestedintegration.scm.git.AccumulatedCommitStrategy; 11 | import org.jenkinsci.plugins.pretestedintegration.scm.git.GitBridge; 12 | import org.jenkinsci.plugins.pretestedintegration.scm.git.PretestedIntegrationAsGitPluginExt; 13 | import org.jenkinsci.plugins.pretestedintegration.scm.git.SquashCommitStrategy; 14 | 15 | import java.util.Arrays; 16 | import java.util.List; 17 | 18 | import static javaposse.jobdsl.dsl.Preconditions.checkArgument; 19 | 20 | /** 21 | *ExtensionPoint used to support the Jenkins Job DSL 22 | * 23 | *Example: 24 | *job("generated") { 25 | * scm { 26 | * git { 27 | * remote { 28 | * name("origin") 29 | * url("some.repo.somewhere.git") 30 | * } 31 | * extensions { 32 | * pretestedIntegration("ACCUMULATED","master","origin") 33 | * } 34 | * } 35 | * } 36 | *} 37 | */ 38 | @Extension(optional = true) 39 | public class PretestedIntegrationJobDslExtension extends ContextExtensionPoint { 40 | 41 | /** 42 | * Valid options for integrationStrategy 43 | */ 44 | private final List strategies = Arrays.asList("ACCUMULATED", "SQUASHED"); 45 | 46 | /** 47 | * Method to configure the Pretested Integration wrapper. 48 | * 49 | * @param strategy the Integration Strategy to use 50 | * @param branch the Integration Branch 51 | * @param repository the repository 52 | * @return a configured PretestedIntegrationBuildWrapper 53 | */ 54 | @RequiresPlugin(id = "pretested-integration", minimumVersion = "3.0.0") 55 | @DslExtensionMethod(context = GitExtensionContext.class) 56 | public Object pretestedIntegration(String strategy, String branch, String repository) { 57 | checkArgument(strategies.contains(strategy), "Strategy must be one of " + strategies); 58 | IntegrationStrategy integrationStrategy = null; 59 | switch (strategy) { 60 | case "ACCUMULATED": 61 | integrationStrategy = new AccumulatedCommitStrategy(); 62 | break; 63 | case "SQUASHED": 64 | integrationStrategy = new SquashCommitStrategy(); 65 | break; 66 | default: 67 | integrationStrategy = new SquashCommitStrategy(); 68 | } 69 | return new PretestedIntegrationAsGitPluginExt(integrationStrategy, branch, repository); 70 | } 71 | 72 | /** 73 | * Method to configure the Pretested Integration publisher 74 | * 75 | * @return a configured PretestedIntegrationPostCheckout 76 | */ 77 | @RequiresPlugin(id = "pretested-integration", minimumVersion = "3.0.0") 78 | @DslExtensionMethod(context = PublisherContext.class) 79 | public Object pretestedIntegration() { 80 | return new PretestedIntegrationPostCheckout(); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/pretestedintegration/SCMBridgeDescriptor.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration; 2 | 3 | import hudson.model.Descriptor.FormException; 4 | import hudson.model.Descriptor; 5 | import net.sf.json.JSONObject; 6 | import org.kohsuke.stapler.StaplerRequest; 7 | 8 | /** 9 | * Descriptor for SCM Bridges 10 | * @param Type of the SCM Bridge. Extends AbstractSCMBridge 11 | */ 12 | public abstract class SCMBridgeDescriptor extends Descriptor { 13 | 14 | /** 15 | * {@inheritDoc} 16 | */ 17 | @Override 18 | public AbstractSCMBridge newInstance(StaplerRequest req, JSONObject formData) throws FormException { 19 | return super.newInstance(req, formData); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/pretestedintegration/exceptions/BranchDeletionFailedException.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.exceptions; 2 | 3 | import java.io.IOException; 4 | 5 | /** 6 | * Used when deleting a branch failed unexpectedly. 7 | */ 8 | public class BranchDeletionFailedException extends IOException { 9 | 10 | /** 11 | * Constructor for BranchDeletionFailedException 12 | */ 13 | public BranchDeletionFailedException() { 14 | super("Failed to delete branch."); 15 | } 16 | 17 | /** 18 | * Constructor for BranchDeletionFailedException 19 | * @param message The Exception message 20 | */ 21 | public BranchDeletionFailedException(String message) { 22 | super(message); 23 | } 24 | 25 | /** 26 | * Constructor for BranchDeletionFailedException 27 | * @param message The Exception message 28 | * @param cause The causal exception 29 | */ 30 | public BranchDeletionFailedException(String message, Exception cause) { 31 | super(message, cause); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/pretestedintegration/exceptions/CommitFailedException.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.exceptions; 2 | 3 | import java.io.IOException; 4 | 5 | /** 6 | * Used when applying commits failed unexpectedly. 7 | */ 8 | public class CommitFailedException extends IOException { 9 | 10 | /** 11 | * Constructor for CommitFailedException 12 | * @param message The Exception message. 13 | */ 14 | public CommitFailedException(String message) { 15 | super(message); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/pretestedintegration/exceptions/EstablishingWorkspaceFailedException.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.exceptions; 2 | 3 | import java.io.IOException; 4 | 5 | /** 6 | * Used when the establishment of the workspace failed unexpectedly. 7 | */ 8 | public class EstablishingWorkspaceFailedException extends IOException { 9 | 10 | /** 11 | * Constructor for EstablishingWorkspaceFailedException 12 | * @param cause The causal Exception. 13 | */ 14 | public EstablishingWorkspaceFailedException(Exception cause) { 15 | super("Failed to establish workspace. Trace written to log", cause); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/pretestedintegration/exceptions/IntegrationFailedException.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.exceptions; 2 | 3 | import java.io.IOException; 4 | 5 | /** 6 | * Used when integration of the commit fails unexpectedly. 7 | */ 8 | public class IntegrationFailedException extends IOException { 9 | 10 | /** 11 | * Constructor for IntegrationFailedException 12 | */ 13 | public IntegrationFailedException() { 14 | super("Merge failure"); 15 | } 16 | 17 | /** 18 | * Constructor for IntegrationFailedException 19 | * @param cause The causal exception 20 | */ 21 | public IntegrationFailedException(Exception cause) { 22 | super("Merge failure", cause); 23 | } 24 | 25 | /** 26 | * Constructor for IntegrationFailedException 27 | * @param message The Exception message 28 | */ 29 | public IntegrationFailedException(String message) { 30 | super(message); 31 | } 32 | 33 | /** 34 | * Constructor for IntegrationFailedException 35 | * @param message The Exception message 36 | * @param cause The causal exception 37 | */ 38 | public IntegrationFailedException(String message, Exception cause) { 39 | super(message, cause); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/pretestedintegration/exceptions/IntegrationUnknownFailureException.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.exceptions; 2 | 3 | import java.io.IOException; 4 | 5 | /** 6 | * Used when integration of the commit fails unexpectedly. 7 | */ 8 | public class IntegrationUnknownFailureException extends IOException { 9 | 10 | /** 11 | * Constructor for IntegrationFailedException 12 | */ 13 | public IntegrationUnknownFailureException() { 14 | super("Unknown root cause"); 15 | } 16 | 17 | /** 18 | * Constructor for IntegrationFailedException 19 | * @param cause The causal exception 20 | */ 21 | public IntegrationUnknownFailureException(Exception cause) { 22 | super("Unknown root cause", cause); 23 | } 24 | 25 | /** 26 | * Constructor for IntegrationFailedException 27 | * @param message The Exception message 28 | */ 29 | public IntegrationUnknownFailureException(String message) { 30 | super(message); 31 | } 32 | 33 | /** 34 | * Constructor for IntegrationFailedException 35 | * @param message The Exception message 36 | * @param cause The causal exception 37 | */ 38 | public IntegrationUnknownFailureException(String message, Exception cause) { 39 | super(message, cause); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/pretestedintegration/exceptions/NothingToDoException.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.exceptions; 2 | 3 | import java.io.IOException; 4 | 5 | /** 6 | * Used when there is nothing to do. 7 | */ 8 | public class NothingToDoException extends IOException { 9 | 10 | /** 11 | * Constructor for NothingToDoException 12 | */ 13 | public NothingToDoException() { 14 | super("Nothing to do."); 15 | } 16 | 17 | /** 18 | * Constructor for NothingToDoException 19 | * @param message the Exception message 20 | */ 21 | public NothingToDoException(String message) { 22 | super("Nothing to do. The reason is: " + message); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/pretestedintegration/exceptions/PushFailedException.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.exceptions; 2 | 3 | import java.io.IOException; 4 | 5 | /** 6 | * Used when applying commits failed unexpectedly. 7 | */ 8 | public class PushFailedException extends IOException { 9 | 10 | /** 11 | * Constructor for PushFailedException 12 | * @param message The Exception message. 13 | */ 14 | public PushFailedException(String message) { 15 | super(message); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/pretestedintegration/exceptions/UnsupportedConfigurationException.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.exceptions; 2 | 3 | import java.io.IOException; 4 | 5 | /** 6 | * Used when discovering illegal or unsupported configuration. 7 | */ 8 | public class UnsupportedConfigurationException extends IOException { 9 | 10 | /** 11 | * Predefined message. 12 | * Used when there's multiple repositories defined that don't match the Pretested Integration repository. 13 | */ 14 | public static final String ILLEGAL_CONFIG_NO_REPO_NAME_DEFINED = String.format("You have multiple git repositories defined, but none of them match your pretested integration repostiory. When using more than 1 repository, remotes must be explicitly named in the Git configuration"); 15 | 16 | /** 17 | * Predefined message. 18 | * Used when there's multiple repositories defined with similar names. 19 | */ 20 | public static final String AMBIGUITY_IN_REMOTE_NAMES = "You have multiple git repositories defined, and more than one have the same name (or defaults to the same name). Pretested Integration is unable to select the correct one."; 21 | 22 | /** 23 | * Predefined message. 24 | * Used when multiple revisions using the same remote were found. 25 | */ 26 | public static final String AMBIGUITY_IN_BUILD_DATA = "Multiple revisions with same remote detected. Cannot determine which one to use."; 27 | 28 | /** 29 | * Constructor for UnsupportedConfigurationException. 30 | * @param message The Exception message 31 | */ 32 | public UnsupportedConfigurationException(String message) { 33 | super(message); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/pretestedintegration/scm/git/FindCommitAuthorCallback.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.scm.git; 2 | 3 | import hudson.remoting.VirtualChannel; 4 | import java.io.IOException; 5 | import org.eclipse.jgit.lib.ObjectId; 6 | import org.eclipse.jgit.lib.Repository; 7 | import org.eclipse.jgit.revwalk.RevCommit; 8 | import org.eclipse.jgit.revwalk.RevWalk; 9 | 10 | /** 11 | * Callback used to find the author of a Git commit 12 | */ 13 | public class FindCommitAuthorCallback extends RepositoryListenerAwareCallback { 14 | 15 | /** 16 | * The commit Id 17 | */ 18 | public final ObjectId id; 19 | 20 | /** 21 | * Constructor for FindCommitAuthorCallback 22 | * @param id The Commit id of the commit of which to find the author. 23 | */ 24 | public FindCommitAuthorCallback(final ObjectId id) { 25 | this.id = id; 26 | } 27 | 28 | /** 29 | * {@inheritDoc} 30 | */ 31 | @Override 32 | public String invoke(Repository repository, VirtualChannel channel) throws IOException, InterruptedException { 33 | RevWalk walk = new RevWalk(repository); 34 | RevCommit commit = walk.parseCommit(id); 35 | walk.dispose(); 36 | return commit.getAuthorIdent().toExternalString(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/pretestedintegration/scm/git/FindCommitMessageCallback.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.scm.git; 2 | 3 | import hudson.remoting.VirtualChannel; 4 | import java.io.IOException; 5 | import org.eclipse.jgit.lib.ObjectId; 6 | import org.eclipse.jgit.lib.Repository; 7 | import org.eclipse.jgit.revwalk.RevCommit; 8 | import org.eclipse.jgit.revwalk.RevWalk; 9 | 10 | /** 11 | * Callback to find the message of a given Git commit 12 | */ 13 | public class FindCommitMessageCallback extends RepositoryListenerAwareCallback { 14 | 15 | /** 16 | * The commit Id 17 | */ 18 | public final ObjectId id; 19 | 20 | /** 21 | * Constructor for FindCommitMessageCallback 22 | * @param id The Commit id of the commit of which to find the author. 23 | */ 24 | public FindCommitMessageCallback(final ObjectId id) { 25 | this.id = id; 26 | } 27 | 28 | /** 29 | * {@inheritDoc} 30 | */ 31 | @Override 32 | public String invoke(Repository repo, VirtualChannel channel) throws IOException, InterruptedException { 33 | RevWalk walk = new RevWalk(repo); 34 | RevCommit commit = walk.parseCommit(id); 35 | walk.dispose(); 36 | return commit.getFullMessage(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/pretestedintegration/scm/git/GetAllCommitsFromBranchCallback.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.scm.git; 2 | 3 | import hudson.remoting.VirtualChannel; 4 | import java.io.IOException; 5 | import java.text.SimpleDateFormat; 6 | import java.util.Date; 7 | import java.util.Locale; 8 | import java.util.logging.Logger; 9 | import java.util.regex.Pattern; 10 | import org.eclipse.jgit.lib.ObjectId; 11 | import org.eclipse.jgit.lib.Repository; 12 | import org.eclipse.jgit.revwalk.RevCommit; 13 | import org.eclipse.jgit.revwalk.RevWalk; 14 | 15 | /** 16 | * Callback to get a list of all Git commits from a given commit to given integrationBranch 17 | */ 18 | public class GetAllCommitsFromBranchCallback extends RepositoryListenerAwareCallback { 19 | 20 | private static final Logger LOGGER = Logger.getLogger(GetAllCommitsFromBranchCallback.class.getName()); 21 | 22 | /** 23 | * The commit Id. 24 | * Starting point. 25 | */ 26 | public final ObjectId id; 27 | 28 | /** 29 | * The integrationBranch name. 30 | * Destination. 31 | */ 32 | public final String branch; 33 | 34 | /** 35 | * Constructor for GetAllCommitsFromBranchCallback 36 | * @param id The commit Id of the starting point 37 | * @param branch The integrationBranch name of the destination. 38 | */ 39 | public GetAllCommitsFromBranchCallback(final ObjectId id, final String branch) { 40 | this.id = id; 41 | this.branch = branch; 42 | } 43 | 44 | /** 45 | * {@inheritDoc} 46 | */ 47 | @Override 48 | public String invoke(Repository repo, VirtualChannel channel) throws IOException, InterruptedException { 49 | StringBuilder sb = new StringBuilder(); 50 | RevWalk walk = new RevWalk(repo); 51 | 52 | // commit on our integrationBranch, resolved from the jGit object id 53 | RevCommit commit = walk.parseCommit(id); 54 | 55 | // walk tree starting from the integration commit 56 | walk.markStart(commit); 57 | 58 | LOGGER.info(String.format(GitMessages.LOG_PREFIX+ "Collecting commit message until reaching branch %s", branch)); 59 | // limit the tree walk to keep away from master commits 60 | // Reference for this idea is: https://wiki.eclipse.org/JGit/User_Guide#Restrict_the_walked_revision_graph 61 | ObjectId to = repo.resolve(branch); 62 | walk.markUninteresting(walk.parseCommit(to)); 63 | 64 | // build the complete commit message, to look like squash commit msg 65 | // iterating over the commits that will be integrated 66 | for (RevCommit rev : walk) { 67 | 68 | sb.append(String.format("commit %s", rev.getName())); 69 | sb.append(String.format("%n")); 70 | // In the commit message overview, the author is right one to give credit (author wrote the code) 71 | sb.append(String.format("Author: %s <%s>", rev.getAuthorIdent().getName(), rev.getAuthorIdent().getEmailAddress())); 72 | sb.append(String.format("%n")); 73 | 74 | Integer secondsSinceUnixEpoch = rev.getCommitTime(); 75 | // Note that the git log shows different date formats, depending on configuration. 76 | // The choices in the git commit message below matches the squashed commit message 77 | // that git generates on a Ubuntu Linux 14.04 with default git installation. 78 | // Locale if forced to enligsh to make it independent from operating system 79 | // and environment. 80 | // Note that it is not the standard ISO format. 81 | SimpleDateFormat formatter = new SimpleDateFormat("EEE MMM d kk:mm:ss yyyy ZZZZ", Locale.ENGLISH); 82 | Date commitTime = new Date(secondsSinceUnixEpoch * 1000L); // seconds to milis 83 | String asString = formatter.format(commitTime); 84 | sb.append(String.format("Date: %s", asString)); 85 | 86 | sb.append(String.format("%n")); 87 | sb.append(String.format("%n")); 88 | 89 | String newlinechar = System.getProperty("line.separator"); 90 | // Using spaces in git commit message formatting, to avoid inconsistent 91 | // results based on tab with, and to mimic normal recommendations 92 | // on writing commit message (indented bullet lists with space) 93 | // following (same) examples: 94 | // http://chris.beams.io/posts/git-commit/ 95 | // http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html 96 | // 4 spaces are used, as this is how the squashed commit message looks like 97 | Integer numberOfSpaces = 4; 98 | String indentation = String.format("%" + numberOfSpaces + "s", ""); 99 | String fullMessage = rev.getFullMessage(); 100 | Pattern myregexp = Pattern.compile(newlinechar, Pattern.MULTILINE); 101 | 102 | String newstring = myregexp.matcher(fullMessage).replaceAll(newlinechar + indentation); 103 | 104 | sb.append(String.format(indentation + "%s", newstring)); 105 | sb.append(String.format("%n")); 106 | sb.append(String.format("%n")); 107 | } 108 | 109 | walk.dispose(); 110 | 111 | return sb.toString(); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/pretestedintegration/scm/git/GetCommitCountFromBranchCallback.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.scm.git; 2 | 3 | import hudson.remoting.VirtualChannel; 4 | import java.io.IOException; 5 | import java.util.Iterator; 6 | import org.eclipse.jgit.lib.ObjectId; 7 | import org.eclipse.jgit.lib.Repository; 8 | import org.eclipse.jgit.revwalk.RevCommit; 9 | import org.eclipse.jgit.revwalk.RevWalk; 10 | 11 | /** 12 | * Callback used to count the commits between a given Commit and a Branch 13 | */ 14 | public class GetCommitCountFromBranchCallback extends RepositoryListenerAwareCallback { 15 | 16 | /** 17 | * The commit Id of the starting point. 18 | */ 19 | public final ObjectId startObjectId; 20 | 21 | /** 22 | * The integrationBranch name of the destination. 23 | */ 24 | public final String targetBranchName; 25 | 26 | /** 27 | * Constructor for GetCommitCountFromBranchCallback 28 | * @param startObjectId The Id of the starting commit 29 | * @param targetBranchName The name of the destination integrationBranch 30 | */ 31 | public GetCommitCountFromBranchCallback(final ObjectId startObjectId, final String targetBranchName) { 32 | this.startObjectId = startObjectId; 33 | this.targetBranchName = targetBranchName; 34 | } 35 | 36 | /** 37 | * {@inheritDoc} 38 | */ 39 | @Override 40 | public Integer invoke(Repository repository, VirtualChannel channel) throws IOException, InterruptedException { 41 | RevWalk walker = new RevWalk(repository); 42 | RevCommit originCommit = walker.parseCommit(startObjectId); 43 | ObjectId targetId = repository.resolve(targetBranchName); 44 | RevCommit targetCommit = walker.parseCommit(targetId); 45 | 46 | walker.markStart(originCommit); 47 | walker.markUninteresting(targetCommit); 48 | 49 | int commitCount = 0; 50 | Iterator iterator = walker.iterator(); 51 | while (iterator.hasNext()) { 52 | iterator.next(); 53 | commitCount++; 54 | } 55 | walker.dispose(); 56 | 57 | return commitCount; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/pretestedintegration/scm/git/GitMessages.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.scm.git; 2 | 3 | /** 4 | * Hold common git error or user messages, used several times in different 5 | * classes and reusable for testing later. 6 | */ 7 | public class GitMessages { 8 | 9 | public static final String LOG_PREFIX = "[PREINT] "; 10 | 11 | /** 12 | * Message for merge strategies to show when they don't find a match between 13 | * remote branches and relevant SCM change. 14 | * 15 | * @param branchName for the selected branch 16 | * @return message for no relevant changes 17 | */ 18 | public static String noRelevantSCMchange(String branchName) { 19 | return String.format("There is no relevant SCM change to integrate where branch matches the 'Integration repository'. Either branch (%s) is deleted or already integrated, or the SCM change is not related to the integration repository.", branchName); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/pretestedintegration/scm/git/IntegrationStrategyAsGitPluginExt.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.scm.git; 2 | 3 | import hudson.model.*; 4 | import hudson.plugins.git.Branch; 5 | import hudson.plugins.git.GitSCM; 6 | import hudson.plugins.git.Revision; 7 | import org.jenkinsci.plugins.gitclient.GitClient; 8 | import org.jenkinsci.plugins.pretestedintegration.exceptions.IntegrationFailedException; 9 | import org.jenkinsci.plugins.pretestedintegration.exceptions.NothingToDoException; 10 | import org.jenkinsci.plugins.pretestedintegration.exceptions.UnsupportedConfigurationException; 11 | 12 | import java.io.IOException; 13 | 14 | /** 15 | * Abstract class representing a strategy to apply when merging pretested commits into the integration integrationBranch. 16 | */ 17 | public interface IntegrationStrategyAsGitPluginExt{ 18 | 19 | /** 20 | * Integrates the commits into the integration integrationBranch. 21 | * 22 | * @param scm Current GIT scm 23 | * @param build The Build 24 | * @param git current git client 25 | * @param listener The BuildListener 26 | * @param marked marked revision for use in GitExtensions 27 | * @param triggeredBranch the triggered branch 28 | * @param bridge the gitbridge 29 | * @throws IntegrationFailedException The integration failed ala merge 30 | * @throws NothingToDoException The triggered revision is behind the integration 31 | * @throws UnsupportedConfigurationException You have a combination that is not supported, like the type of job 32 | * @throws IOException Unforeseen IO problems 33 | * @throws InterruptedException Unforeseen problems 34 | */ 35 | 36 | void integrate(GitSCM scm, Run build, GitClient git, TaskListener listener, Revision marked, Branch triggeredBranch, GitBridge bridge) 37 | throws IntegrationFailedException, NothingToDoException, UnsupportedConfigurationException, IOException, InterruptedException; 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/pretestedintegration/scm/git/PretestTriggerCommitAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package org.jenkinsci.plugins.pretestedintegration.scm.git; 7 | 8 | import hudson.model.InvisibleAction; 9 | import hudson.plugins.git.Branch; 10 | 11 | /** 12 | * 13 | * @author Mads 14 | */ 15 | public class PretestTriggerCommitAction extends InvisibleAction { 16 | 17 | public final Branch triggerBranch; 18 | public final String integrationBranch; 19 | public final String integrationRepo; 20 | public final String ucCredentialsId; 21 | 22 | public PretestTriggerCommitAction( final Branch triggerBranch, final String integrationBranch, final String integrationRepo, final String ucCredentialsId ) { 23 | this.triggerBranch = triggerBranch; 24 | this.integrationBranch = integrationBranch; 25 | this.integrationRepo = integrationRepo; 26 | this.ucCredentialsId = ucCredentialsId; 27 | 28 | } 29 | 30 | public PretestTriggerCommitAction( final Branch triggerBranch ) { 31 | this.triggerBranch = triggerBranch; 32 | this.integrationBranch = null; 33 | this.integrationRepo = null; 34 | this.ucCredentialsId = null; 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/pretestedintegration/scm/git/PretestedIntegrationSCMTrait.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.scm.git; 2 | 3 | import edu.umd.cs.findbugs.annotations.NonNull; 4 | import hudson.Extension; 5 | import jenkins.plugins.git.traits.GitSCMExtensionTrait; 6 | import jenkins.plugins.git.traits.GitSCMExtensionTraitDescriptor; 7 | import org.jenkinsci.plugins.pretestedintegration.IntegrationStrategy; 8 | import org.kohsuke.stapler.DataBoundConstructor; 9 | 10 | import javax.annotation.Nonnull; 11 | 12 | public class PretestedIntegrationSCMTrait extends GitSCMExtensionTrait { 13 | 14 | @DataBoundConstructor 15 | public PretestedIntegrationSCMTrait(PretestedIntegrationAsGitPluginExt extension) { 16 | super(extension); 17 | } 18 | 19 | @Extension 20 | public static class DescriptorImpl extends GitSCMExtensionTraitDescriptor { 21 | @Nonnull 22 | @Override 23 | public String getDisplayName() { 24 | return "Use pretested integration"; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/pretestedintegration/scm/git/RepositoryListenerAwareCallback.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.scm.git; 2 | 3 | import hudson.remoting.VirtualChannel; 4 | import java.io.IOException; 5 | import org.eclipse.jgit.lib.Repository; 6 | import org.jenkinsci.plugins.gitclient.RepositoryCallback; 7 | 8 | /** 9 | * RepositoryCallback that keeps track of the TaskListener 10 | * @param Return type of the Callback 11 | */ 12 | public abstract class RepositoryListenerAwareCallback implements RepositoryCallback { 13 | 14 | /** 15 | * The TaskListener for use in invoke 16 | */ 17 | // public final TaskListener listener; 18 | 19 | /** 20 | * Constructor for a RepositoryListenerAwareCallback 21 | */ 22 | public RepositoryListenerAwareCallback() {} 23 | 24 | /** 25 | * {@inheritDoc } 26 | */ 27 | @Override 28 | public abstract T invoke(Repository repo, VirtualChannel channel) throws IOException, InterruptedException; 29 | } 30 | -------------------------------------------------------------------------------- /src/main/resources/index.jelly: -------------------------------------------------------------------------------- 1 | 2 | 5 |
6 | The Pretested Integration Plugin offers a branchy approach to pretested integration (also known as pre-tested commits), which upholds the invariant; that for a specific branch, known as the integration branch, all commits have been verified. 7 |
8 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/pretestedintegration/PretestedIntegrationBuildWrapper/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/pretestedintegration/PretestedIntegrationBuildWrapper/global.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/pretestedintegration/PretestedIntegrationBuildWrapper/help-stageRepositoryUrl.html: -------------------------------------------------------------------------------- 1 | Enter the local (or remote) location of the repository to push to 2 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/pretestedintegration/PretestedIntegrationBuildWrapper/index.jelly: -------------------------------------------------------------------------------- 1 | 2 | 5 |
6 | This plugin allows commits to automatically be tested. 7 |
8 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/pretestedintegration/PretestedIntegrationPostCheckout/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/pretestedintegration/scm/git/AccumulatedCommitStrategy/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/pretestedintegration/scm/git/AccumulatedCommitStrategy/help.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

Accumulated Commit Strategy

5 |
This strategy merges your commits with the --no-ff switch
6 | 7 | 8 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/pretestedintegration/scm/git/GitBridge/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/pretestedintegration/scm/git/GitBridge/help-branch.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

What to specify

5 |

The branch name must match your integration branch name. No trailing slash.

6 |

Merge is performed the following way

7 |
Squash commit
8 |
 9 |             git checkout -B <Branch name> <Repository name>/<Branch name>
10 |             git merge --squash <Branch matched by git>
11 |             git commit -C <Branch matched by git>
12 |
Accumulated commit
13 |
14 |             git checkout -B <Branch name> <Repository name>/<Branch name>
15 |             git merge -m <commitMsg> <Branch matched by git> --no-ff
16 |

When changes are pushed to the integration branch?

17 |

Changes are only ever pushed when the build results is SUCCESS

18 |
19 |             git push <Repository name> <Branch name>
20 | 21 | 22 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/pretestedintegration/scm/git/GitBridge/help-repoName.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |

What to specify

5 |

6 | The repository name. In git the repository is always the name of the remote. So if you have specified a repository name 7 | in your Git configuration. You need to specify the exact same name here, otherwise no integration will be performed. We do the merge 8 | based on this. 9 |

10 |

No trailing slash on repository name.

11 |

12 | Remember to specify this when working with NAMED repositories in Git 13 |

14 |
15 | 16 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/pretestedintegration/scm/git/PretestedIntegrationAsGitPluginExt/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/pretestedintegration/scm/git/PretestedIntegrationAsGitPluginExt/help-integrationBranch.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

What to specify

5 |

The branch name must match your integration branch name. No trailing slash.

6 |

Merge is performed the following way

7 |
Squash commit
8 |
 9 |             git checkout -B <Branch name> <Repository name>/<Branch name>
10 |             git merge --squash <Branch matched by git>
11 |             git commit -C <Branch matched by git>
12 |
Accumulated commit
13 |
14 |             git checkout -B <Branch name> <Repository name>/<Branch name>
15 |             git merge -m <commitMsg> <Branch matched by git> --no-ff
16 |

When changes are pushed to the integration branch?

17 |

Changes are only ever pushed when the build results is SUCCESS

18 |
19 |             git push <Repository name> <Branch name>
20 | 21 | 22 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/pretestedintegration/scm/git/PretestedIntegrationAsGitPluginExt/help-repoName.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |

What to specify

5 |

6 | The repository name. In git the repository is always the name of the remote. So if you have specified a repository name 7 | in your Git configuration. You need to specify the exact same name here, otherwise no integration will be performed. We do the merge 8 | based on this. 9 |

10 |

No trailing slash on repository name.

11 |

12 | Remember to specify this when working with NAMED repositories in Git 13 |

14 |
15 | 16 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/pretestedintegration/scm/git/SquashCommitStrategy/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/pretestedintegration/scm/git/SquashCommitStrategy/help.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

Squashed Commit Strategy

5 |
This strategy squashes all your commit on a given branch with the --squash option
6 | 7 | 8 | -------------------------------------------------------------------------------- /src/test/java/org/jenkinsci/plugins/pretestedintegration/integration/scm/git/ChangelessBranchFailsBuildIT.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.integration.scm.git; 2 | 3 | import hudson.model.FreeStyleBuild; 4 | import hudson.model.FreeStyleProject; 5 | import hudson.model.Result; 6 | import org.eclipse.jgit.api.Git; 7 | import org.eclipse.jgit.lib.Repository; 8 | import org.junit.After; 9 | import org.junit.Rule; 10 | import org.junit.Test; 11 | import org.jvnet.hudson.test.JenkinsRule; 12 | 13 | import static junit.framework.TestCase.assertTrue; 14 | 15 | /** 16 | * Currently, if you push a ready branch with no changes, the build fails because either it can't find the MERGE_MSG file, or it is empty. 17 | * Since the exceptions thrown by the API's do a very bad job at actually pointing out what went wrong, we've written these tests 18 | * to make sure that the user is presented with a text that make sure there is a chance to decipher the error. 19 | */ 20 | public class ChangelessBranchFailsBuildIT { 21 | 22 | @Rule 23 | public JenkinsRule jenkins = new JenkinsRule(); 24 | 25 | private Repository repository; 26 | 27 | @After 28 | public void tearDown() throws Exception{ 29 | TestUtilsFactory.destroyRepo(repository); 30 | } 31 | 32 | @Test 33 | public void squash_changelessBranchFailsBuild() throws Exception { 34 | repository = TestUtilsFactory.createRepoWithoutBranches("squash_changelessBranchFailsBuild"); 35 | Git.open(repository.getDirectory()).branchCreate().setName("ready/no-changes").call(); 36 | FreeStyleProject project = TestUtilsFactory.configurePretestedIntegrationPlugin(jenkins, TestUtilsFactory.STRATEGY_TYPE.SQUASH, repository); 37 | FreeStyleBuild build = project.scheduleBuild2(0).get(); 38 | String console = jenkins.createWebClient().getPage(build, "console").asText(); 39 | System.out.println(console); 40 | jenkins.assertBuildStatus(Result.NOT_BUILT, build); 41 | } 42 | 43 | @Test 44 | public void accumulated_changelessBranchFailsBuild() throws Exception { 45 | repository = TestUtilsFactory.createRepoWithoutBranches("accumulated_changelessBranchFailsBuild"); 46 | Git.open(repository.getDirectory()).branchCreate().setName("ready/no-changes").call(); 47 | FreeStyleProject project = TestUtilsFactory.configurePretestedIntegrationPlugin(jenkins, TestUtilsFactory.STRATEGY_TYPE.ACCUMULATED, repository); 48 | FreeStyleBuild build = project.scheduleBuild2(0).get(); 49 | String console = jenkins.createWebClient().getPage(build, "console").asText(); 50 | System.out.println(console); 51 | jenkins.assertBuildStatus(Result.NOT_BUILT, build); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/test/java/org/jenkinsci/plugins/pretestedintegration/integration/scm/git/GHI97_SupportChecksIT.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.integration.scm.git; 2 | 3 | import hudson.matrix.MatrixProject; 4 | import hudson.model.FreeStyleProject; 5 | import hudson.model.ItemGroup; 6 | import org.jenkinsci.plugins.pretestedintegration.PretestedIntegrationPostCheckout; 7 | import org.junit.Test; 8 | 9 | import static junit.framework.Assert.assertFalse; 10 | import static junit.framework.Assert.assertTrue; 11 | 12 | public class GHI97_SupportChecksIT { 13 | 14 | /** 15 | * See GitHub issue #97 16 | */ 17 | @Test 18 | public void validateReturnsFromSupportedChecks_ValidatesGHI97() { 19 | PretestedIntegrationPostCheckout pipPost = new PretestedIntegrationPostCheckout(); 20 | FreeStyleProject freeStyleProject = new FreeStyleProject((ItemGroup)null, "FreeStyleProjectMustBeSupported"); 21 | MatrixProject matrix = new MatrixProject(null,"MatrixJobsMustBeSupported"); 22 | assertFalse(pipPost.isSupported("com.tikal.jenkins.plugins.multijob.MultiJobProject")); 23 | assertTrue(pipPost.isSupported(freeStyleProject.getClass())); 24 | assertTrue(pipPost.isSupported(matrix.getClass())); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/java/org/jenkinsci/plugins/pretestedintegration/integration/scm/git/GHI98_SupportForCredentialsIT.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.integration.scm.git; 2 | 3 | import com.cloudbees.plugins.credentials.CredentialsScope; 4 | import com.cloudbees.plugins.credentials.SystemCredentialsProvider; 5 | import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl; 6 | import hudson.model.FreeStyleProject; 7 | import hudson.plugins.git.UserRemoteConfig; 8 | import org.apache.commons.io.FileUtils; 9 | import org.eclipse.jgit.api.Git; 10 | import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; 11 | import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; 12 | import org.jenkinsci.plugins.workflow.job.WorkflowJob; 13 | import org.junit.Rule; 14 | import org.junit.Test; 15 | import org.jvnet.hudson.test.JenkinsRule; 16 | 17 | import java.io.File; 18 | import java.util.ArrayList; 19 | import java.util.Date; 20 | import java.util.List; 21 | 22 | import static org.junit.Assume.assumeTrue; 23 | 24 | /** 25 | * Created by mads on 1/11/18. 26 | * 27 | * This test requires 3 arguments from maven in order to be executed. We've done this because we use our own repo 28 | * and do not want to share our credentials to GitHub with everyone. 29 | * 30 | * Run this with parameters: 31 | *
    32 | *
  • -DpasswordForTest=...
  • 33 | *
  • -DusernameForTest=...
  • 34 | *
  • -DrepoForTest=...
  • 35 | *
36 | */ 37 | public class GHI98_SupportForCredentialsIT { 38 | 39 | @Rule 40 | public JenkinsRule jenkinsRule = new JenkinsRule(); 41 | 42 | final String pw = System.getProperty("passwordForTest"); 43 | final String uName = System.getProperty("usernameForTest"); 44 | final String repo = System.getProperty("repoForTest"); 45 | final String pipelineScript = "node {\n" + 46 | " checkout([$class: 'GitSCM', branches: [[name: '*/ready/**']], doGenerateSubmoduleConfigurations: false, extensions: [pretestedIntegration(gitIntegrationStrategy: squash(), integrationBranch: 'master', repoName: 'origin')], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'pipCredentials', url: '%repoForTest']]])\n" + 47 | " pretestedIntegrationPublisher()\n" + 48 | " echo \"Ohoy we've got success!\"\n" + 49 | "}"; 50 | 51 | @Test 52 | public void testCredentialsSupportForAbstractProjectTypes() throws Exception { 53 | assumeTrue(pw != null && repo != null && uName != null); 54 | cloneTestRepositoryAndPrepareABranch(); 55 | SystemCredentialsProvider scp = (SystemCredentialsProvider)jenkinsRule.getInstance().getExtensionList("com.cloudbees.plugins.credentials.SystemCredentialsProvider").get(0); 56 | UsernamePasswordCredentialsImpl unpwCred = new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, "pipCredentials","description", uName, pw); 57 | scp.getCredentials().add(unpwCred); 58 | scp.save(); 59 | List urcList = new ArrayList<>(); 60 | UserRemoteConfig urc = new UserRemoteConfig(repo,null,null,"pipCredentials"); 61 | urcList.add(urc); 62 | FreeStyleProject freeStyle = TestUtilsFactory.configurePretestedIntegrationPlugin(jenkinsRule, TestUtilsFactory.STRATEGY_TYPE.SQUASH, urcList,"origin", false); 63 | jenkinsRule.buildAndAssertSuccess(freeStyle); 64 | } 65 | 66 | @Test 67 | public void testCredentialsSupportForWorkflowProjectTypes() throws Exception { 68 | assumeTrue(pw != null && repo != null && uName != null); 69 | cloneTestRepositoryAndPrepareABranch(); 70 | SystemCredentialsProvider scp = (SystemCredentialsProvider)jenkinsRule.getInstance().getExtensionList("com.cloudbees.plugins.credentials.SystemCredentialsProvider").get(0); 71 | UsernamePasswordCredentialsImpl unpwCred = new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, "pipCredentials","description", uName, pw); 72 | scp.getCredentials().add(unpwCred); 73 | scp.save(); 74 | WorkflowJob wfJob = jenkinsRule.createProject(WorkflowJob.class, "PipTestPipeline"); 75 | wfJob.setDefinition(new CpsFlowDefinition(pipelineScript.replace("%repoForTest", repo), true)); 76 | jenkinsRule.buildAndAssertSuccess(wfJob); 77 | } 78 | 79 | private void cloneTestRepositoryAndPrepareABranch() throws Exception { 80 | File f = new File(TestUtilsFactory.WORKDIR,"testRepo"); 81 | if(f.exists()) FileUtils.deleteDirectory(f); 82 | Git g = Git.cloneRepository().setURI(repo).setDirectory(f).call(); 83 | Date d = new Date(); 84 | File fileWithContent = new File(f, "testOutput.txt"); 85 | g.checkout().setCreateBranch(true).setName("ready/"+d.getTime()).call(); 86 | FileUtils.writeStringToFile(fileWithContent,"Test case "+"org.jenkinsci.plugins.pretestedintegration.integration.scm.git.GHI98_SupportForCredentialsIT committed on "+d.getTime()+"\n",true); 87 | g.add().addFilepattern(fileWithContent.getName()).call(); 88 | g.commit().setAll(true).setMessage("GHI98_SupportForCredentialsIT committed on "+d.getTime()).call(); 89 | g.push().setPushAll().setCredentialsProvider(new UsernamePasswordCredentialsProvider(uName, pw)).call(); 90 | } 91 | 92 | } -------------------------------------------------------------------------------- /src/test/java/org/jenkinsci/plugins/pretestedintegration/integration/scm/git/GetCommitCountFromBranchCallbackIT.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.integration.scm.git; 2 | 3 | import hudson.model.TaskListener; 4 | 5 | import java.io.File; 6 | 7 | import org.apache.commons.io.FileUtils; 8 | import org.eclipse.jgit.api.Git; 9 | import org.eclipse.jgit.lib.ObjectId; 10 | import org.jenkinsci.plugins.pretestedintegration.scm.git.GetCommitCountFromBranchCallback; 11 | import org.junit.After; 12 | import org.junit.Test; 13 | 14 | import static junit.framework.TestCase.assertEquals; 15 | 16 | public class GetCommitCountFromBranchCallbackIT { 17 | 18 | private static final String FOLDER_PREFIX = "CommitCount_"; 19 | private File dir; 20 | 21 | @After 22 | public void tearDown() throws Exception { 23 | try { 24 | TestUtilsFactory.destroyDirectory(dir); 25 | } catch (Exception e) { 26 | System.out.format("WARNING: Could not delete the dir: " + dir.getAbsolutePath()); 27 | } 28 | } 29 | 30 | @Test 31 | public void counts_two_commits() throws Exception { 32 | dir = new File(TestUtilsFactory.WORKDIR,FOLDER_PREFIX + "count2"); 33 | Git git = Git.init().setDirectory(dir).call(); 34 | File testFile = new File(dir + "/file"); 35 | 36 | // First commit to master 37 | FileUtils.writeStringToFile(testFile, "master commit 1"); 38 | git.add().addFilepattern("file").call(); 39 | git.commit().setMessage("master commit 1").call(); 40 | 41 | // Create a branch 42 | git.checkout().setCreateBranch(true).setName("branch").call(); 43 | // First commit to branch 44 | FileUtils.writeStringToFile(testFile, "branch commit 1", true); 45 | git.add().addFilepattern("file").call(); 46 | git.commit().setMessage("branch commit 1").call(); 47 | // Second commit to branch 48 | FileUtils.writeStringToFile(testFile, "branch commit 2", true); 49 | git.add().addFilepattern("file").call(); 50 | ObjectId startCommit = git.commit().setMessage("branch commit 2").call(); 51 | 52 | // Counts two commits 53 | GetCommitCountFromBranchCallback callback = new GetCommitCountFromBranchCallback(startCommit, "master"); 54 | assertEquals("Commit count did not match expectations.", Integer.valueOf(2), callback.invoke(git.getRepository(), null)); 55 | 56 | // Second commit to master 57 | FileUtils.writeStringToFile(testFile, "master commit 2"); 58 | git.add().addFilepattern("file").call(); 59 | git.commit().setMessage("master commit 2").call(); 60 | 61 | // STILL counts two commits 62 | callback = new GetCommitCountFromBranchCallback(startCommit, "master"); 63 | assertEquals("Commit count did not match expectations.", new Integer(2), callback.invoke(git.getRepository(), null)); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/test/java/org/jenkinsci/plugins/pretestedintegration/integration/scm/git/JobDSLIT.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.integration.scm.git; 2 | 3 | import hudson.model.FreeStyleBuild; 4 | import hudson.model.FreeStyleProject; 5 | import javaposse.jobdsl.plugin.ExecuteDslScripts; 6 | import org.eclipse.jgit.api.Git; 7 | import org.eclipse.jgit.lib.Repository; 8 | import org.junit.After; 9 | import org.junit.Before; 10 | import org.junit.Rule; 11 | import org.junit.Test; 12 | import org.jvnet.hudson.test.JenkinsRule; 13 | 14 | import java.io.File; 15 | import java.util.ArrayList; 16 | import java.util.List; 17 | 18 | import static org.junit.Assert.assertNotNull; 19 | import static org.junit.Assert.assertTrue; 20 | 21 | /** 22 | * Created by mads on 1/15/18. 23 | job("generated") { 24 | scm { 25 | git { 26 | remote { 27 | name("origin") 28 | url("some.repo.somewhere.git") 29 | } 30 | extensions { 31 | pretestedIntegration("ACCUMULATED","master","origin") 32 | } 33 | } 34 | } 35 | publishers { 36 | pretestedIntegration() 37 | } 38 | } 39 | */ 40 | public class JobDSLIT { 41 | 42 | List repositories; 43 | 44 | String script = "job(\"generated\") {\n" + 45 | " scm {\n" + 46 | " git {\n" + 47 | " remote {\n" + 48 | " name(\"origin\")\n" + 49 | " url(\"%REPO_URL\")\n" + 50 | " }\n" + 51 | " extensions {\n" + 52 | " pretestedIntegration(\"ACCUMULATED\",\"master\",\"origin\")\n" + 53 | " }\n" + 54 | " }\n" + 55 | " }\n" + 56 | " \tpublishers {\n" + 57 | " \tpretestedIntegration() \n" + 58 | " \t}\n" + 59 | "}"; 60 | 61 | @Rule 62 | public JenkinsRule jr = new JenkinsRule(); 63 | 64 | @Test 65 | public void testGenerationOfJobDSLJob() throws Exception { 66 | /** 67 | * Step 1 68 | * Prepare a repository we can use. We create only a happy day scenario 69 | */ 70 | String repoName = "test-repo"; 71 | Repository repository = TestUtilsFactory.createValidRepository(repoName); 72 | repositories.add(repository); 73 | 74 | File workDir = new File(TestUtilsFactory.WORKDIR, repoName); 75 | 76 | Git.cloneRepository().setURI("file:///" + repository.getDirectory().getAbsolutePath()).setDirectory(workDir) 77 | .setBare(false) 78 | .setCloneAllBranches(true) 79 | .setNoCheckout(false) 80 | .call().close(); 81 | 82 | /** 83 | * Step 2 84 | * Create a seed job to create the job we want to use 85 | */ 86 | FreeStyleProject fp = jr.createFreeStyleProject("seed"); 87 | ExecuteDslScripts ex = new ExecuteDslScripts(); 88 | ex.setScriptText(script.replaceAll("%REPO_URL", "file://"+repository.getDirectory().getAbsolutePath())); 89 | fp.getBuildersList().add(ex); 90 | jr.buildAndAssertSuccess(fp); 91 | 92 | //Assert that our job was created 93 | assertNotNull(jr.getInstance().getItemByFullName("generated", FreeStyleProject.class)); 94 | 95 | /** 96 | * Step 3 97 | * Create and execute the seed job assert success 98 | */ 99 | FreeStyleBuild fb = jr.buildAndAssertSuccess(jr.getInstance().getItemByFullName("generated", FreeStyleProject.class)); 100 | assertTrue(fb.getLog().contains("[PREINT] Done pushing changes")); 101 | } 102 | 103 | @Before 104 | public void setup() { 105 | repositories = new ArrayList<>(); 106 | } 107 | 108 | @After 109 | public void tearDown() throws Exception { 110 | for (Repository repo : repositories) { 111 | TestUtilsFactory.destroyRepo(repo); 112 | } 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /src/test/java/org/jenkinsci/plugins/pretestedintegration/integration/scm/git/MatrixProjectBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package org.jenkinsci.plugins.pretestedintegration.integration.scm.git; 7 | 8 | import hudson.matrix.Axis; 9 | import hudson.matrix.MatrixProject; 10 | import hudson.model.AbstractProject; 11 | import hudson.model.FreeStyleProject; 12 | import hudson.model.TopLevelItem; 13 | import hudson.plugins.git.BranchSpec; 14 | import hudson.plugins.git.GitSCM; 15 | import hudson.plugins.git.SubmoduleConfig; 16 | import hudson.plugins.git.UserRemoteConfig; 17 | import hudson.plugins.git.extensions.GitSCMExtension; 18 | import hudson.plugins.git.extensions.impl.CleanCheckout; 19 | import hudson.plugins.git.extensions.impl.PruneStaleBranch; 20 | 21 | import java.util.ArrayList; 22 | import java.util.Arrays; 23 | import java.util.Collections; 24 | import java.util.List; 25 | 26 | import org.jenkinsci.plugins.pretestedintegration.PretestedIntegrationPostCheckout; 27 | import org.jenkinsci.plugins.pretestedintegration.scm.git.AccumulatedCommitStrategy; 28 | import org.jenkinsci.plugins.pretestedintegration.scm.git.PretestedIntegrationAsGitPluginExt; 29 | import org.jenkinsci.plugins.pretestedintegration.scm.git.SquashCommitStrategy; 30 | import org.jvnet.hudson.test.JenkinsRule; 31 | 32 | /** 33 | * 34 | * @author Mads 35 | */ 36 | public class MatrixProjectBuilder { 37 | 38 | private JenkinsRule rule; 39 | private String integrationBranchName = "master"; 40 | private String repoName = "origin"; 41 | private Class jobType; 42 | private TestUtilsFactory.STRATEGY_TYPE type; 43 | private List gitRepos; 44 | private boolean useSlave; 45 | 46 | public MatrixProjectBuilder setRule(JenkinsRule rule) { 47 | this.rule = rule; 48 | return this; 49 | } 50 | 51 | public MatrixProjectBuilder setIntegrationBranchName(String integrationBranchName) { 52 | this.integrationBranchName = integrationBranchName; 53 | return this; 54 | } 55 | 56 | public MatrixProjectBuilder setJobType(Class jobType) { 57 | this.jobType = jobType; 58 | return this; 59 | } 60 | 61 | public MatrixProjectBuilder setStrategy(TestUtilsFactory.STRATEGY_TYPE type) { 62 | this.type = type; 63 | return this; 64 | } 65 | 66 | public MatrixProjectBuilder setGitRepos(List gitRepos) { 67 | this.gitRepos = gitRepos; 68 | return this; 69 | } 70 | 71 | public MatrixProjectBuilder setUseSlaves(boolean useSlave) { 72 | this.useSlave = useSlave; 73 | return this; 74 | } 75 | 76 | public MatrixProjectBuilder setRepoName(String repoName) { 77 | this.repoName = repoName; 78 | return this; 79 | } 80 | 81 | public AbstractProject generateJenkinsJob() throws Exception { 82 | assert jobType.equals(FreeStyleProject.class) || jobType.equals(MatrixProject.class) : "We must use either matrix or free style job types"; 83 | //TODO: This does not work with type 84 | MatrixProject project = rule.createProject(MatrixProject.class, "GeneratedJenkinsJob"); 85 | 86 | List gitSCMExtensions = new ArrayList<>(); 87 | gitSCMExtensions.add(new PruneStaleBranch()); 88 | gitSCMExtensions.add(new CleanCheckout()); 89 | gitSCMExtensions.add(new PretestedIntegrationAsGitPluginExt(type == TestUtilsFactory.STRATEGY_TYPE.SQUASH ? new SquashCommitStrategy() : new AccumulatedCommitStrategy(), integrationBranchName, repoName)); 90 | 91 | GitSCM gitSCM = new GitSCM(gitRepos, 92 | Collections.singletonList(new BranchSpec("*/ready/**")), 93 | false, Collections.emptyList(), 94 | null, null, gitSCMExtensions); 95 | 96 | project.setScm(gitSCM); 97 | project.getPublishersList().add(new PretestedIntegrationPostCheckout()); 98 | 99 | project.getAxes().add(new Axis("OS", Arrays.asList("Linux", "Windows","OS2"))); 100 | 101 | 102 | return project; 103 | } 104 | 105 | 106 | } 107 | -------------------------------------------------------------------------------- /src/test/java/org/jenkinsci/plugins/pretestedintegration/integration/scm/git/NothingToDoFailsBuild.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.integration.scm.git; 2 | 3 | import hudson.model.FreeStyleBuild; 4 | import hudson.model.FreeStyleProject; 5 | import hudson.model.Result; 6 | import org.eclipse.jgit.lib.Repository; 7 | import org.junit.After; 8 | import org.junit.Rule; 9 | import org.junit.Test; 10 | import org.jvnet.hudson.test.JenkinsRule; 11 | 12 | import static junit.framework.Assert.assertTrue; 13 | 14 | /** 15 | * Arguably when there's NothingToDo the build result should be 'NOT_BUILT'. 16 | * After an internal discussion we decided that we'd stick to 'FAILED' since: 17 | * A) If there's nothing to do, why was the job triggered? Something might've gone wrong. 18 | * B) We eventually want to get rid of the NothingToDo path or at least rewrite how it's handled. 19 | */ 20 | public class NothingToDoFailsBuild { 21 | 22 | @Rule 23 | public JenkinsRule jenkins = new JenkinsRule(); 24 | 25 | private Repository repository; 26 | 27 | @After 28 | public void tearDown() throws Exception{ 29 | TestUtilsFactory.destroyRepo(repository); 30 | } 31 | 32 | @Test 33 | public void squash_nothingToDoFailsBuild() throws Exception { 34 | repository = TestUtilsFactory.createRepoWithoutBranches("squash_nothingToDoFailsBuild"); 35 | FreeStyleProject project = TestUtilsFactory.configurePretestedIntegrationPlugin(jenkins, TestUtilsFactory.STRATEGY_TYPE.SQUASH, repository); 36 | FreeStyleBuild build = project.scheduleBuild2(0).get(); 37 | String console = jenkins.createWebClient().getPage(build, "console").asText(); 38 | System.out.println(console); 39 | jenkins.assertBuildStatus(Result.FAILURE, build); 40 | assertTrue(console.contains("Nothing to do")); 41 | } 42 | 43 | @Test 44 | public void accumulated_nothingToDoFailsBuild() throws Exception { 45 | repository = TestUtilsFactory.createRepoWithoutBranches("accumulated_nothingToDoFailsBuild"); 46 | FreeStyleProject project = TestUtilsFactory.configurePretestedIntegrationPlugin(jenkins, TestUtilsFactory.STRATEGY_TYPE.SQUASH, repository); 47 | FreeStyleBuild build = project.scheduleBuild2(0).get(); 48 | String console = jenkins.createWebClient().getPage(build, "console").asText(); 49 | System.out.println(console); 50 | jenkins.assertBuildStatus(Result.FAILURE, build); 51 | assertTrue(console.contains("Nothing to do")); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/test/java/org/jenkinsci/plugins/pretestedintegration/integration/scm/git/PipAsGitExtensionIT.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.integration.scm.git; 2 | 3 | import hudson.model.FreeStyleProject; 4 | import hudson.model.Result; 5 | import hudson.plugins.git.BranchSpec; 6 | import hudson.plugins.git.GitSCM; 7 | import hudson.plugins.git.UserRemoteConfig; 8 | import hudson.plugins.git.extensions.GitSCMExtension; 9 | import hudson.plugins.git.extensions.impl.CleanCheckout; 10 | import hudson.plugins.git.extensions.impl.PruneStaleBranch; 11 | import hudson.slaves.DumbSlave; 12 | import org.apache.commons.lang.StringUtils; 13 | import org.eclipse.jgit.lib.Repository; 14 | import org.jenkinsci.plugins.pretestedintegration.PretestedIntegrationPostCheckout; 15 | import org.jenkinsci.plugins.pretestedintegration.scm.git.PretestedIntegrationAsGitPluginExt; 16 | import org.jenkinsci.plugins.pretestedintegration.scm.git.SquashCommitStrategy; 17 | import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; 18 | import org.jenkinsci.plugins.workflow.job.WorkflowJob; 19 | import org.jenkinsci.plugins.workflow.job.WorkflowRun; 20 | import org.junit.*; 21 | import org.jvnet.hudson.test.JenkinsRule; 22 | 23 | import java.util.ArrayList; 24 | import java.util.Arrays; 25 | import java.util.Collections; 26 | import java.util.List; 27 | 28 | import static junit.framework.Assert.assertEquals; 29 | 30 | public class PipAsGitExtensionIT { 31 | 32 | 33 | @Rule 34 | public JenkinsRule jenkinsRule = new JenkinsRule(); 35 | private Repository repo; 36 | 37 | 38 | public PipAsGitExtensionIT() { 39 | } 40 | 41 | @Before 42 | public void setUp() { 43 | 44 | 45 | } 46 | 47 | @After 48 | public void tearDown() throws Exception { 49 | TestUtilsFactory.destroyRepo(repo); 50 | 51 | } 52 | 53 | @Test 54 | public void gitSCMIntegrationTest() throws Exception { 55 | String repoName = "service-desk"; 56 | 57 | repo = TestUtilsFactory.createValidRepository(repoName); 58 | 59 | FreeStyleProject project = jenkinsRule.createFreeStyleProject(); 60 | 61 | DumbSlave slave = jenkinsRule.createOnlineSlave(); 62 | project.setAssignedNode(slave); 63 | 64 | 65 | List scmExtensions = new ArrayList<>(); 66 | scmExtensions.add(new PretestedIntegrationAsGitPluginExt(new SquashCommitStrategy(), "master", "origin")); 67 | scmExtensions.add(new PruneStaleBranch()); 68 | scmExtensions.add(new CleanCheckout()); 69 | 70 | List userConfigs = new ArrayList<>(); 71 | userConfigs.add(new UserRemoteConfig("file://" + repo.getDirectory().getAbsolutePath(), "origin", null, null)); 72 | 73 | 74 | project.getPublishersList().add(new PretestedIntegrationPostCheckout()); 75 | 76 | GitSCM git = new GitSCM(userConfigs, 77 | Collections.singletonList(new BranchSpec("*/ready/**")) 78 | , false 79 | , null 80 | , null, null, scmExtensions); 81 | 82 | project.setScm(git); 83 | project.save(); 84 | 85 | TestUtilsFactory.triggerProject(project); 86 | jenkinsRule.waitUntilNoActivityUpTo(60000); 87 | 88 | String console = jenkinsRule.createWebClient().getPage(project.getFirstBuild(), "console").asText(); 89 | System.out.println(console); 90 | 91 | int commits = TestUtilsFactory.countCommits(repo); 92 | System.out.println(commits); 93 | assertEquals(3, commits); 94 | assertEquals(Result.SUCCESS, project.getFirstBuild().getResult()); 95 | 96 | } 97 | 98 | 99 | @Test 100 | public void pipelineScriptTest() throws Exception { 101 | 102 | repo = TestUtilsFactory.createValidRepository("script-desk"); 103 | 104 | WorkflowJob job = jenkinsRule.createProject(WorkflowJob.class, "foo-project"); 105 | CpsFlowDefinition flowDef = new CpsFlowDefinition(StringUtils.join(Arrays.asList( 106 | "node {", 107 | "checkout([$class: 'GitSCM'," + 108 | " branches: [[name: '*/ready/**']]," + 109 | " doGenerateSubmoduleConfigurations: false," + 110 | " extensions: [pretestedIntegration(gitIntegrationStrategy: squash(), integrationBranch: 'master', repoName: 'origin')]," + 111 | " submoduleCfg: []," + 112 | " userRemoteConfigs: [[url: '" + "file://" + repo.getDirectory().getAbsolutePath() + "']]])", 113 | "pretestedIntegrationPublisher()", 114 | "}"), "\n"), false); 115 | 116 | job.setDefinition(flowDef); 117 | job.save(); 118 | 119 | WorkflowRun workflow = job.scheduleBuild2(0).get(); 120 | 121 | 122 | jenkinsRule.waitUntilNoActivityUpTo(60000); 123 | 124 | String console = jenkinsRule.createWebClient().getPage(job.getFirstBuild(), "console").asText(); 125 | System.out.println(console); 126 | 127 | int commits = TestUtilsFactory.countCommits(repo); 128 | 129 | assertEquals(3, commits); 130 | assertEquals(Result.SUCCESS, workflow.getResult()); 131 | } 132 | 133 | 134 | } 135 | -------------------------------------------------------------------------------- /src/test/java/org/jenkinsci/plugins/pretestedintegration/integration/scm/git/TestCommit.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.integration.scm.git; 2 | 3 | public class TestCommit { 4 | 5 | public final String branch; 6 | public final String file; 7 | public final String content; 8 | public final String message; 9 | 10 | public TestCommit(String branch, String file, String content, String message) { 11 | this.branch = branch; 12 | this.file = file; 13 | this.content = content; 14 | this.message = message; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/org/jenkinsci/plugins/pretestedintegration/integration/scm/git/UniqueBranchGenerator.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.integration.scm.git; 2 | 3 | import java.io.File; 4 | import java.util.UUID; 5 | import org.apache.commons.io.FileUtils; 6 | import org.eclipse.jgit.api.CommitCommand; 7 | import org.eclipse.jgit.api.CreateBranchCommand; 8 | import org.eclipse.jgit.api.Git; 9 | import org.eclipse.jgit.lib.Repository; 10 | import static org.jenkinsci.plugins.pretestedintegration.integration.scm.git.TestUtilsFactory.AUTHOR_EMAIL; 11 | import static org.jenkinsci.plugins.pretestedintegration.integration.scm.git.TestUtilsFactory.AUTHOR_NAME; 12 | 13 | /** 14 | *

General purpose class that helps using JGit

15 | *

16 | * Create a unique branch with unique content on master branch when 17 | * {@link #build()} is called

18 | */ 19 | public class UniqueBranchGenerator { 20 | 21 | public String[] commitMessages; 22 | public Repository repo; 23 | public String branchName; 24 | 25 | public UniqueBranchGenerator(Repository repo, String... commitMessages) { 26 | this.commitMessages = commitMessages; 27 | this.repo = repo; 28 | } 29 | 30 | public UniqueBranchGenerator usingBranch(String branchName) { 31 | this.branchName = branchName; 32 | return this; 33 | } 34 | 35 | /** 36 | * Requires a bare repository. We clone to a random workspace 37 | * 38 | * @throws Exception 39 | * @return The generator currently being worked on 40 | */ 41 | public UniqueBranchGenerator build() throws Exception { 42 | 43 | Git git; 44 | 45 | File workDirTarget = new File(repo.getDirectory().getAbsolutePath() + "/../../" + UUID.randomUUID().toString()); 46 | System.out.println(workDirTarget.getAbsolutePath()); 47 | 48 | Git.cloneRepository() 49 | .setURI("file://" + repo.getDirectory().getAbsolutePath()) 50 | .setBare(false) 51 | .setNoCheckout(false) 52 | .setCloneAllBranches(true) 53 | .setDirectory(workDirTarget).call().close(); 54 | 55 | File gitMetaDir = new File(workDirTarget.getAbsolutePath() + System.getProperty("file.separator") + ".git"); 56 | System.out.println("Setting .git metadata to work in directory: " + gitMetaDir.getAbsolutePath()); 57 | 58 | git = Git.open(gitMetaDir); 59 | 60 | CreateBranchCommand createBranchCommand = git.branchCreate(); 61 | createBranchCommand.setName(branchName); 62 | createBranchCommand.call(); 63 | git.checkout().setName(branchName).call(); 64 | 65 | File repoRoot = git.getRepository().getWorkTree(); 66 | UUID rand = UUID.randomUUID(); 67 | File randomFile = new File(repoRoot, rand.toString() + ".log"); 68 | randomFile.createNewFile(); 69 | git.add().addFilepattern(".").call(); 70 | 71 | int cnt = 0; 72 | for (String msg : commitMessages) { 73 | FileUtils.writeStringToFile(randomFile, rand.toString() + "-" + cnt + "\n", true); 74 | CommitCommand commitCommand = git.commit(); 75 | commitCommand.setMessage(msg); 76 | commitCommand.setAuthor(AUTHOR_NAME, AUTHOR_EMAIL); 77 | commitCommand.call(); 78 | cnt++; 79 | } 80 | 81 | git.push().setPushAll().call(); 82 | git.checkout().setName("master"); 83 | git.close(); 84 | 85 | FileUtils.deleteDirectory(workDirTarget); 86 | return this; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/test/java/org/jenkinsci/plugins/pretestedintegration/unit/AbstractSCMBridgeTest.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.unit; 2 | 3 | import hudson.Launcher; 4 | import hudson.model.BuildListener; 5 | import hudson.model.FreeStyleBuild; 6 | import hudson.model.Result; 7 | import hudson.model.StreamBuildListener; 8 | import hudson.plugins.git.Branch; 9 | import hudson.plugins.git.Revision; 10 | import hudson.plugins.git.util.Build; 11 | import hudson.plugins.git.util.BuildData; 12 | import java.io.OutputStream; 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | import junit.framework.TestCase; 16 | import org.apache.commons.io.output.ByteArrayOutputStream; 17 | import org.jenkinsci.plugins.pretestedintegration.AbstractSCMBridge; 18 | import org.jenkinsci.plugins.pretestedintegration.SCMBridgeDescriptor; 19 | import org.junit.Rule; 20 | import org.junit.Test; 21 | import org.jvnet.hudson.test.JenkinsRule; 22 | import static junit.framework.TestCase.assertFalse; 23 | import static junit.framework.TestCase.assertTrue; 24 | import static org.mockito.Mockito.*; 25 | 26 | public class AbstractSCMBridgeTest { 27 | 28 | @Rule 29 | public JenkinsRule rule = new JenkinsRule(); 30 | 31 | @Test 32 | public void testShouldIncludeDummySCMExtension() throws Exception { 33 | boolean includedInInterfaceDescriptors = false; 34 | boolean includedInDescriptors = false; 35 | List> interfaceDescriptors = AbstractSCMBridge.all(); 36 | for (SCMBridgeDescriptor i : interfaceDescriptors) { 37 | if (i.getDisplayName().equals("DummySCM")) { 38 | includedInInterfaceDescriptors = true; 39 | } 40 | } 41 | assertTrue(includedInInterfaceDescriptors); 42 | 43 | List> descriptors = AbstractSCMBridge.getDescriptors(); 44 | for (SCMBridgeDescriptor d : descriptors) { 45 | if (d.getDisplayName().equals("DummySCM")) { 46 | includedInDescriptors = true; 47 | } 48 | } 49 | assertTrue(includedInDescriptors); 50 | } 51 | 52 | @Test 53 | public void testShouldGetCorrectDescriptor() { 54 | DummySCM scm = new DummySCM(null); 55 | TestCase.assertEquals("DummySCM", scm.getDescriptor().getDisplayName()); 56 | } 57 | 58 | @Test 59 | public void testShouldBeCommited() throws Exception { 60 | DummySCM scm = new DummySCM(null); 61 | FreeStyleBuild build = mock(FreeStyleBuild.class); 62 | when(build.getResult()).thenReturn(Result.SUCCESS); 63 | Launcher launcher = mock(Launcher.class); 64 | 65 | BuildData gitBuildData = mock(BuildData.class); 66 | Build lastBuild = mock(Build.class); 67 | Revision rev = mock(Revision.class); 68 | Branch gitBranchData = mock(Branch.class); 69 | 70 | gitBuildData.lastBuild = lastBuild; 71 | lastBuild.revision = rev; 72 | 73 | when(build.getAction(BuildData.class)).thenReturn(gitBuildData); 74 | 75 | List branches = new ArrayList<>(); 76 | branches.add(gitBranchData); 77 | when(gitBuildData.lastBuild.revision.getBranches()).thenReturn(branches); 78 | when(gitBranchData.getName()).thenReturn("origin/ready/f1"); 79 | 80 | OutputStream out = new ByteArrayOutputStream(); 81 | BuildListener listener = new StreamBuildListener(out); 82 | assertFalse(scm.isCommited()); 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /src/test/java/org/jenkinsci/plugins/pretestedintegration/unit/DummyBridge.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.unit; 2 | 3 | import hudson.Launcher; 4 | import hudson.model.AbstractBuild; 5 | import hudson.model.BuildListener; 6 | import java.io.IOException; 7 | import org.jenkinsci.plugins.pretestedintegration.AbstractSCMBridge; 8 | import org.jenkinsci.plugins.pretestedintegration.exceptions.EstablishingWorkspaceFailedException; 9 | import org.jenkinsci.plugins.pretestedintegration.IntegrationStrategy; 10 | 11 | public class DummyBridge extends AbstractSCMBridge { 12 | 13 | public DummyBridge(IntegrationStrategy behaves) { 14 | super(behaves); 15 | } 16 | 17 | @Override 18 | protected String getIntegrationBranch() { 19 | return "master"; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/org/jenkinsci/plugins/pretestedintegration/unit/DummyIntegrationStrategy.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.unit; 2 | 3 | import hudson.Launcher; 4 | import hudson.model.AbstractBuild; 5 | import hudson.model.BuildListener; 6 | import org.jenkinsci.plugins.pretestedintegration.AbstractSCMBridge; 7 | import org.jenkinsci.plugins.pretestedintegration.exceptions.IntegrationFailedException; 8 | import org.jenkinsci.plugins.pretestedintegration.exceptions.NothingToDoException; 9 | import org.jenkinsci.plugins.pretestedintegration.exceptions.UnsupportedConfigurationException; 10 | import org.jenkinsci.plugins.pretestedintegration.IntegrationStrategy; 11 | import org.kohsuke.stapler.DataBoundConstructor; 12 | 13 | public class DummyIntegrationStrategy extends IntegrationStrategy { 14 | 15 | @DataBoundConstructor 16 | public DummyIntegrationStrategy() { 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/test/java/org/jenkinsci/plugins/pretestedintegration/unit/DummySCM.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.unit; 2 | 3 | import hudson.Extension; 4 | import hudson.Launcher; 5 | import hudson.model.AbstractBuild; 6 | import hudson.model.BuildListener; 7 | import hudson.model.Result; 8 | import java.io.IOException; 9 | import net.sf.json.JSONObject; 10 | import org.jenkinsci.plugins.pretestedintegration.AbstractSCMBridge; 11 | import org.jenkinsci.plugins.pretestedintegration.exceptions.PushFailedException; 12 | import org.jenkinsci.plugins.pretestedintegration.exceptions.EstablishingWorkspaceFailedException; 13 | import org.jenkinsci.plugins.pretestedintegration.IntegrationStrategy; 14 | import org.jenkinsci.plugins.pretestedintegration.SCMBridgeDescriptor; 15 | import org.kohsuke.stapler.DataBoundConstructor; 16 | 17 | import org.kohsuke.stapler.StaplerRequest; 18 | 19 | public class DummySCM extends AbstractSCMBridge { 20 | 21 | private boolean commited = false; 22 | private boolean rolledBack = false; 23 | 24 | @DataBoundConstructor 25 | public DummySCM(IntegrationStrategy behaves) { 26 | super(behaves); 27 | } 28 | 29 | public boolean isCommited() { 30 | return commited; 31 | } 32 | 33 | public boolean isRolledBack() { 34 | return rolledBack; 35 | } 36 | 37 | @Override 38 | protected String getIntegrationBranch() { 39 | return "master"; 40 | } 41 | 42 | @Extension 43 | public static final class DescriptorImpl extends SCMBridgeDescriptor { 44 | 45 | @Override 46 | public String getDisplayName() { 47 | return "DummySCM"; 48 | } 49 | 50 | @Override 51 | public DummyBridge newInstance(StaplerRequest req, JSONObject formData) throws FormException { 52 | DummyBridge i = (DummyBridge) super.newInstance(req, formData); 53 | save(); 54 | return i; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/test/java/org/jenkinsci/plugins/pretestedintegration/unit/GitIntegrationStrategyTest.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.pretestedintegration.unit; 2 | 3 | import hudson.Launcher; 4 | import hudson.model.AbstractBuild; 5 | import hudson.model.BuildListener; 6 | import static junit.framework.TestCase.assertEquals; 7 | import static junit.framework.TestCase.assertNotNull; 8 | 9 | import hudson.model.Run; 10 | import hudson.model.TaskListener; 11 | import hudson.plugins.git.Branch; 12 | import hudson.plugins.git.GitSCM; 13 | import hudson.plugins.git.Revision; 14 | import org.eclipse.jgit.lib.PersonIdent; 15 | import org.jenkinsci.plugins.gitclient.GitClient; 16 | import org.jenkinsci.plugins.pretestedintegration.AbstractSCMBridge; 17 | import org.jenkinsci.plugins.pretestedintegration.exceptions.IntegrationFailedException; 18 | import org.jenkinsci.plugins.pretestedintegration.exceptions.NothingToDoException; 19 | import org.jenkinsci.plugins.pretestedintegration.exceptions.UnsupportedConfigurationException; 20 | import org.jenkinsci.plugins.pretestedintegration.scm.git.GitBridge; 21 | import org.jenkinsci.plugins.pretestedintegration.scm.git.GitIntegrationStrategy; 22 | import org.junit.Test; 23 | 24 | import java.io.IOException; 25 | 26 | public class GitIntegrationStrategyTest { 27 | @Test 28 | public void getPersonIdentTest() throws Exception{ 29 | GitIntegrationStrategy strategy = getDummyStrategy(); 30 | PersonIdent identity = strategy.getPersonIdent("john Doe 1442321765 +0200"); 31 | assertNotNull("Shouldn't be null.", identity); 32 | assertEquals("Identity name mismatch", "john Doe", identity.getName()); 33 | assertEquals("Identity mail mismatch", "Joh@praqma.net", identity.getEmailAddress()); 34 | } 35 | 36 | private GitIntegrationStrategy getDummyStrategy() { 37 | return new GitIntegrationStrategy() { 38 | @Override 39 | public void integrate(GitSCM scm, Run build, GitClient git, TaskListener listener, Revision marked, Branch triggeredBranch, GitBridge bridge) throws IntegrationFailedException, NothingToDoException, UnsupportedConfigurationException, IOException, InterruptedException { 40 | throw new UnsupportedOperationException("Dummies can't integrate."); 41 | } 42 | }; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/test/resources/EndUserTesting/Jenkinsfile: -------------------------------------------------------------------------------- 1 | 2 | def pattern = 'MultiBranchPipePreSCM' 3 | 4 | def triggerBranchPattern = '*/ready' + pattern + '/*' 5 | def integrationBranch = 'master' + pattern 6 | 7 | 8 | node { 9 | stage ('Checkout'){ 10 | // checkout scm 11 | ///** 12 | try { 13 | checkout([ 14 | $class: 'GitSCM', 15 | branches: [[name: triggerBranchPattern ]], 16 | userRemoteConfigs: [[ 17 | name: 'origin', 18 | url: 'git@github.com:bicschneider/test-git-phlow-plugin.git' 19 | ]], 20 | extensions: [ 21 | pretestedIntegration( 22 | gitIntegrationStrategy: accumulated(), 23 | integrationBranch: integrationBranch, 24 | repoName: 'origin') 25 | , 26 | [ $class: 'ChangelogToBranch', 27 | options: [compareRemote: 'origin', compareTarget: integrationBranch] 28 | ], 29 | [$class: 'PruneStaleBranch'] 30 | ] 31 | ]) 32 | } catch(Exception e) { 33 | echo "Leave further processing to publisher" 34 | } 35 | 36 | // */ 37 | // try { 38 | // sh ''' 39 | // if [ -e ./build_failed.md ]; then 40 | // exit 1 41 | // fi 42 | // ''' 43 | // } catch(Exception e) { 44 | // currentBuild.result = 'UNSTABLE' 45 | // } 46 | pretestedIntegrationPublisher() 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/test/resources/EndUserTesting/JenkinsfileDeclCheckoutSCM: -------------------------------------------------------------------------------- 1 | 2 | def pattern = 'PipeDeclCheckoutSCM' 3 | 4 | def triggerBranchPattern = '*/ready' + pattern + '/*' 5 | def integrationBranch = 'master' + pattern 6 | pipeline{ 7 | agent none 8 | stages { 9 | stage ('Checkout') { 10 | agent { 11 | label 'master' 12 | } 13 | steps { 14 | checkout([ 15 | $class: 'GitSCM', 16 | branches: [[name: triggerBranchPattern ]], 17 | userRemoteConfigs: [[ 18 | name: 'origin', 19 | url: 'git@github.com:bicschneider/test-git-phlow-plugin.git' 20 | ]], 21 | extensions: [ 22 | pretestedIntegration( 23 | gitIntegrationStrategy: accumulated(), 24 | integrationBranch: integrationBranch, 25 | repoName: 'origin') 26 | , 27 | [ $class: 'ChangelogToBranch', 28 | options: [compareRemote: 'origin', compareTarget: integrationBranch] 29 | ], 30 | [$class: 'PruneStaleBranch'] 31 | ] 32 | ]) 33 | // sh ''' 34 | // if [ -e ./build_failed.md ]; then 35 | // exit 1 36 | // fi 37 | // ''' 38 | } 39 | post { 40 | always { 41 | pretestedIntegrationPublisher() 42 | } 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/test/resources/EndUserTesting/JenkinsfileDeclPreSCM: -------------------------------------------------------------------------------- 1 | 2 | def pattern = 'PipeDeclPreSCM' 3 | 4 | def triggerBranchPattern = '*/ready' + pattern + '/*' 5 | def integrationBranch = 'master' + pattern 6 | pipeline{ 7 | agent none 8 | stages { 9 | stage ('Checkout') { 10 | agent { 11 | label 'master' 12 | } 13 | steps { 14 | checkout scm // just reference SCM in the job executing the Pipeline script. 15 | // sh ''' 16 | // if [ -e ./build_failed.md ]; then 17 | // exit 1 18 | // fi 19 | // ''' 20 | } 21 | post { 22 | always { 23 | pretestedIntegrationPublisher() 24 | } 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/resources/EndUserTesting/JenkinsfileScriptedCheckoutSCM: -------------------------------------------------------------------------------- 1 | 2 | def pattern = 'PipeScriptedCheckoutSCM' 3 | 4 | def triggerBranchPattern = '*/ready' + pattern + '/*' 5 | def integrationBranch = 'master' + pattern 6 | node { 7 | stage ('Checkout'){ 8 | 9 | try { 10 | checkout([ 11 | $class: 'GitSCM', 12 | branches: [[name: triggerBranchPattern ]], 13 | userRemoteConfigs: [[ 14 | name: 'origin', 15 | url: 'git@github.com:bicschneider/test-git-phlow-plugin.git' 16 | ]], 17 | extensions: [ 18 | pretestedIntegration( 19 | gitIntegrationStrategy: accumulated(), 20 | integrationBranch: integrationBranch, 21 | repoName: 'origin') 22 | , 23 | [ $class: 'ChangelogToBranch', 24 | options: [compareRemote: 'origin', compareTarget: integrationBranch] 25 | ], 26 | [$class: 'PruneStaleBranch'] 27 | ] 28 | ]) 29 | } catch(Exception e) { 30 | echo "Leave further processing to publisher" 31 | } 32 | // try { 33 | // sh ''' 34 | // if [ -e ./build_failed.md ]; then 35 | // exit 1 36 | // fi 37 | // ''' 38 | // } catch(Exception e) { 39 | // currentBuild.result = 'UNSTABLE' 40 | // } 41 | pretestedIntegrationPublisher() 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/test/resources/EndUserTesting/JenkinsfileScriptedPreSCM: -------------------------------------------------------------------------------- 1 | 2 | def pattern = 'PipeScriptedSCM' 3 | 4 | def triggerBranchPattern = '*/ready' + pattern + '/*' 5 | def integrationBranch = 'master' + pattern 6 | node { 7 | stage ('Checkout'){ 8 | checkout scm // just reference SCM in the job executing the Pipeline script. 9 | /** 10 | checkout([ 11 | $class: 'GitSCM', 12 | branches: [[name: triggerBranchPattern ]], 13 | userRemoteConfigs: [[ 14 | name: 'origin', 15 | url: 'git@github.com:bicschneider/test-git-phlow-plugin.git' 16 | ]], 17 | extensions: [ 18 | pretestedIntegration( 19 | gitIntegrationStrategy: accumulated(), 20 | integrationBranch: integrationBranch, 21 | repoName: 'origin') 22 | , 23 | [ $class: 'ChangelogToBranch', 24 | options: [compareRemote: 'origin', compareTarget: integrationBranch] 25 | ], 26 | [$class: 'PruneStaleBranch'] 27 | ] 28 | ]) 29 | */ 30 | // try { 31 | // sh ''' 32 | // if [ -e ./build_failed.md ]; then 33 | // exit 1 34 | // fi 35 | // ''' 36 | // } catch(Exception e) { 37 | // currentBuild.result = 'UNSTABLE' 38 | // } 39 | pretestedIntegrationPublisher() 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/test/resources/EndUserTesting/README.md: -------------------------------------------------------------------------------- 1 | # End users testing with the build-in Jenkins instance 2 | A set of jobs has been created in order to easy make end user testing. Currently the jobs are hardcoded copy xml, but 3 | should be chagned to JobDSL etc and later also Pipeline with the support is there 4 | 5 | ## HowTo run the EndUser test scenarios 6 | * Create the test repo 7 | * Run the script `./src/test/resources/EndUserTesting/createRepoForIntegrationSituations.sh` 8 | * TODO: parameterize the script to take a `repo-url` 9 | * Setup the jobs in Jenkins 10 | * cp the jobs from `jobs` to `/works/jobs` 11 | * Install these plugins manually: 12 | * `text-finder` 13 | * `conditional-buildstep` 14 | * Run the Jenkins instance (hpi:run) in Run or Debug mode 15 | 16 | ## How to easy clean and rerun (A) 17 | * Delete the jenkins jobs produced contents 18 | * Stop the Jenkins instance 19 | * run `for job in $(ls -1d work/jobs/test*) ; do rm -rf $job/builds $job/workspace $job/configurations $job/nextBuildNumber $job/scm-polling.log; done` 20 | * `cd test-git-phlow-plugin && git push origin --mirror -f && cd -` 21 | * Start the Jenkins Instance 22 | 23 | ## How to easy clean and rerun (B) 24 | * run `for job in $(ls -1d work/jobs/test*) ; do rm -rf $job/builds $job/workspace $job/configurations $job/nextBuildNumber $job/scm-polling.log; done` 25 | * Open url `localhost:8080/jenkins/reload` -> hit the button 26 | * `cd test-git-phlow-plugin && git push origin --mirror -f && cd -` 27 | -------------------------------------------------------------------------------- /src/test/resources/EndUserTesting/jobs/test-FsExtAcc/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | 2 9 | 10 | 11 | git@github.com:bicschneider/test-git-phlow-plugin.git 12 | 13 | 14 | 15 | 16 | */readyFsExtAcc/* 17 | 18 | 19 | false 20 | 21 | 22 | 23 | masterFsExtAcc 24 | origin 25 | 26 | false 27 | 28 | 29 | 30 | 31 | 32 | true 33 | false 34 | false 35 | false 36 | 37 | 38 | * * * * * 39 | false 40 | 41 | 42 | false 43 | 44 | 45 | 46 | 47 | 48 | SUCCESS 49 | 0 50 | BLUE 51 | true 52 | 53 | 54 | SUCCESS 55 | 0 56 | BLUE 57 | true 58 | 59 | 60 | 61 | 62 | git log --graph --oneline -10 63 | 64 | if [ -e ./build_failed.md ]; then 65 | echo "BUILD FAILED" 66 | fi 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /src/test/resources/EndUserTesting/jobs/test-FsExtSq/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | 2 9 | 10 | 11 | git@github.com:bicschneider/test-git-phlow-plugin.git 12 | 13 | 14 | 15 | 16 | */readyFsExtSq/* 17 | 18 | 19 | false 20 | 21 | 22 | 23 | masterFsExtSq 24 | origin 25 | 26 | 27 | 28 | 29 | 30 | true 31 | false 32 | false 33 | false 34 | 35 | 36 | * * * * * 37 | false 38 | 39 | 40 | false 41 | 42 | 43 | 44 | 45 | 46 | SUCCESS 47 | 0 48 | BLUE 49 | true 50 | 51 | 52 | SUCCESS 53 | 0 54 | BLUE 55 | true 56 | 57 | 58 | 59 | 60 | git log --graph --oneline -10 61 | 62 | if [ -e ./build_failed.md ]; then 63 | echo "BUILD FAILED" 64 | fi 65 | 66 | 67 | 68 | 69 | 70 | 71 | BUILD FAILED 72 | false 73 | true 74 | true 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /src/test/resources/EndUserTesting/jobs/test-MuExtAcc/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | 2 9 | 10 | 11 | git@github.com:bicschneider/test-git-phlow-plugin.git 12 | 13 | 14 | 15 | 16 | */readyMuExtAcc/* 17 | 18 | 19 | false 20 | 21 | 22 | 23 | masterMuExtAcc 24 | origin 25 | 26 | 27 | 28 | 29 | 30 | true 31 | false 32 | false 33 | false 34 | 35 | 36 | * * * * * 37 | false 38 | 39 | 40 | false 41 | 42 | 43 | git log --oneline --decorate --graph -10 44 | 45 | 46 | 47 | 48 | 49 | 50 | SUCCESS 51 | 0 52 | BLUE 53 | true 54 | 55 | 56 | SUCCESS 57 | 0 58 | BLUE 59 | true 60 | 61 | 62 | 63 | 64 | if [ -e build_failed.md ]; then 65 | echo "BUILD FAILED" 66 | fi 67 | 68 | 69 | 70 | 71 | 72 | 73 | BUILD FAILED 74 | false 75 | true 76 | true 77 | 78 | 79 | 80 | 81 | false 82 | -------------------------------------------------------------------------------- /src/test/resources/EndUserTesting/jobs/test-MuExtSq/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | 2 9 | 10 | 11 | git@github.com:bicschneider/test-git-phlow-plugin.git 12 | 13 | 14 | 15 | 16 | */readyMuExtSq/* 17 | 18 | 19 | false 20 | 21 | 22 | 23 | masterMuExtSq 24 | origin 25 | 26 | 27 | 28 | 29 | 30 | true 31 | false 32 | false 33 | false 34 | 35 | 36 | * * * * * 37 | false 38 | 39 | 40 | false 41 | 42 | 43 | git log --oneline --decorate --graph -10 44 | 45 | 46 | 47 | 48 | 49 | 50 | SUCCESS 51 | 0 52 | BLUE 53 | true 54 | 55 | 56 | SUCCESS 57 | 0 58 | BLUE 59 | true 60 | 61 | 62 | 63 | 64 | if [ -e build_failed.md ]; then 65 | echo "BUILD FAILED" 66 | fi 67 | 68 | 69 | 70 | 71 | 72 | 73 | BUILD FAILED 74 | false 75 | true 76 | true 77 | 78 | 79 | 80 | 81 | false 82 | -------------------------------------------------------------------------------- /src/test/resources/EndUserTesting/jobs/test-MultiBranchPipePreSCM/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | All 15 | false 16 | false 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | false 27 | -1 28 | -1 29 | 30 | 31 | 32 | * * * * * 33 | 60000 34 | 35 | 36 | 37 | 38 | 39 | 40 | b45396c8-a7e2-4a3b-8d6c-83c64f1b8012 41 | git@github.com:bicschneider/test-git-phlow-plugin.git 42 | 43 | 44 | 45 | 46 | readyMultiBranchPipePreSCM/* 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /src/test/resources/EndUserTesting/jobs/test-MvnExtAcc/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | 2 9 | 10 | 11 | git@github.com:bicschneider/test-git-phlow-plugin.git 12 | d1fbf0b2-2804-4bf9-b9b8-70ce3e94f952 13 | 14 | 15 | 16 | 17 | */readyMvnExtAcc/* 18 | 19 | 20 | false 21 | 22 | 23 | 24 | 25 | 26 | 27 | true 28 | false 29 | false 30 | false 31 | 32 | 33 | * * * * * 34 | false 35 | 36 | 37 | false 38 | 39 | com.example 40 | java-maven-junit-helloworld 41 | 42 | java-maven-junit-helloworld/pom.xml 43 | compile 44 | true 45 | false 46 | true 47 | false 48 | false 49 | false 50 | false 51 | false 52 | false 53 | -1 54 | false 55 | false 56 | true 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | rm -rf java-maven-junit-helloworld 67 | git clone https://github.com/LableOrg/java-maven-junit-helloworld.git 68 | 69 | 70 | 71 | 72 | if [ -e ./build_failed.md ]; then 73 | exit 1 74 | fi 75 | 76 | 77 | 78 | 79 | FAILURE 80 | 2 81 | RED 82 | true 83 | 84 | -------------------------------------------------------------------------------- /src/test/resources/EndUserTesting/jobs/test-MxExtAcc/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | 2 9 | 10 | 11 | git@github.com:bicschneider/test-git-phlow-plugin.git 12 | 13 | 14 | 15 | 16 | */readyMxExtAcc/* 17 | 18 | 19 | false 20 | 21 | 22 | 23 | masterMxExtAcc 24 | origin 25 | 26 | 27 | 28 | 29 | 30 | 31 | origin 32 | masterMxExtAcc 33 | 34 | 35 | 36 | 37 | true 38 | false 39 | false 40 | false 41 | 42 | 43 | * * * * * 44 | false 45 | 46 | 47 | false 48 | 49 | 50 | test 51 | 52 | a 53 | b 54 | 55 | 56 | 57 | 58 | 59 | git log --graph --oneline --decorate -10 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | SUCCESS 68 | 0 69 | BLUE 70 | true 71 | 72 | 73 | SUCCESS 74 | 0 75 | BLUE 76 | true 77 | 78 | 79 | 80 | 81 | if [ -e build_failed.md ] ; then 82 | echo "BUILD FAILED" 83 | fi 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | false 94 | 95 | -------------------------------------------------------------------------------- /src/test/resources/EndUserTesting/jobs/test-MxExtSq/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | 2 9 | 10 | 11 | git@github.com:bicschneider/test-git-phlow-plugin.git 12 | 13 | 14 | 15 | 16 | */readyMxExtSq/* 17 | 18 | 19 | false 20 | 21 | 22 | 23 | masterMxExtSq 24 | origin 25 | 26 | 27 | 28 | 29 | 30 | 31 | true 32 | false 33 | false 34 | false 35 | 36 | 37 | * * * * * 38 | false 39 | 40 | 41 | false 42 | 43 | 44 | test 45 | 46 | a 47 | b 48 | 49 | 50 | 51 | 52 | 53 | git log --graph --oneline --decorate -10 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | SUCCESS 62 | 0 63 | BLUE 64 | true 65 | 66 | 67 | SUCCESS 68 | 0 69 | BLUE 70 | true 71 | 72 | 73 | 74 | 75 | if [ -e build_failed.md ] ; then 76 | echo "BUILD FAILED" 77 | fi 78 | 79 | 80 | 81 | 82 | 83 | 84 | BUILD FAILED 85 | false 86 | true 87 | true 88 | 89 | 90 | 91 | 92 | 93 | false 94 | 95 | -------------------------------------------------------------------------------- /src/test/resources/EndUserTesting/jobs/test-PipeDeclCheckoutSCM/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | 9 | 10 | * * * * * 11 | false 12 | 13 | 14 | 15 | 16 | 17 | 18 | 2 19 | 20 | 21 | git@github.com:bicschneider/test-git-phlow-plugin.git 22 | d1fbf0b2-2804-4bf9-b9b8-70ce3e94f952 23 | 24 | 25 | 26 | 27 | */readyPipeDeclCheckoutSCM/* 28 | 29 | 30 | false 31 | 32 | 33 | 34 | 35 | 36 | JenkinsfileDeclCheckoutSCM 37 | false 38 | 39 | false 40 | -------------------------------------------------------------------------------- /src/test/resources/EndUserTesting/jobs/test-PipeDeclPreSCM/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | 9 | 10 | * * * * * 11 | false 12 | 13 | 14 | 15 | 16 | 17 | 18 | 2 19 | 20 | 21 | git@github.com:bicschneider/test-git-phlow-plugin.git 22 | d1fbf0b2-2804-4bf9-b9b8-70ce3e94f952 23 | 24 | 25 | 26 | 27 | */readyPipeDeclPreSCM/* 28 | 29 | 30 | false 31 | 32 | 33 | 34 | masterPipeDeclPreSCM 35 | origin 36 | 37 | 38 | 39 | 40 | origin 41 | masterPipeDeclPreSCM 42 | 43 | 44 | 45 | 46 | 47 | JenkinsfileDeclPreSCM 48 | false 49 | 50 | false 51 | -------------------------------------------------------------------------------- /src/test/resources/EndUserTesting/jobs/test-PipeDeclScript/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | 9 | 10 | * * * * * 11 | false 12 | 13 | 14 | 15 | 16 | 17 | 64 | true 65 | 66 | -------------------------------------------------------------------------------- /src/test/resources/EndUserTesting/jobs/test-PipeScriptedCheckoutSCM/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | 9 | 10 | * * * * * 11 | false 12 | 13 | 14 | 15 | 16 | 17 | 18 | 2 19 | 20 | 21 | git@github.com:bicschneider/test-git-phlow-plugin.git 22 | 23 | 24 | 25 | 26 | */readyPipeScriptedCheckoutSCM/* 27 | 28 | 29 | false 30 | 31 | 32 | 33 | 34 | 35 | JenkinsfileScriptedCheckoutSCM 36 | false 37 | 38 | false 39 | -------------------------------------------------------------------------------- /src/test/resources/EndUserTesting/jobs/test-PipeScriptedPreSCM/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | 9 | 10 | * * * * * 11 | false 12 | 13 | 14 | 15 | 16 | 17 | 18 | 2 19 | 20 | 21 | git@github.com:bicschneider/test-git-phlow-plugin.git 22 | 23 | 24 | 25 | 26 | */readyPipeScriptedPreSCM/* 27 | 28 | 29 | false 30 | 31 | 32 | 33 | masterPipeScriptedPreSCM 34 | origin 35 | 36 | 37 | 38 | 39 | JenkinsfileScriptedPreSCM 40 | false 41 | 42 | false 43 | -------------------------------------------------------------------------------- /src/test/resources/EndUserTesting/jobs/test-PipeScriptedScript/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | 9 | 10 | * * * * * 11 | false 12 | 13 | 14 | 15 | 16 | 17 | 41 | true 42 | 43 | -------------------------------------------------------------------------------- /src/test/resources/JENKINS-28640.md: -------------------------------------------------------------------------------- 1 | # Test repository with commits for issue JENKINS-28640 2 | 3 | Problem is double quotes in commit messages, are wrongly escaped in commands. 4 | 5 | Issue [JENKINS-28640 Quotationmarks in commit message leads to merge failure](https://issues.jenkins-ci.org/browse/JENKINS-28640) report a possible bug, if using double quotes in a commit message. 6 | 7 | An earlier issue, namely the [JENKINS-27662](https://issues.jenkins-ci.org/browse/JENKINS-27662) didn't find such problems. It can be related to either our test environment or the way we created the commit messges in those test repositories used in the functional tests. 8 | 9 | 10 | This repository was created by one of the users of the plugin, a customer of Praqma, and supplies a test example that can reproduce the problem. 11 | 12 | There is no script for reproducing the repository, it was created under Windows. 13 | 14 | The repository have been converted to a bare git repository, to use it with the tests. 15 | -------------------------------------------------------------------------------- /src/test/resources/JENKINS-28640.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/pretested-integration-plugin/16c04bae14e55fec1a785c4b27f056a3479391cb/src/test/resources/JENKINS-28640.zip -------------------------------------------------------------------------------- /src/test/resources/commitMessagesWithDoubleQuotes.md: -------------------------------------------------------------------------------- 1 | # Commit message with double quotes 2 | 3 | Issue [JENKINS-27662](https://issues.jenkins-ci.org/browse/JENKINS-27662) report a possible bug, if using double quotes in a commit message. 4 | 5 | This repository is used for testing the scenario where a commit message contain double quotes. 6 | 7 | There are two repositories, one created on Linux and on created on Windows, to see if there are any platform dependent issues. 8 | 9 | Both script used, are almost identical but one is Bash shell and one is Windows batch script. 10 | 11 | Commands used to call the scripts: 12 | 13 | `./commitMessagesWithDoubleQuotes_linux.sh >> commitMessagesWithDoubleQuotes_linux.sh.log` 14 | 15 | `C:\Users\myuser\Documents>commitMessagesWithDoubleQuotes_windows.bat >> commitMessa 16 | gesWithDoubleQuotes_windows.bat.log` 17 | 18 | 19 | The linux version logged information about the git repo and commits in file `commitMessagesWithDoubleQuotes_linux-repo_description.log` which is seen below: 20 | 21 | ## Repository view and commits 22 | 23 | Git version: 24 | git version 1.9.1 25 | 26 | After initial commit on master: 27 | ------------------------------- 28 | 29 | * 116912c - (HEAD, master) Initial commit - added README (0 seconds ago) 30 | 31 | After the two commit on dev branch: 32 | ----------------------------------- 33 | 34 | * 57807c9 - (HEAD, origin/dev/JENKINS-27662_doublequotes, dev/JENKINS-27662_doublequotes) This is a commit message with double quotes, eg. "test quotes". (0 seconds ago) 35 | * 4ca68de - Added test commit log file (0 seconds ago) 36 | * 116912c - (origin/master, master) Initial commit - added README (0 seconds ago) 37 | 38 | Final repository, view dev branch after push to ready-branch: 39 | ------------------------------------------------------------------------------ 40 | 41 | * 57807c9 - (HEAD, origin/ready/JENKINS-27662_doublequotes, origin/dev/JENKINS-27662_doublequotes, dev/JENKINS-27662_doublequotes) This is a commit message with double quotes, eg. "test quotes". (0 seconds ago) 42 | * 4ca68de - Added test commit log file (0 seconds ago) 43 | * 116912c - (origin/master, master) Initial commit - added README (0 seconds ago) 44 | 45 | -------------------------------------------------------------------------------- /src/test/resources/commitMessagesWithDoubleQuotesSingleQuotesMade.md: -------------------------------------------------------------------------------- 1 | # Commit message with double quotes made with single quotes 2 | 3 | 4 | Issue [JENKINS-28640 Quotationmarks in commit message leads to merge failure](https://issues.jenkins-ci.org/browse/JENKINS-28640) report a possible bug, if using double quotes in a commit message. 5 | 6 | An earlier issue, namely the [JENKINS-27662](https://issues.jenkins-ci.org/browse/JENKINS-27662) didn't find such problems. It can be related to either our test environment or the way we created the commit messges in those test repositories used in the functional tests. 7 | 8 | 9 | A new set of test repositories have been created, but on different Windows environments for more variations. 10 | -------------------------------------------------------------------------------- /src/test/resources/commitMessagesWithDoubleQuotesSingleQuotesMade_linux-repo_description.log: -------------------------------------------------------------------------------- 1 | # Repository view and commits 2 | 3 | Git version: 4 | git version 1.9.1 5 | 6 | After initial commit on master: 7 | ------------------------------- 8 | * 97e8cea - (HEAD, master) Initial commit - added README (0 seconds ago)  9 | 10 | After the two commit on dev branch: 11 | ----------------------------------- 12 | * 7921dd6 - (HEAD, origin/dev/JENKINS-27662_doublequotes, dev/JENKINS-27662_doublequotes) This is a commit message with double quotes, and =, eg. "test quotes". (0 seconds ago)  13 | * 7d5b38a - Added test commit log file (0 seconds ago)  14 | * 97e8cea - (origin/master, master) Initial commit - added README (0 seconds ago)  15 | 16 | Final repository, view dev branch after push to ready-branch: 17 | ------------------------------------------------------------------------------ 18 | * 7921dd6 - (HEAD, origin/ready/JENKINS-27662_doublequotes, origin/dev/JENKINS-27662_doublequotes, dev/JENKINS-27662_doublequotes) This is a commit message with double quotes, and =, eg. "test quotes". (0 seconds ago)  19 | * 7d5b38a - Added test commit log file (0 seconds ago)  20 | * 97e8cea - (origin/master, master) Initial commit - added README (0 seconds ago)  21 | 22 | -------------------------------------------------------------------------------- /src/test/resources/commitMessagesWithDoubleQuotesSingleQuotesMade_linux.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # setting names and stuff 4 | if [ -z "$1" ]; then 5 | VERSION="" 6 | else 7 | VERSION="_$1" 8 | fi 9 | NAME=commitMessagesWithDoubleQuotesSingleQuotesMade_linux 10 | REPO_NAME=$NAME$VERSION # used for manual testing of script and re-runs 11 | WORK_DIR=`pwd` 12 | 13 | LOG=$WORK_DIR/$REPO_NAME-repo_description.log 14 | echo "# Repository view and commits" >> $LOG 15 | echo "" >> $LOG 16 | echo "Git version:" >> $LOG 17 | git --version >> $LOG 18 | echo "" >> $LOG 19 | 20 | 21 | mkdir -v $REPO_NAME.git 22 | cd $REPO_NAME.git 23 | git init --bare 24 | 25 | cd $WORK_DIR 26 | git clone $REPO_NAME.git 27 | cd $REPO_NAME 28 | git config user.name "Praqma Support" 29 | git config user.email "support@praqma.net" 30 | 31 | touch README.md 32 | echo "# README of repository $REPO_NAME" >> README.md 33 | echo "" >> README.md 34 | echo "This is a test repository for functional tests." >> README.md 35 | git add README.md 36 | git commit -m "Initial commit - added README" 37 | 38 | 39 | echo "After initial commit on master:" >> $LOG 40 | echo "-------------------------------" >> $LOG 41 | git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative >> $LOG 42 | echo "" >> $LOG 43 | echo "" >> $LOG 44 | 45 | git push origin master 46 | 47 | # custom parts 48 | BN=JENKINS-27662_doublequotes 49 | git checkout -b dev/$BN 50 | touch testCommit.log 51 | echo "# Test commit log" >> testCommit.log 52 | echo "" >> testCommit.log 53 | echo "Used for adding lines to commit something during tests.\n" >> testCommit.log 54 | git add testCommit.log 55 | git commit -m "Added test commit log file" 56 | 57 | # Problematic commit message with double quotes 58 | 59 | echo "Added a new line to this file, to commit something. Commit message will have double quotes" >> testCommit.log 60 | git add testCommit.log 61 | git commit -m 'This is a commit message with double quotes, and =, eg. "test quotes".' 62 | git push origin dev/$BN 63 | 64 | echo "After the two commit on dev branch:" >> $LOG 65 | echo "-----------------------------------" >> $LOG 66 | git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative >> $LOG 67 | echo "" >> $LOG 68 | echo "" >> $LOG 69 | 70 | # also push to ready branch, so integration can start during the test 71 | git push origin dev/$BN:ready/$BN 72 | 73 | echo "Final repository, view dev branch after push to ready-branch:" >> $LOG 74 | echo "------------------------------------------------------------------------------" >> $LOG 75 | git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative >> $LOG 76 | echo "" >> $LOG 77 | echo "" >> $LOG 78 | 79 | # Post process 80 | 81 | cd $WORK_DIR 82 | zip -r $NAME$VERSION.zip $REPO_NAME.git 83 | rm -rf $REPO_NAME.git $REPO_NAME 84 | 85 | -------------------------------------------------------------------------------- /src/test/resources/commitMessagesWithDoubleQuotesSingleQuotesMade_linux.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/pretested-integration-plugin/16c04bae14e55fec1a785c4b27f056a3479391cb/src/test/resources/commitMessagesWithDoubleQuotesSingleQuotesMade_linux.zip -------------------------------------------------------------------------------- /src/test/resources/commitMessagesWithDoubleQuotesSingleQuotesMade_windows.bat: -------------------------------------------------------------------------------- 1 | @echo on 2 | 3 | SET NAME=commitMessagesWithDoubleQuotesSingleQuotesMade_windows 4 | SET REPO_NAME=commitMessagesWithDoubleQuotesSingleQuotesMade_windows 5 | SET WORK_DIR=%~dp0 6 | 7 | 8 | REM pre-process 9 | 10 | mkdir %REPO_NAME%.git 11 | cd %REPO_NAME%.git 12 | git init --bare 13 | 14 | cd %WORK_DIR% 15 | git clone %REPO_NAME%.git 16 | cd %REPO_NAME% 17 | git config user.name "Praqma Support" 18 | git config user.email "support@praqma.net" 19 | 20 | 21 | touch README.md 22 | echo "# README of repository $REPO_NAME" >> README.md 23 | echo "" >> README.md 24 | echo "This is a test repository for functional tests." >> README.md 25 | git add README.md 26 | git commit -m "Initial commit - added README" 27 | 28 | 29 | git push origin master 30 | 31 | REM custom parts 32 | 33 | SET BN=JENKINS-27662_doublequotes 34 | git checkout -b dev/%BN% 35 | touch testCommit.log 36 | echo "# Test commit log" >> testCommit.log 37 | echo "" >> testCommit.log 38 | echo "Used for adding lines to commit something during tests.\n" >> testCommit.log 39 | git add testCommit.log 40 | git commit -m "Added test commit log file" 41 | 42 | REM Problematic commit message with double quotes 43 | 44 | echo "Added a new line to this file, to commit something. Commit message will have double quotes" >> testCommit.log 45 | git add testCommit.log 46 | git commit -m 'This is a commit message with double quotes (commit made on Windows), and =, eg. "test quotes".' 47 | git push origin dev/%BN% 48 | 49 | REM also push to ready branch, so integration can start during the test 50 | 51 | git push origin dev/%BN%:ready/%BN% 52 | git remote -v show 53 | 54 | REM Post process 55 | 56 | cd %WORK_DIR% 57 | 7z a -r %NAME%%VERSION%.zip %REPO_NAME%.git 58 | 59 | rmdir /S /Q %REPO_NAME%.git 60 | del /Q %REPO_NAME% 61 | rmdir /S /Q %REPO_NAME% 62 | -------------------------------------------------------------------------------- /src/test/resources/commitMessagesWithDoubleQuotesSingleQuotesMade_windows.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/pretested-integration-plugin/16c04bae14e55fec1a785c4b27f056a3479391cb/src/test/resources/commitMessagesWithDoubleQuotesSingleQuotesMade_windows.zip -------------------------------------------------------------------------------- /src/test/resources/commitMessagesWithDoubleQuotes_linux-repo_description.log: -------------------------------------------------------------------------------- 1 | # Repository view and commits 2 | 3 | Git version: 4 | git version 1.9.1 5 | 6 | After initial commit on master: 7 | ------------------------------- 8 | * 116912c - (HEAD, master) Initial commit - added README (0 seconds ago)  9 | 10 | After the two commit on dev branch: 11 | ----------------------------------- 12 | * 57807c9 - (HEAD, origin/dev/JENKINS-27662_doublequotes, dev/JENKINS-27662_doublequotes) This is a commit message with double quotes, eg. "test quotes". (0 seconds ago)  13 | * 4ca68de - Added test commit log file (0 seconds ago)  14 | * 116912c - (origin/master, master) Initial commit - added README (0 seconds ago)  15 | 16 | Final repository, view dev branch after push to ready-branch: 17 | ------------------------------------------------------------------------------ 18 | * 57807c9 - (HEAD, origin/ready/JENKINS-27662_doublequotes, origin/dev/JENKINS-27662_doublequotes, dev/JENKINS-27662_doublequotes) This is a commit message with double quotes, eg. "test quotes". (0 seconds ago)  19 | * 4ca68de - Added test commit log file (0 seconds ago)  20 | * 116912c - (origin/master, master) Initial commit - added README (0 seconds ago)  21 | 22 | -------------------------------------------------------------------------------- /src/test/resources/commitMessagesWithDoubleQuotes_linux.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # setting names and stuff 4 | if [ -z "$1" ]; then 5 | VERSION="" 6 | else 7 | VERSION="_$1" 8 | fi 9 | NAME=commitMessagesWithDoubleQuotes_linux 10 | REPO_NAME=$NAME$VERSION # used for manual testing of script and re-runs 11 | WORK_DIR=`pwd` 12 | 13 | LOG=$WORK_DIR/$REPO_NAME-repo_description.log 14 | echo "# Repository view and commits" >> $LOG 15 | echo "" >> $LOG 16 | echo "Git version:" >> $LOG 17 | git --version >> $LOG 18 | echo "" >> $LOG 19 | 20 | 21 | mkdir -v $REPO_NAME.git 22 | cd $REPO_NAME.git 23 | git init --bare 24 | 25 | cd $WORK_DIR 26 | git clone $REPO_NAME.git 27 | cd $REPO_NAME 28 | git config user.name "Praqma Support" 29 | git config user.email "support@praqma.net" 30 | 31 | touch README.md 32 | echo "# README of repository $REPO_NAME" >> README.md 33 | echo "" >> README.md 34 | echo "This is a test repository for functional tests." >> README.md 35 | git add README.md 36 | git commit -m "Initial commit - added README" 37 | 38 | 39 | echo "After initial commit on master:" >> $LOG 40 | echo "-------------------------------" >> $LOG 41 | git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative >> $LOG 42 | echo "" >> $LOG 43 | echo "" >> $LOG 44 | 45 | git push origin master 46 | 47 | # custom parts 48 | BN=JENKINS-27662_doublequotes 49 | git checkout -b dev/$BN 50 | touch testCommit.log 51 | echo "# Test commit log" >> testCommit.log 52 | echo "" >> testCommit.log 53 | echo "Used for adding lines to commit something during tests.\n" >> testCommit.log 54 | git add testCommit.log 55 | git commit -m "Added test commit log file" 56 | 57 | # Problematic commit message with double quotes 58 | 59 | echo "Added a new line to this file, to commit something. Commit message will have double quotes" >> testCommit.log 60 | git add testCommit.log 61 | git commit -m 'This is a commit message with double quotes, eg. "test quotes".' 62 | git push origin dev/$BN 63 | 64 | echo "After the two commit on dev branch:" >> $LOG 65 | echo "-----------------------------------" >> $LOG 66 | git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative >> $LOG 67 | echo "" >> $LOG 68 | echo "" >> $LOG 69 | 70 | # also push to ready branch, so integration can start during the test 71 | git push origin dev/$BN:ready/$BN 72 | 73 | echo "Final repository, view dev branch after push to ready-branch:" >> $LOG 74 | echo "------------------------------------------------------------------------------" >> $LOG 75 | git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative >> $LOG 76 | echo "" >> $LOG 77 | echo "" >> $LOG 78 | 79 | # Post process 80 | 81 | cd $WORK_DIR 82 | zip -r $NAME$VERSION.zip $REPO_NAME.git 83 | rm -rf $REPO_NAME.git $REPO_NAME 84 | 85 | -------------------------------------------------------------------------------- /src/test/resources/commitMessagesWithDoubleQuotes_linux.sh.log: -------------------------------------------------------------------------------- 1 | mkdir: created directory ‘commitMessagesWithDoubleQuotes_linux.git’ 2 | Initialized empty Git repository in /home/bue/gitlab-repos/github/pretested-integration-plugin/src/test/resources/commitMessagesWithDoubleQuotes_linux.git/ 3 | [master (root-commit) 2f2c873] Initial commit - added README 4 | 1 file changed, 3 insertions(+) 5 | create mode 100644 README.md 6 | [dev/JENKINS-27662_doublequotes ca7160d] Added test commit log file 7 | 1 file changed, 3 insertions(+) 8 | create mode 100644 testCommit.log 9 | [dev/JENKINS-27662_doublequotes 13523b0] This is a commit message with double quotes, eg. "test quotes". 10 | 1 file changed, 1 insertion(+) 11 | mkdir: created directory ‘commitMessagesWithDoubleQuotes_linux.git’ 12 | Initialized empty Git repository in /home/bue/gitlab-repos/github/pretested-integration-plugin/src/test/resources/commitMessagesWithDoubleQuotes_linux.git/ 13 | [master (root-commit) 116912c] Initial commit - added README 14 | 1 file changed, 3 insertions(+) 15 | create mode 100644 README.md 16 | [dev/JENKINS-27662_doublequotes 4ca68de] Added test commit log file 17 | 1 file changed, 3 insertions(+) 18 | create mode 100644 testCommit.log 19 | [dev/JENKINS-27662_doublequotes 57807c9] This is a commit message with double quotes, eg. "test quotes". 20 | 1 file changed, 1 insertion(+) 21 | adding: commitMessagesWithDoubleQuotes_linux.git/ (stored 0%) 22 | adding: commitMessagesWithDoubleQuotes_linux.git/branches/ (stored 0%) 23 | adding: commitMessagesWithDoubleQuotes_linux.git/config (deflated 11%) 24 | adding: commitMessagesWithDoubleQuotes_linux.git/info/ (stored 0%) 25 | adding: commitMessagesWithDoubleQuotes_linux.git/info/exclude (deflated 28%) 26 | adding: commitMessagesWithDoubleQuotes_linux.git/HEAD (stored 0%) 27 | adding: commitMessagesWithDoubleQuotes_linux.git/objects/ (stored 0%) 28 | adding: commitMessagesWithDoubleQuotes_linux.git/objects/60/ (stored 0%) 29 | adding: commitMessagesWithDoubleQuotes_linux.git/objects/60/8dde79ba00fba3e54ffdad6bc7d6022080fce4 (stored 0%) 30 | adding: commitMessagesWithDoubleQuotes_linux.git/objects/ce/ (stored 0%) 31 | adding: commitMessagesWithDoubleQuotes_linux.git/objects/ce/057c3522f9730756425c4b967eee724dea2d50 (stored 0%) 32 | adding: commitMessagesWithDoubleQuotes_linux.git/objects/pack/ (stored 0%) 33 | adding: commitMessagesWithDoubleQuotes_linux.git/objects/11/ (stored 0%) 34 | adding: commitMessagesWithDoubleQuotes_linux.git/objects/11/6912cf24208b02c33e3cff8b8287eb9014499c (stored 0%) 35 | adding: commitMessagesWithDoubleQuotes_linux.git/objects/a9/ (stored 0%) 36 | adding: commitMessagesWithDoubleQuotes_linux.git/objects/a9/2bdebb90d01823a028ed83f889df7938f0a202 (stored 0%) 37 | adding: commitMessagesWithDoubleQuotes_linux.git/objects/info/ (stored 0%) 38 | adding: commitMessagesWithDoubleQuotes_linux.git/objects/df/ (stored 0%) 39 | adding: commitMessagesWithDoubleQuotes_linux.git/objects/df/bb4a6c8d8640e8c119f5929abc6fa371a98c83 (stored 0%) 40 | adding: commitMessagesWithDoubleQuotes_linux.git/objects/4c/ (stored 0%) 41 | adding: commitMessagesWithDoubleQuotes_linux.git/objects/4c/a68de437d106b6600bef36d6887c8527275652 (stored 0%) 42 | adding: commitMessagesWithDoubleQuotes_linux.git/objects/57/ (stored 0%) 43 | adding: commitMessagesWithDoubleQuotes_linux.git/objects/57/807c99bea0fa0f929bd32973ff9651f7c0fb04 (stored 0%) 44 | adding: commitMessagesWithDoubleQuotes_linux.git/objects/92/ (stored 0%) 45 | adding: commitMessagesWithDoubleQuotes_linux.git/objects/92/38465f075bf23d9b3a2d3891f06a10084e3754 (stored 0%) 46 | adding: commitMessagesWithDoubleQuotes_linux.git/objects/b8/ (stored 0%) 47 | adding: commitMessagesWithDoubleQuotes_linux.git/objects/b8/6137600f45e0173bdce39e7954005295118ab1 (stored 0%) 48 | adding: commitMessagesWithDoubleQuotes_linux.git/description (deflated 14%) 49 | adding: commitMessagesWithDoubleQuotes_linux.git/hooks/ (stored 0%) 50 | adding: commitMessagesWithDoubleQuotes_linux.git/hooks/applypatch-msg.sample (deflated 41%) 51 | adding: commitMessagesWithDoubleQuotes_linux.git/hooks/pre-rebase.sample (deflated 59%) 52 | adding: commitMessagesWithDoubleQuotes_linux.git/hooks/pre-applypatch.sample (deflated 36%) 53 | adding: commitMessagesWithDoubleQuotes_linux.git/hooks/update.sample (deflated 68%) 54 | adding: commitMessagesWithDoubleQuotes_linux.git/hooks/pre-push.sample (deflated 50%) 55 | adding: commitMessagesWithDoubleQuotes_linux.git/hooks/prepare-commit-msg.sample (deflated 46%) 56 | adding: commitMessagesWithDoubleQuotes_linux.git/hooks/pre-commit.sample (deflated 43%) 57 | adding: commitMessagesWithDoubleQuotes_linux.git/hooks/commit-msg.sample (deflated 44%) 58 | adding: commitMessagesWithDoubleQuotes_linux.git/hooks/post-update.sample (deflated 27%) 59 | adding: commitMessagesWithDoubleQuotes_linux.git/refs/ (stored 0%) 60 | adding: commitMessagesWithDoubleQuotes_linux.git/refs/tags/ (stored 0%) 61 | adding: commitMessagesWithDoubleQuotes_linux.git/refs/heads/ (stored 0%) 62 | adding: commitMessagesWithDoubleQuotes_linux.git/refs/heads/ready/ (stored 0%) 63 | adding: commitMessagesWithDoubleQuotes_linux.git/refs/heads/ready/JENKINS-27662_doublequotes (stored 0%) 64 | adding: commitMessagesWithDoubleQuotes_linux.git/refs/heads/dev/ (stored 0%) 65 | adding: commitMessagesWithDoubleQuotes_linux.git/refs/heads/dev/JENKINS-27662_doublequotes (stored 0%) 66 | adding: commitMessagesWithDoubleQuotes_linux.git/refs/heads/master (stored 0%) 67 | -------------------------------------------------------------------------------- /src/test/resources/commitMessagesWithDoubleQuotes_linux.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/pretested-integration-plugin/16c04bae14e55fec1a785c4b27f056a3479391cb/src/test/resources/commitMessagesWithDoubleQuotes_linux.zip -------------------------------------------------------------------------------- /src/test/resources/commitMessagesWithDoubleQuotes_windows.bat: -------------------------------------------------------------------------------- 1 | @echo on 2 | 3 | SET NAME=commitMessagesWithDoubleQuotes_windows 4 | SET REPO_NAME=commitMessagesWithDoubleQuotes_windows 5 | SET WORK_DIR=%~dp0 6 | 7 | 8 | REM pre-process 9 | 10 | mkdir %REPO_NAME%.git 11 | cd %REPO_NAME%.git 12 | git init --bare 13 | 14 | cd %WORK_DIR% 15 | git clone %REPO_NAME%.git 16 | cd %REPO_NAME% 17 | git config user.name "Praqma Support" 18 | git config user.email "support@praqma.net" 19 | 20 | 21 | touch README.md 22 | echo "# README of repository $REPO_NAME" >> README.md 23 | echo "" >> README.md 24 | echo "This is a test repository for functional tests." >> README.md 25 | git add README.md 26 | git commit -m "Initial commit - added README" 27 | 28 | 29 | git push origin master 30 | 31 | REM custom parts 32 | 33 | SET BN=JENKINS-27662_doublequotes 34 | git checkout -b dev/%BN% 35 | touch testCommit.log 36 | echo "# Test commit log" >> testCommit.log 37 | echo "" >> testCommit.log 38 | echo "Used for adding lines to commit something during tests.\n" >> testCommit.log 39 | git add testCommit.log 40 | git commit -m "Added test commit log file" 41 | 42 | REM Problematic commit message with double quotes 43 | 44 | echo "Added a new line to this file, to commit something. Commit message will have double quotes" >> testCommit.log 45 | git add testCommit.log 46 | git commit -m "This is a commit message with double quotes (commit made on Windows), eg. \"test quotes\"." 47 | git push origin dev/%BN% 48 | 49 | REM also push to ready branch, so integration can start during the test 50 | 51 | git push origin dev/%BN%:ready/%BN% 52 | git remote -v show 53 | 54 | REM Post process 55 | 56 | cd %WORK_DIR% 57 | 7z a -r %NAME%%VERSION%.zip %REPO_NAME%.git 58 | 59 | rmdir /S /Q %REPO_NAME%.git 60 | del /Q %REPO_NAME% 61 | rmdir /S /Q %REPO_NAME% 62 | -------------------------------------------------------------------------------- /src/test/resources/commitMessagesWithDoubleQuotes_windows.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/pretested-integration-plugin/16c04bae14e55fec1a785c4b27f056a3479391cb/src/test/resources/commitMessagesWithDoubleQuotes_windows.zip -------------------------------------------------------------------------------- /src/test/resources/customIntegrationBranch.md: -------------------------------------------------------------------------------- 1 | # Test repository description for custom integration branch tests 2 | 3 | 4 | Related to [JENKINS-28596 Hardcoded branch name when resolving commit messages](https://issues.jenkins-ci.org/browse/JENKINS-28596) we have created the _customIntegrationBranch_ test repository for testing the use case where the plugin is configured to integrate development branch changed on the custom integration branch - that is something else than master. 5 | 6 | 7 | See the log-file `customIntegrationBranch-repo_description.log` for details on the repository. 8 | -------------------------------------------------------------------------------- /src/test/resources/customIntegrationBranch.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/pretested-integration-plugin/16c04bae14e55fec1a785c4b27f056a3479391cb/src/test/resources/customIntegrationBranch.zip -------------------------------------------------------------------------------- /src/test/resources/useAuthorOfLastCommit-repo_description.log: -------------------------------------------------------------------------------- 1 | # Repository view and commits 2 | 3 | Git version: 4 | git version 1.9.1 5 | 6 | Linux: 7 | Linux orange-one 3.13.0-49-generic #83-Ubuntu SMP Fri Apr 10 20:11:33 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux 8 | LSB Version: core-2.0-amd64:core-2.0-noarch:core-3.0-amd64:core-3.0-noarch:core-3.1-amd64:core-3.1-noarch:core-3.2-amd64:core-3.2-noarch:core-4.0-amd64:core-4.0-noarch:core-4.1-amd64:core-4.1-noarch:security-4.0-amd64:security-4.0-noarch:security-4.1-amd64:security-4.1-noarch 9 | 10 | After initial commit on master: 11 | ------------------------------- 12 | --- git log graph: --- 13 | * d7743e8 - (HEAD, master) Initial commit - added README (0 seconds ago)  14 | 15 | --- git log one-liner: --- 16 | * 139036a (Author: Praqma Support ) (Committer: Praqma Support ): Initial commit - added README 17 | 18 | After the two commits on the branch: 19 | ----------------------------------- 20 | git log one-liner: 21 | 2264699 (Author: Praqma Support Author Two ) (Committer Praqma Support Author Two ): Added test commit log file - second commit by 'Praqma Support Author Two' 22 | fe02308 (Author: Praqma Support Author One ) (Committer Praqma Support Author One ): Added test commit log file - first commit by 'Praqma Support Author One' 23 | 139036a (Author: Praqma Support ) (Committer Praqma Support ): Initial commit - added README--- git log graph: --- 24 | * a1b88be - (HEAD, twoCommitsBranch) Added test commit log file - second commit by 'Praqma Support Author Two' (0 seconds ago)  25 | * 0174ae0 - Added test commit log file - first commit by 'Praqma Support Author One' (0 seconds ago)  26 | * d7743e8 - (origin/master, master) Initial commit - added README (0 seconds ago)  27 | 28 | --- git log one-liner: --- 29 | * 2264699 (Author: Praqma Support Author Two ) (Committer: Praqma Support Author Two ): Added test commit log file - second commit by 'Praqma Support Author Two' 30 | * fe02308 (Author: Praqma Support Author One ) (Committer: Praqma Support Author One ): Added test commit log file - first commit by 'Praqma Support Author One' 31 | * 139036a (Author: Praqma Support ) (Committer: Praqma Support ): Initial commit - added README 32 | 33 | Final repository, view after push to ready-branch: 34 | ----------------------------------- 35 | git log one-liner: 36 | 2264699 (Author: Praqma Support Author Two ) (Committer Praqma Support Author Two ): Added test commit log file - second commit by 'Praqma Support Author Two' 37 | fe02308 (Author: Praqma Support Author One ) (Committer Praqma Support Author One ): Added test commit log file - first commit by 'Praqma Support Author One' 38 | 139036a (Author: Praqma Support ) (Committer Praqma Support ): Initial commit - added README--- git log graph: --- 39 | * a1b88be - (HEAD, origin/ready/twoCommitsBranch, twoCommitsBranch) Added test commit log file - second commit by 'Praqma Support Author Two' (0 seconds ago)  40 | * 0174ae0 - Added test commit log file - first commit by 'Praqma Support Author One' (0 seconds ago)  41 | * d7743e8 - (origin/master, master) Initial commit - added README (0 seconds ago)  42 | 43 | --- git log one-liner: --- 44 | * 2264699 (Author: Praqma Support Author Two ) (Committer: Praqma Support Author Two ): Added test commit log file - second commit by 'Praqma Support Author Two' 45 | * fe02308 (Author: Praqma Support Author One ) (Committer: Praqma Support Author One ): Added test commit log file - first commit by 'Praqma Support Author One' 46 | * 139036a (Author: Praqma Support ) (Committer: Praqma Support ): Initial commit - added README 47 | 48 | -------------------------------------------------------------------------------- /src/test/resources/useAuthorOfLastCommit.md: -------------------------------------------------------------------------------- 1 | # Integration commit must have author of last commit 2 | 3 | _Test repository for the following feature_: 4 | 5 | Both accumulated and squashed strategy sets both committer and author to the git user on the Jenkins slave. 6 | 7 | The author on the commits on the development branch should be kept, as the author on the new commit on the integration branch. 8 | This follows the well know pull-request patterns of many OSS project, where the maintainer accepts the pull requests and becomes the commiter, while the original author doing the work get credit as author. 9 | 10 | The usual repository browser shows author of commits, thus the history in such systems will be more interesting when looking over the git history. Today it is the git user on the Jenkins slave showing as both committer and author. 11 | 12 | * if there is more than one commit on the ready branch, the author of the last commit will be used. 13 | 14 | 15 | * https://issues.jenkins-ci.org/browse/JENKINS-28590 16 | 17 | 18 | The test repositories uses different commit authors when creating the repository, thus the tests can verify that the correct author is used when integrating. 19 | -------------------------------------------------------------------------------- /src/test/resources/useAuthorOfLastCommit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # setting names and stuff 4 | if [ -z "$1" ]; then 5 | VERSION="" 6 | else 7 | VERSION="_$1" 8 | fi 9 | NAME=useAuthorOfLastCommit 10 | REPO_NAME=$NAME$VERSION # used for manual testing of script and re-runs 11 | WORK_DIR=`pwd` 12 | 13 | LOG=$WORK_DIR/$REPO_NAME-repo_description.log 14 | echo "# Repository view and commits" >> $LOG 15 | echo "" >> $LOG 16 | echo "Git version:" >> $LOG 17 | git --version >> $LOG 18 | echo "" >> $LOG 19 | echo "Linux:" >> $LOG 20 | uname -a >> $LOG 21 | lsb_release >> $LOG 22 | echo "" >> $LOG 23 | 24 | mkdir -v $REPO_NAME.git 25 | cd $REPO_NAME.git 26 | git init --bare 27 | 28 | cd $WORK_DIR 29 | git clone $REPO_NAME.git 30 | cd $REPO_NAME 31 | git config user.name "Praqma Support" 32 | git config user.email "support@praqma.net" 33 | 34 | touch README.md 35 | echo "# README of repository $REPO_NAME" >> README.md 36 | echo "" >> README.md 37 | echo "This is a test repository for functional tests." >> README.md 38 | git add README.md 39 | git commit -m "Initial commit - added README" 40 | 41 | 42 | echo "After initial commit on master:" >> $LOG 43 | echo "-------------------------------" >> $LOG 44 | echo "--- git log graph: ---" >> $LOG 45 | git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative >> $LOG 46 | echo "" >> $LOG 47 | echo "" >> $LOG 48 | echo "--- git log one-liner: ---" >> $LOG 49 | git log --pretty=format:" * %t (Author: %an <%ae>) (Committer: %cn <%ce>): %s" >> $LOG 50 | echo "" >> $LOG 51 | echo "" >> $LOG 52 | 53 | git push origin master 54 | 55 | # Doing two commits - each with different author 56 | BN=twoCommitsBranch 57 | git checkout -b $BN 58 | 59 | git config user.name "Praqma Support Author One" 60 | git config user.email "support@praqma.net" 61 | 62 | touch testCommit.log 63 | echo "# Test commit log" >> testCommit.log 64 | echo "" >> testCommit.log 65 | echo "Used for adding lines to easily commit something during tests. Commit is done by 'Praqma Support Author One'\n" >> testCommit.log 66 | git add testCommit.log 67 | git commit -m "Added test commit log file - first commit by 'Praqma Support Author One'" 68 | 69 | git config user.name "Praqma Support Author Two" 70 | git config user.email "support@praqma.net" 71 | 72 | touch testCommit.log 73 | echo "Added a new line to this file, to commit something. Commit is done by 'Praqma Support Author Two'\n" >> testCommit.log 74 | git add testCommit.log 75 | git commit -m "Added test commit log file - second commit by 'Praqma Support Author Two'" 76 | 77 | echo "After the two commits on the branch:" >> $LOG 78 | echo "-----------------------------------" >> $LOG 79 | echo "git log one-liner:" >> $LOG 80 | git log --pretty=format:"%t (Author: %an <%ae>) (Committer %cn <%ce>): %s" >> $LOG 81 | echo "--- git log graph: ---" >> $LOG 82 | git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative >> $LOG 83 | echo "" >> $LOG 84 | echo "" >> $LOG 85 | echo "--- git log one-liner: ---" >> $LOG 86 | git log --pretty=format:" * %t (Author: %an <%ae>) (Committer: %cn <%ce>): %s" >> $LOG 87 | echo "" >> $LOG 88 | echo "" >> $LOG 89 | 90 | # also push to ready branch, so integration can start during the test 91 | git push origin $BN:ready/$BN 92 | 93 | echo "Final repository, view after push to ready-branch:" >> $LOG 94 | echo "-----------------------------------" >> $LOG 95 | echo "git log one-liner:" >> $LOG 96 | git log --pretty=format:"%t (Author: %an <%ae>) (Committer %cn <%ce>): %s" >> $LOG 97 | echo "--- git log graph: ---" >> $LOG 98 | git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative >> $LOG 99 | echo "" >> $LOG 100 | echo "" >> $LOG 101 | echo "--- git log one-liner: ---" >> $LOG 102 | git log --pretty=format:" * %t (Author: %an <%ae>) (Committer: %cn <%ce>): %s" >> $LOG 103 | echo "" >> $LOG 104 | echo "" >> $LOG 105 | 106 | # Post process 107 | 108 | cd $WORK_DIR 109 | zip -r $NAME$VERSION.zip $REPO_NAME.git 110 | rm -rf $REPO_NAME.git $REPO_NAME 111 | 112 | -------------------------------------------------------------------------------- /src/test/resources/useAuthorOfLastCommit.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/pretested-integration-plugin/16c04bae14e55fec1a785c4b27f056a3479391cb/src/test/resources/useAuthorOfLastCommit.zip --------------------------------------------------------------------------------