├── docs ├── docinfo.html ├── crawler.png ├── favicon.ico ├── spinnaker.png ├── images │ ├── forkme.png │ ├── demo │ │ ├── demo.png │ │ ├── demo_alerting.png │ │ └── demo_metrics.png │ ├── intro │ │ ├── how.png │ │ ├── build.png │ │ ├── flow.png │ │ ├── prod.png │ │ ├── stage.png │ │ ├── test.png │ │ ├── monolith.png │ │ ├── no_e2e_tests.png │ │ ├── flow_concourse.png │ │ ├── many_microservices.png │ │ └── stubbed_dependencies.png │ ├── iconsprite.png │ ├── jenkins │ │ ├── git.png │ │ ├── jdk.png │ │ ├── blue_1.png │ │ ├── blue_2.png │ │ ├── blue_3.png │ │ ├── blue_4.png │ │ ├── blue_5.png │ │ ├── blue_6.png │ │ ├── blue_7.png │ │ ├── seed.png │ │ ├── env_vars.png │ │ ├── pks_seed.png │ │ ├── seed_run.png │ │ ├── credentials.png │ │ ├── global_tool.png │ │ ├── jenkinsfile.png │ │ ├── kubo_token.png │ │ ├── seed_built.png │ │ ├── seed_click.png │ │ ├── seed_views.png │ │ ├── groovy_token.png │ │ ├── pipeline_run.png │ │ ├── configure_system.png │ │ ├── credentials_add.png │ │ ├── jdk_installation.png │ │ ├── kubo_credentials.png │ │ ├── kubo_update_git.png │ │ ├── manage_jenkins.png │ │ ├── pipeline_manual.png │ │ ├── credentials_global.png │ │ ├── credentials_system.png │ │ ├── pipeline_finished.png │ │ ├── pipeline_run_props.png │ │ ├── credentials_example.png │ │ ├── kubo_script_console_1.png │ │ └── kubo_script_console_2.png │ └── spring-logo.png ├── docinfo-footer.html ├── js │ ├── tocbot │ │ └── tocbot.css │ └── highlight │ │ └── styles │ │ ├── monokai.min.css │ │ ├── zenburn.min.css │ │ ├── dracula.min.css │ │ ├── monokai-sublime.min.css │ │ ├── solarized-light.min.css │ │ ├── an-old-hope.min.css │ │ ├── github.min.css │ │ ├── atom-one-dark.min.css │ │ ├── atom-one-light.min.css │ │ ├── atom-one-dark-reasonable.min.css │ │ └── a11y-dark.min.css ├── DEMO_SETUP.html └── JENKINS_RUN_SEED.html ├── demo ├── .gitignore ├── seed │ ├── k8s │ │ └── .gitignore │ └── settings.xml ├── stop.sh ├── whats_my_ip.sh ├── Dockerfile-artifactory ├── docker-compose.yml ├── src │ └── test │ │ └── groovy │ │ └── io │ │ └── cloudpipelines │ │ └── SingleScriptPipelineSpec.groovy ├── start.sh ├── build.gradle └── artifactory.config.import.yml ├── job-dsl ├── src │ ├── main │ │ ├── resources │ │ │ └── .gitkeep │ │ ├── bash │ │ │ └── steps │ │ │ │ ├── stage_e2e.sh │ │ │ │ ├── test_smoke.sh │ │ │ │ ├── prod_deploy.sh │ │ │ │ ├── stage_deploy.sh │ │ │ │ ├── test_deploy.sh │ │ │ │ ├── prod_complete.sh │ │ │ │ ├── prod_rollback.sh │ │ │ │ ├── prod_remove_prod_tag.sh │ │ │ │ ├── test_rollback_deploy.sh │ │ │ │ ├── test_rollback_smoke.sh │ │ │ │ ├── test_prepare.sh │ │ │ │ ├── stage_prepare.sh │ │ │ │ └── download_latest_prod_binary.sh │ │ └── groovy │ │ │ └── io │ │ │ └── cloudpipelines │ │ │ ├── spinnaker │ │ │ ├── pipeline │ │ │ │ ├── model │ │ │ │ │ ├── PayloadConstraints.groovy │ │ │ │ │ ├── AppConfig.groovy │ │ │ │ │ ├── StageEnabled.groovy │ │ │ │ │ ├── Capacity.groovy │ │ │ │ │ ├── cf │ │ │ │ │ │ ├── ListOfCloudFoundryManifest.groovy │ │ │ │ │ │ └── CloudFoundryManifest.groovy │ │ │ │ │ ├── Artifact.groovy │ │ │ │ │ ├── Root.groovy │ │ │ │ │ ├── Manifest.groovy │ │ │ │ │ ├── Cluster.groovy │ │ │ │ │ ├── Trigger.groovy │ │ │ │ │ └── Stage.groovy │ │ │ │ └── steps │ │ │ │ │ ├── ProdSetTag.groovy │ │ │ │ │ └── ProdRemoveTag.groovy │ │ │ ├── SpinnakerDefaults.groovy │ │ │ └── SpinnakerDefaultView.groovy │ │ │ ├── common │ │ │ ├── RepoType.groovy │ │ │ ├── GeneratedJobs.groovy │ │ │ ├── PipelineJobsFactoryProvider.groovy │ │ │ ├── PipelineJobsFactory.groovy │ │ │ ├── JobCustomizer.groovy │ │ │ ├── BashFunctions.groovy │ │ │ ├── PipelineDescriptor.groovy │ │ │ ├── StepEnabledChecker.groovy │ │ │ └── Coordinates.groovy │ │ │ ├── test │ │ │ └── TestUtils.groovy │ │ │ ├── steps │ │ │ ├── CreatedJob.groovy │ │ │ ├── Step.groovy │ │ │ ├── ProdRollback.groovy │ │ │ ├── StageTest.groovy │ │ │ ├── ProdComplete.groovy │ │ │ ├── ProdDeploy.groovy │ │ │ ├── TestDeployLatestProdVersion.groovy │ │ │ ├── TestTest.groovy │ │ │ ├── TestRollbackTest.groovy │ │ │ └── TestDeploy.groovy │ │ │ └── default_pipeline │ │ │ ├── DefaultPipelineDefaults.groovy │ │ │ └── DefaultView.groovy │ └── test │ │ ├── resources │ │ ├── META-INF │ │ │ └── services │ │ │ │ └── io.cloudpipelines.common.JobCustomizer │ │ ├── cloudpipelines-scripts │ │ │ ├── prod_deploy.sh │ │ │ ├── build_and_upload.sh │ │ │ ├── test_deploy.sh │ │ │ ├── stage_deploy.sh │ │ │ ├── stage_e2e.sh │ │ │ ├── test_smoke.sh │ │ │ ├── build_api_compatibility_check.sh │ │ │ ├── prod_complete.sh │ │ │ ├── prod_rollback.sh │ │ │ ├── test_rollback_deploy.sh │ │ │ └── test_rollback_smoke.sh │ │ ├── default-pipeline │ │ │ └── views │ │ │ │ ├── Seeds.xml │ │ │ │ └── Pipelines.xml │ │ └── spinnaker-jobs │ │ │ └── views │ │ │ └── Spinnaker.xml │ │ ├── bats │ │ ├── fixtures │ │ │ └── scripts │ │ │ │ ├── stage_e2e.sh │ │ │ │ ├── test_smoke.sh │ │ │ │ ├── prod_deploy.sh │ │ │ │ ├── stage_deploy.sh │ │ │ │ ├── test_deploy.sh │ │ │ │ ├── prod_complete.sh │ │ │ │ ├── prod_rollback.sh │ │ │ │ ├── test_rollback_deploy.sh │ │ │ │ ├── test_rollback_smoke.sh │ │ │ │ └── pipeline.sh │ │ ├── test_helper.bash │ │ └── steps.bats │ │ └── groovy │ │ └── io │ │ └── cloudpipelines │ │ ├── common │ │ ├── TestJobCustomizer.groovy │ │ └── PipelineDescriptorSpec.groovy │ │ ├── util │ │ ├── XmlComparator.groovy │ │ └── JobCreator.groovy │ │ └── JobScriptsSpec.groovy ├── build.gradle └── jobs │ ├── jenkins_pipeline_sample_view.groovy │ ├── jenkins_pipeline_crawler_sample.groovy │ └── jenkins_spinnaker_pipeline_sample.groovy ├── docs-sources └── src │ └── main │ └── asciidoc │ ├── index.adoc │ ├── MISC.adoc │ ├── images │ ├── forkme.png │ ├── demo │ │ ├── demo.png │ │ ├── demo_alerting.png │ │ └── demo_metrics.png │ ├── iconsprite.png │ ├── intro │ │ ├── flow.png │ │ ├── how.png │ │ ├── prod.png │ │ ├── test.png │ │ ├── build.png │ │ ├── stage.png │ │ ├── monolith.png │ │ ├── no_e2e_tests.png │ │ ├── flow_concourse.png │ │ ├── many_microservices.png │ │ └── stubbed_dependencies.png │ ├── jenkins │ │ ├── git.png │ │ ├── jdk.png │ │ ├── seed.png │ │ ├── blue_1.png │ │ ├── blue_2.png │ │ ├── blue_3.png │ │ ├── blue_4.png │ │ ├── blue_5.png │ │ ├── blue_6.png │ │ ├── blue_7.png │ │ ├── env_vars.png │ │ ├── kubo_token.png │ │ ├── pks_seed.png │ │ ├── seed_built.png │ │ ├── seed_click.png │ │ ├── seed_run.png │ │ ├── seed_views.png │ │ ├── credentials.png │ │ ├── global_tool.png │ │ ├── groovy_token.png │ │ ├── jenkinsfile.png │ │ ├── pipeline_run.png │ │ ├── credentials_add.png │ │ ├── kubo_update_git.png │ │ ├── manage_jenkins.png │ │ ├── pipeline_manual.png │ │ ├── configure_system.png │ │ ├── jdk_installation.png │ │ ├── kubo_credentials.png │ │ ├── pipeline_finished.png │ │ ├── credentials_example.png │ │ ├── credentials_global.png │ │ ├── credentials_system.png │ │ ├── pipeline_run_props.png │ │ ├── kubo_script_console_1.png │ │ └── kubo_script_console_2.png │ └── spring-logo.png │ ├── JENKINS.adoc │ ├── SETUP.adoc │ ├── DOCS.adoc │ ├── DEMO_SETUP.adoc │ ├── JENKINS_RUN_SEED.adoc │ ├── JENKINS_RUN_PIPELINE.adoc │ ├── CUSTOMIZATION.adoc │ ├── JENKINS_BLUE_OCEAN.adoc │ └── CF_JENKINS_FAQ.adoc ├── tools ├── k8s │ ├── namespace.yml │ ├── jenkins-service.yml │ ├── artifactory-service.yml │ ├── jenkins-gce-pvc.yml │ ├── artifactory.yml │ ├── jenkins-vsphere-pvc.yml │ ├── jenkins-gce.yml │ └── jenkins-vsphere.yml ├── cf │ └── manifest-eureka.yml ├── remove-prod-tags.sh ├── deploy-infra-k8s.sh ├── deploy-infra.sh └── build-helper.sh ├── settings.gradle ├── gradle ├── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── custom.gradle └── dist.gradle ├── .editorconfig ├── gradle.properties ├── .gitmodules ├── README.adoc ├── .gitignore ├── .circleci └── config.yml ├── declarative-pipeline ├── build.gradle ├── jobs │ └── jenkins_pipeline_jenkinsfile_empty.groovy └── src │ └── test │ └── groovy │ └── io │ └── cloudpipelines │ └── JobScriptsSpec.groovy └── gradlew.bat /docs/docinfo.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/.gitignore: -------------------------------------------------------------------------------- 1 | plugins.json 2 | -------------------------------------------------------------------------------- /job-dsl/src/main/resources/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/seed/k8s/.gitignore: -------------------------------------------------------------------------------- 1 | *.crt 2 | *.key -------------------------------------------------------------------------------- /demo/stop.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | docker-compose stop -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/index.adoc: -------------------------------------------------------------------------------- 1 | include::DOCS.adoc[] 2 | -------------------------------------------------------------------------------- /tools/k8s/namespace.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: {{name}} -------------------------------------------------------------------------------- /docs/crawler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/crawler.png -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/favicon.ico -------------------------------------------------------------------------------- /docs/spinnaker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/spinnaker.png -------------------------------------------------------------------------------- /docs/images/forkme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/forkme.png -------------------------------------------------------------------------------- /docs/images/demo/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/demo/demo.png -------------------------------------------------------------------------------- /docs/images/intro/how.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/intro/how.png -------------------------------------------------------------------------------- /docs/images/iconsprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/iconsprite.png -------------------------------------------------------------------------------- /docs/images/intro/build.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/intro/build.png -------------------------------------------------------------------------------- /docs/images/intro/flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/intro/flow.png -------------------------------------------------------------------------------- /docs/images/intro/prod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/intro/prod.png -------------------------------------------------------------------------------- /docs/images/intro/stage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/intro/stage.png -------------------------------------------------------------------------------- /docs/images/intro/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/intro/test.png -------------------------------------------------------------------------------- /docs/images/jenkins/git.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/git.png -------------------------------------------------------------------------------- /docs/images/jenkins/jdk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/jdk.png -------------------------------------------------------------------------------- /docs/images/spring-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/spring-logo.png -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = "jenkins" 2 | include 'docs', 'docs-sources', 'demo', 'declarative-pipeline', 'job-dsl' 3 | -------------------------------------------------------------------------------- /docs/images/intro/monolith.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/intro/monolith.png -------------------------------------------------------------------------------- /docs/images/jenkins/blue_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/blue_1.png -------------------------------------------------------------------------------- /docs/images/jenkins/blue_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/blue_2.png -------------------------------------------------------------------------------- /docs/images/jenkins/blue_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/blue_3.png -------------------------------------------------------------------------------- /docs/images/jenkins/blue_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/blue_4.png -------------------------------------------------------------------------------- /docs/images/jenkins/blue_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/blue_5.png -------------------------------------------------------------------------------- /docs/images/jenkins/blue_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/blue_6.png -------------------------------------------------------------------------------- /docs/images/jenkins/blue_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/blue_7.png -------------------------------------------------------------------------------- /docs/images/jenkins/seed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/seed.png -------------------------------------------------------------------------------- /job-dsl/src/test/resources/META-INF/services/io.cloudpipelines.common.JobCustomizer: -------------------------------------------------------------------------------- 1 | io.cloudpipelines.common.TestJobCustomizer 2 | -------------------------------------------------------------------------------- /docs/images/jenkins/env_vars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/env_vars.png -------------------------------------------------------------------------------- /docs/images/jenkins/pks_seed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/pks_seed.png -------------------------------------------------------------------------------- /docs/images/jenkins/seed_run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/seed_run.png -------------------------------------------------------------------------------- /docs/images/demo/demo_alerting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/demo/demo_alerting.png -------------------------------------------------------------------------------- /docs/images/demo/demo_metrics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/demo/demo_metrics.png -------------------------------------------------------------------------------- /docs/images/intro/no_e2e_tests.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/intro/no_e2e_tests.png -------------------------------------------------------------------------------- /docs/images/jenkins/credentials.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/credentials.png -------------------------------------------------------------------------------- /docs/images/jenkins/global_tool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/global_tool.png -------------------------------------------------------------------------------- /docs/images/jenkins/jenkinsfile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/jenkinsfile.png -------------------------------------------------------------------------------- /docs/images/jenkins/kubo_token.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/kubo_token.png -------------------------------------------------------------------------------- /docs/images/jenkins/seed_built.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/seed_built.png -------------------------------------------------------------------------------- /docs/images/jenkins/seed_click.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/seed_click.png -------------------------------------------------------------------------------- /docs/images/jenkins/seed_views.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/seed_views.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /docs/images/intro/flow_concourse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/intro/flow_concourse.png -------------------------------------------------------------------------------- /docs/images/jenkins/groovy_token.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/groovy_token.png -------------------------------------------------------------------------------- /docs/images/jenkins/pipeline_run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/pipeline_run.png -------------------------------------------------------------------------------- /docs/images/intro/many_microservices.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/intro/many_microservices.png -------------------------------------------------------------------------------- /docs/images/jenkins/configure_system.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/configure_system.png -------------------------------------------------------------------------------- /docs/images/jenkins/credentials_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/credentials_add.png -------------------------------------------------------------------------------- /docs/images/jenkins/jdk_installation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/jdk_installation.png -------------------------------------------------------------------------------- /docs/images/jenkins/kubo_credentials.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/kubo_credentials.png -------------------------------------------------------------------------------- /docs/images/jenkins/kubo_update_git.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/kubo_update_git.png -------------------------------------------------------------------------------- /docs/images/jenkins/manage_jenkins.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/manage_jenkins.png -------------------------------------------------------------------------------- /docs/images/jenkins/pipeline_manual.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/pipeline_manual.png -------------------------------------------------------------------------------- /docs/docinfo-footer.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/images/intro/stubbed_dependencies.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/intro/stubbed_dependencies.png -------------------------------------------------------------------------------- /docs/images/jenkins/credentials_global.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/credentials_global.png -------------------------------------------------------------------------------- /docs/images/jenkins/credentials_system.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/credentials_system.png -------------------------------------------------------------------------------- /docs/images/jenkins/pipeline_finished.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/pipeline_finished.png -------------------------------------------------------------------------------- /docs/images/jenkins/pipeline_run_props.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/pipeline_run_props.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/MISC.adoc: -------------------------------------------------------------------------------- 1 | include::JENKINS_FAQ.adoc[] 2 | // remove::start[CF] 3 | include::CF_JENKINS_FAQ.adoc[] 4 | // remove::end[CF] 5 | 6 | -------------------------------------------------------------------------------- /docs/images/jenkins/credentials_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/credentials_example.png -------------------------------------------------------------------------------- /docs/images/jenkins/kubo_script_console_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/kubo_script_console_1.png -------------------------------------------------------------------------------- /docs/images/jenkins/kubo_script_console_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs/images/jenkins/kubo_script_console_2.png -------------------------------------------------------------------------------- /demo/whats_my_ip.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1' | head -n 1 4 | -------------------------------------------------------------------------------- /job-dsl/src/test/bats/fixtures/scripts/stage_e2e.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o errtrace 5 | set -o pipefail 6 | 7 | echo "Executed stage_e2e" 8 | -------------------------------------------------------------------------------- /job-dsl/src/test/bats/fixtures/scripts/test_smoke.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o errtrace 5 | set -o pipefail 6 | 7 | echo "Executed test_smoke" 8 | -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/forkme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/forkme.png -------------------------------------------------------------------------------- /job-dsl/src/test/bats/fixtures/scripts/prod_deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o errtrace 5 | set -o pipefail 6 | 7 | echo "Executed prod_deploy" 8 | -------------------------------------------------------------------------------- /job-dsl/src/test/bats/fixtures/scripts/stage_deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o errtrace 5 | set -o pipefail 6 | 7 | echo "Executed stage_deploy" 8 | -------------------------------------------------------------------------------- /job-dsl/src/test/bats/fixtures/scripts/test_deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o errtrace 5 | set -o pipefail 6 | 7 | echo "Executed test_deploy" 8 | -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/demo/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/demo/demo.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/iconsprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/iconsprite.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/intro/flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/intro/flow.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/intro/how.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/intro/how.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/intro/prod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/intro/prod.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/intro/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/intro/test.png -------------------------------------------------------------------------------- /job-dsl/src/test/bats/fixtures/scripts/prod_complete.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o errtrace 5 | set -o pipefail 6 | 7 | echo "Executed prod_complete" 8 | -------------------------------------------------------------------------------- /job-dsl/src/test/bats/fixtures/scripts/prod_rollback.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o errtrace 5 | set -o pipefail 6 | 7 | echo "Executed prod_rollback" 8 | -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/intro/build.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/intro/build.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/intro/stage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/intro/stage.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/git.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/git.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/jdk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/jdk.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/seed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/seed.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/spring-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/spring-logo.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/intro/monolith.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/intro/monolith.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/blue_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/blue_1.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/blue_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/blue_2.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/blue_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/blue_3.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/blue_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/blue_4.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/blue_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/blue_5.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/blue_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/blue_6.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/blue_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/blue_7.png -------------------------------------------------------------------------------- /job-dsl/src/test/bats/fixtures/scripts/test_rollback_deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o errtrace 5 | set -o pipefail 6 | 7 | echo "Executed test_rollback_deploy" 8 | -------------------------------------------------------------------------------- /job-dsl/src/test/bats/fixtures/scripts/test_rollback_smoke.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o errtrace 5 | set -o pipefail 6 | 7 | echo "Executed test_rollback_smoke" 8 | -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/demo/demo_alerting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/demo/demo_alerting.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/demo/demo_metrics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/demo/demo_metrics.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/intro/no_e2e_tests.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/intro/no_e2e_tests.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/env_vars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/env_vars.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/kubo_token.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/kubo_token.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/pks_seed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/pks_seed.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/seed_built.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/seed_built.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/seed_click.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/seed_click.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/seed_run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/seed_run.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/seed_views.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/seed_views.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/intro/flow_concourse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/intro/flow_concourse.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/credentials.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/credentials.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/global_tool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/global_tool.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/groovy_token.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/groovy_token.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/jenkinsfile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/jenkinsfile.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/pipeline_run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/pipeline_run.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/credentials_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/credentials_add.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/kubo_update_git.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/kubo_update_git.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/manage_jenkins.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/manage_jenkins.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/pipeline_manual.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/pipeline_manual.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/intro/many_microservices.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/intro/many_microservices.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/configure_system.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/configure_system.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/jdk_installation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/jdk_installation.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/kubo_credentials.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/kubo_credentials.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/pipeline_finished.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/pipeline_finished.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/intro/stubbed_dependencies.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/intro/stubbed_dependencies.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/credentials_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/credentials_example.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/credentials_global.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/credentials_global.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/credentials_system.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/credentials_system.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/pipeline_run_props.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/pipeline_run_props.png -------------------------------------------------------------------------------- /job-dsl/src/main/bash/steps/stage_e2e.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -o errexit 3 | set -o errtrace 4 | set -o pipefail 5 | 6 | # shellcheck source=/dev/null 7 | "${WORKSPACE}"/.git/tools/src/main/bash/stage_e2e.sh 8 | -------------------------------------------------------------------------------- /job-dsl/src/main/bash/steps/test_smoke.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -o errexit 3 | set -o errtrace 4 | set -o pipefail 5 | 6 | # shellcheck source=/dev/null 7 | "${WORKSPACE}"/.git/tools/src/main/bash/test_smoke.sh 8 | -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/kubo_script_console_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/kubo_script_console_1.png -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/images/jenkins/kubo_script_console_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/cloudpipelines-jenkins/master/docs-sources/src/main/asciidoc/images/jenkins/kubo_script_console_2.png -------------------------------------------------------------------------------- /job-dsl/src/main/bash/steps/prod_deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -o errexit 3 | set -o errtrace 4 | set -o pipefail 5 | 6 | # shellcheck source=/dev/null 7 | "${WORKSPACE}"/.git/tools/src/main/bash/prod_deploy.sh 8 | -------------------------------------------------------------------------------- /job-dsl/src/main/bash/steps/stage_deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -o errexit 3 | set -o errtrace 4 | set -o pipefail 5 | 6 | # shellcheck source=/dev/null 7 | "${WORKSPACE}"/.git/tools/src/main/bash/stage_deploy.sh 8 | -------------------------------------------------------------------------------- /job-dsl/src/main/bash/steps/test_deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -o errexit 3 | set -o errtrace 4 | set -o pipefail 5 | 6 | # shellcheck source=/dev/null 7 | "${WORKSPACE}"/.git/tools/src/main/bash/test_deploy.sh 8 | -------------------------------------------------------------------------------- /tools/k8s/jenkins-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: jenkins 5 | spec: 6 | type: NodePort 7 | ports: 8 | - port: 8080 9 | selector: 10 | name: jenkins 11 | -------------------------------------------------------------------------------- /job-dsl/src/main/bash/steps/prod_complete.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -o errexit 3 | set -o errtrace 4 | set -o pipefail 5 | 6 | # shellcheck source=/dev/null 7 | "${WORKSPACE}"/.git/tools/src/main/bash/prod_complete.sh 8 | -------------------------------------------------------------------------------- /job-dsl/src/main/bash/steps/prod_rollback.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -o errexit 3 | set -o errtrace 4 | set -o pipefail 5 | 6 | # shellcheck source=/dev/null 7 | "${WORKSPACE}"/.git/tools/src/main/bash/prod_rollback.sh 8 | -------------------------------------------------------------------------------- /job-dsl/src/main/bash/steps/prod_remove_prod_tag.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export ENVIRONMENT=prod 4 | 5 | # shellcheck source=/dev/null 6 | source "${WORKSPACE}"/.git/tools/src/main/bash/pipeline.sh 7 | 8 | removeProdTag 9 | -------------------------------------------------------------------------------- /tools/k8s/artifactory-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: artifactory 5 | spec: 6 | type: NodePort 7 | ports: 8 | - port: 8081 9 | selector: 10 | name: artifactory 11 | -------------------------------------------------------------------------------- /job-dsl/src/main/bash/steps/test_rollback_deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -o errexit 3 | set -o errtrace 4 | set -o pipefail 5 | 6 | # shellcheck source=/dev/null 7 | "${WORKSPACE}"/.git/tools/src/main/bash/test_rollback_deploy.sh 8 | -------------------------------------------------------------------------------- /job-dsl/src/main/bash/steps/test_rollback_smoke.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -o errexit 3 | set -o errtrace 4 | set -o pipefail 5 | 6 | # shellcheck source=/dev/null 7 | "${WORKSPACE}"/.git/tools/src/main/bash/test_rollback_smoke.sh 8 | -------------------------------------------------------------------------------- /gradle/custom.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | In this file you can provide your own customizations of the build. 3 | Since this file will not change in the main repository of Cloud Pipelines, 4 | you will not have any conflicts when pulling upstream changes. 5 | */ 6 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/spinnaker/pipeline/model/PayloadConstraints.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.spinnaker.pipeline.model 2 | 3 | import groovy.transform.CompileStatic 4 | 5 | @CompileStatic 6 | class PayloadConstraints { 7 | } 8 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/spinnaker/pipeline/model/AppConfig.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.spinnaker.pipeline.model 2 | 3 | import groovy.transform.CompileStatic; 4 | 5 | @CompileStatic 6 | class AppConfig { 7 | } 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/spinnaker/pipeline/model/StageEnabled.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.spinnaker.pipeline.model 2 | 3 | import groovy.transform.CompileStatic 4 | 5 | @CompileStatic 6 | class StageEnabled { 7 | String expression 8 | String type 9 | } 10 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/spinnaker/pipeline/model/Capacity.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.spinnaker.pipeline.model 2 | 3 | import groovy.transform.CompileStatic 4 | 5 | @CompileStatic 6 | class Capacity { 7 | String desired 8 | String max 9 | String min 10 | } 11 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | [*] 7 | indent_style = tab 8 | indent_size = 4 9 | end_of_line = lf 10 | insert_final_newline = true 11 | 12 | [*.yml] 13 | indent_style = space 14 | indent_size = 2 15 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.daemon=false 2 | 3 | shellcheckVersion=v0.4.6 4 | jrubyVersion=1.5.0 5 | asciidoctorGradleVersion=1.5.9.2 6 | gradleDockerPluginVersion=3.6.0 7 | springDocResourcesVersion=0.1.0.RELEASE 8 | 9 | jenkinsJobDslVersion=1.72 10 | 11 | defaultVersion=1.0.0.BUILD-SNAPSHOT 12 | -------------------------------------------------------------------------------- /demo/Dockerfile-artifactory: -------------------------------------------------------------------------------- 1 | FROM docker.bintray.io/jfrog/artifactory-oss:6.1.0 2 | 3 | MAINTAINER Marcin Grzejszczak 4 | 5 | COPY artifactory.config.import.yml /var/opt/jfrog/artifactory/etc/artifactory.config.import.yml 6 | 7 | ENTRYPOINT ["/bin/sh", "-c", "/entrypoint-artifactory.sh"] 8 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/spinnaker/pipeline/model/cf/ListOfCloudFoundryManifest.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.spinnaker.pipeline.model.cf 2 | 3 | import groovy.transform.CompileStatic 4 | 5 | @CompileStatic 6 | class ListOfCloudFoundryManifest { 7 | List applications 8 | } 9 | -------------------------------------------------------------------------------- /tools/k8s/jenkins-gce-pvc.yml: -------------------------------------------------------------------------------- 1 | kind: PersistentVolumeClaim 2 | apiVersion: v1 3 | metadata: 4 | name: jenkins-volume 5 | annotations: 6 | volume.alpha.kubernetes.io/storage-class: default 7 | spec: 8 | accessModes: 9 | - ReadWriteOnce 10 | resources: 11 | requests: 12 | storage: 10Gi 13 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/spinnaker/pipeline/model/Artifact.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.spinnaker.pipeline.model 2 | 3 | import groovy.transform.CompileStatic 4 | 5 | @CompileStatic 6 | class Artifact { 7 | String account 8 | String reference 9 | String pattern 10 | String type 11 | } 12 | -------------------------------------------------------------------------------- /job-dsl/src/test/bats/test_helper.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | FIXTURES_DIR="${BATS_TEST_DIRNAME}/fixtures" 4 | SOURCE_DIR="${BATS_TEST_DIRNAME}/../../.." 5 | STEPS_DIR="${SOURCE_DIR}/src/main/bash/steps" 6 | PROJECT_ROOT_DIR="${BATS_TEST_DIRNAME}/../../../../" 7 | 8 | export FIXTURES_DIR SOURCE_DIR STEPS_DIR PROJECT_ROOT_DIR 9 | -------------------------------------------------------------------------------- /tools/cf/manifest-eureka.yml: -------------------------------------------------------------------------------- 1 | --- 2 | applications: 3 | - name: github-eureka 4 | services: 5 | - github-rabbitmq 6 | env: 7 | SPRING_PROFILES_ACTIVE: cloud 8 | DEBUG: "true" 9 | # TODO: Remove this from github eureka codebases 10 | APPLICATION_DOMAIN: github-eureka-cloudpipelines-test.cfapps.io 11 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "job-dsl/src/test/bats/test_helper/bats-support"] 2 | path = job-dsl/src/test/bats/test_helper/bats-support 3 | url = https://github.com/ztombol/bats-support 4 | [submodule "job-dsl/src/test/bats/test_helper/bats-assert"] 5 | path = job-dsl/src/test/bats/test_helper/bats-assert 6 | url = https://github.com/ztombol/bats-assert 7 | -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/JENKINS.adoc: -------------------------------------------------------------------------------- 1 | include::JENKINS_COMMON.adoc[] 2 | 3 | // remove::start[CF] 4 | include::CF_JENKINS.adoc[] 5 | // remove::end[CF] 6 | 7 | // remove::start[K8S] 8 | include::K8S_JENKINS.adoc[] 9 | // remove::end[K8S] 10 | 11 | == Setup examples 12 | 13 | You can go to link:SETUP.html[setup subpage] to read more 14 | about different setup scenarios. 15 | -------------------------------------------------------------------------------- /job-dsl/src/main/bash/steps/test_prepare.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -o errexit 3 | set -o errtrace 4 | set -o pipefail 5 | 6 | export PAAS_TYPE=CF 7 | export ENVIRONMENT=TEST 8 | 9 | # shellcheck source=/dev/null 10 | source "${WORKSPACE}"/.git/tools/src/main/bash/pipeline.sh 11 | 12 | # Log in to PaaS to start deployment 13 | logInToPaas 14 | 15 | deployServices 16 | waitForServicesToInitialize 17 | -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/SETUP.adoc: -------------------------------------------------------------------------------- 1 | = Sample setups 2 | 3 | In these sections you will see examples of setups 4 | for different platforms. 5 | 6 | // remove::start[K8S] 7 | include::K8S_SETUP.adoc[] 8 | // remove::end[K8S] 9 | 10 | // remove::start[CF] 11 | include::CF_DEMO.adoc[] 12 | // remove::end[CF] 13 | 14 | // remove::start[K8S] 15 | include::K8S_DEMO.adoc[] 16 | // remove::end[K8S] 17 | -------------------------------------------------------------------------------- /job-dsl/src/main/bash/steps/stage_prepare.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -o errexit 3 | set -o errtrace 4 | set -o pipefail 5 | 6 | export PAAS_TYPE=CF 7 | export ENVIRONMENT=STAGE 8 | 9 | # shellcheck source=/dev/null 10 | source "${WORKSPACE}"/.git/tools/src/main/bash/pipeline.sh 11 | 12 | # Log in to PaaS to start deployment 13 | logInToPaas 14 | 15 | deployServices 16 | waitForServicesToInitialize 17 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/spinnaker/pipeline/model/Root.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.spinnaker.pipeline.model 2 | 3 | import groovy.transform.CompileStatic 4 | 5 | @CompileStatic 6 | class Root { 7 | AppConfig appConfig = new AppConfig() 8 | boolean keepWaitingPipelines 9 | boolean limitConcurrent = true 10 | List stages = [] 11 | List triggers = [] 12 | } 13 | -------------------------------------------------------------------------------- /tools/k8s/artifactory.yml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: artifactory 5 | spec: 6 | replicas: 1 7 | template: 8 | metadata: 9 | labels: 10 | name: artifactory 11 | spec: 12 | containers: 13 | - name: artifactory 14 | image: jfrog-docker-registry.bintray.io/artifactory/artifactory-oss:latest 15 | ports: 16 | - containerPort: 8081 17 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/spinnaker/pipeline/model/Manifest.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.spinnaker.pipeline.model 2 | 3 | import groovy.transform.CompileStatic 4 | 5 | @CompileStatic 6 | class Manifest { 7 | String diskQuota 8 | List> env = [] 9 | int instances 10 | String memory 11 | List services = [] 12 | String type 13 | List routes 14 | String account 15 | String reference 16 | } 17 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/common/RepoType.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.common 2 | 3 | import groovy.transform.CompileStatic 4 | 5 | /** 6 | * Ways in which the tools repo can be fetched 7 | * 8 | * @author Marcin Grzejszczak 9 | * @since 1.0.0 10 | */ 11 | @CompileStatic 12 | enum RepoType { 13 | TARBALL, GIT 14 | 15 | static RepoType from(String string) { 16 | if (string.endsWith(".tar.gz")) return TARBALL 17 | return GIT 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/spinnaker/pipeline/model/Cluster.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.spinnaker.pipeline.model 2 | 3 | import groovy.transform.CompileStatic 4 | 5 | @CompileStatic 6 | class Cluster { 7 | String account 8 | String application 9 | Artifact artifact 10 | Capacity capacity 11 | String cloudProvider 12 | String detail 13 | Manifest manifest 14 | String provider 15 | String region 16 | String spaceId 17 | String stack 18 | String strategy 19 | } 20 | -------------------------------------------------------------------------------- /job-dsl/src/test/resources/cloudpipelines-scripts/prod_deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o errtrace 5 | set -o pipefail 6 | 7 | # synopsis {{{ 8 | # Deploys app to production. Sources pipeline.sh 9 | # }}} 10 | 11 | __DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 12 | 13 | export ENVIRONMENT=PROD 14 | 15 | # shellcheck source=/dev/null 16 | [[ -f "${__DIR}/pipeline.sh" ]] && source "${__DIR}/pipeline.sh" || \ 17 | echo "No pipeline.sh found" 18 | 19 | prodDeploy 20 | -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/DOCS.adoc: -------------------------------------------------------------------------------- 1 | = Cloud Pipelines Jenkins 2 | 3 | This project contains setup for Jenkins that creates jobs and pipelines 4 | via Jenkins Job DSL or Jenkinsfile for your projects. The pipelines and 5 | jobs use the scripts defined in 6 | https://github.com/CloudPipelines/scripts[Cloud Pipelines Scripts] repo. 7 | 8 | include::INTRO.adoc[] 9 | 10 | include::CUSTOMIZATION.adoc[] 11 | 12 | include::JENKINS.adoc[] 13 | 14 | include::TECH.adoc[] 15 | 16 | include::MISC.adoc[] 17 | -------------------------------------------------------------------------------- /job-dsl/src/test/resources/cloudpipelines-scripts/build_and_upload.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o errtrace 5 | set -o pipefail 6 | 7 | # synopsis {{{ 8 | # Executes a build of the project. Sources pipeline.sh 9 | # }}} 10 | 11 | __DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 12 | 13 | export ENVIRONMENT=BUILD 14 | 15 | # shellcheck source=/dev/null 16 | [[ -f "${__DIR}/pipeline.sh" ]] && source "${__DIR}/pipeline.sh" || \ 17 | echo "No pipeline.sh found" 18 | 19 | build 20 | -------------------------------------------------------------------------------- /job-dsl/src/test/resources/cloudpipelines-scripts/test_deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o errtrace 5 | set -o pipefail 6 | 7 | # synopsis {{{ 8 | # Deploys app to test environment. Sources pipeline.sh 9 | # }}} 10 | 11 | __DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 12 | 13 | export ENVIRONMENT=TEST 14 | 15 | # shellcheck source=/dev/null 16 | [[ -f "${__DIR}/pipeline.sh" ]] && source "${__DIR}/pipeline.sh" || \ 17 | echo "No pipeline.sh found" 18 | 19 | testDeploy 20 | -------------------------------------------------------------------------------- /job-dsl/src/test/resources/cloudpipelines-scripts/stage_deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o errtrace 5 | set -o pipefail 6 | 7 | # synopsis {{{ 8 | # Deploys app to stage environment. Sources pipeline.sh 9 | # }}} 10 | 11 | __DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 12 | 13 | export ENVIRONMENT=STAGE 14 | 15 | # shellcheck source=/dev/null 16 | [[ -f "${__DIR}/pipeline.sh" ]] && source "${__DIR}/pipeline.sh" || \ 17 | echo "No pipeline.sh found" 18 | 19 | stageDeploy 20 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/spinnaker/pipeline/model/Trigger.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.spinnaker.pipeline.model 2 | 3 | import groovy.transform.CompileStatic 4 | 5 | @CompileStatic 6 | class Trigger { 7 | String account 8 | String branch 9 | Boolean enabled 10 | String job 11 | String master 12 | String organization 13 | PayloadConstraints payloadConstraints 14 | String project 15 | String repository 16 | String slug 17 | String source 18 | String type 19 | String propertyFile 20 | } 21 | -------------------------------------------------------------------------------- /job-dsl/src/test/resources/cloudpipelines-scripts/stage_e2e.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o errtrace 5 | set -o pipefail 6 | 7 | # synopsis {{{ 8 | # Runs end to end tests on stage. Sources pipeline.sh 9 | # }}} 10 | 11 | __DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 12 | 13 | export ENVIRONMENT=STAGE 14 | 15 | # shellcheck source=/dev/null 16 | [[ -f "${__DIR}/pipeline.sh" ]] && source "${__DIR}/pipeline.sh" || \ 17 | echo "No pipeline.sh found" 18 | 19 | prepareForE2eTests 20 | runE2eTests 21 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/spinnaker/pipeline/model/cf/CloudFoundryManifest.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.spinnaker.pipeline.model.cf 2 | 3 | import groovy.transform.CompileStatic 4 | 5 | /** 6 | * 7 | * @author Marcin Grzejszczak 8 | * @since 1.0.0 9 | */ 10 | @CompileStatic 11 | class CloudFoundryManifest { 12 | int instances 13 | String memory 14 | String diskQuota 15 | String buildpack 16 | List routes = [] 17 | Map env = [:] 18 | List services = [] 19 | } 20 | 21 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/test/TestUtils.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.test 2 | 3 | import groovy.transform.CompileStatic 4 | 5 | import io.cloudpipelines.projectcrawler.Repository 6 | 7 | /** 8 | * Utility class helping to test the scripts 9 | * 10 | * @author Marcin Grzejszczak 11 | * @since 1.0.0 12 | */ 13 | @CompileStatic 14 | class TestUtils { 15 | 16 | public static List TEST_REPO = [new Repository("foo", "git@bar.com:baz/foo.git", "https://bar.com/baz/foo.git", "master")] 17 | } 18 | -------------------------------------------------------------------------------- /job-dsl/src/test/resources/cloudpipelines-scripts/test_smoke.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o errtrace 5 | set -o pipefail 6 | 7 | # synopsis {{{ 8 | # Runs smoke tests on the test environment. Sources pipeline.sh 9 | # }}} 10 | 11 | __DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 12 | 13 | export ENVIRONMENT=TEST 14 | 15 | # shellcheck source=/dev/null 16 | [[ -f "${__DIR}/pipeline.sh" ]] && source "${__DIR}/pipeline.sh" || \ 17 | echo "No pipeline.sh found" 18 | 19 | prepareForSmokeTests 20 | runSmokeTests 21 | -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | # cloudpipelines-jenkins is no longer actively maintained by VMware, Inc. 2 | 3 | = Cloud Pipelines Jenkins 4 | 5 | This project contains setup for Jenkins that creates jobs and pipelines 6 | via Jenkins Job DSL or Jenkinsfile for your projects. The pipelines and 7 | jobs use the scripts defined in 8 | https://cloud.spring.io/cloudpipelines-scripts/[Cloud Pipelines Scripts] repo. 9 | 10 | You can check out the `docs` folder for the documentation. The deployed docs are available https://cloud.spring.io/cloudpipelines-jenkins/[here] 11 | -------------------------------------------------------------------------------- /job-dsl/src/test/resources/cloudpipelines-scripts/build_api_compatibility_check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o errtrace 5 | set -o pipefail 6 | 7 | # synopsis {{{ 8 | # Executes a api compatibility check of the project. Sources pipeline.sh 9 | # }}} 10 | 11 | __DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 12 | 13 | export ENVIRONMENT=BUILD 14 | 15 | # shellcheck source=/dev/null 16 | [[ -f "${__DIR}/pipeline.sh" ]] && source "${__DIR}/pipeline.sh" || \ 17 | echo "No pipeline.sh found" 18 | 19 | apiCompatibilityCheck 20 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/common/GeneratedJobs.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.common 2 | 3 | import groovy.transform.Canonical 4 | import groovy.transform.CompileStatic 5 | 6 | import io.cloudpipelines.projectcrawler.Repository 7 | 8 | /** 9 | * @author Marcin Grzejszczak 10 | * @since 1.0.0 11 | */ 12 | @CompileStatic 13 | @Canonical 14 | class GeneratedJobs { 15 | List repositoriesForViews = [] 16 | Map errors = [:] 17 | 18 | boolean hasErrors() { 19 | return !errors.isEmpty() 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /job-dsl/src/test/resources/cloudpipelines-scripts/prod_complete.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o errtrace 5 | set -o pipefail 6 | 7 | # synopsis {{{ 8 | # Executes a switch over of the traffic, fully to the new instance. 9 | # Sources pipeline.sh 10 | # }}} 11 | 12 | __DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 13 | 14 | export ENVIRONMENT=PROD 15 | 16 | # shellcheck source=/dev/null 17 | [[ -f "${__DIR}/pipeline.sh" ]] && source "${__DIR}/pipeline.sh" || \ 18 | echo "No pipeline.sh found" 19 | 20 | completeSwitchOver 21 | -------------------------------------------------------------------------------- /demo/seed/settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ${M2_SETTINGS_REPO_ID} 6 | ${M2_SETTINGS_REPO_USERNAME} 7 | ${M2_SETTINGS_REPO_PASSWORD} 8 | 9 | 10 | ${DOCKER_SERVER_ID} 11 | ${DOCKER_USERNAME} 12 | ${DOCKER_PASSWORD} 13 | 14 | ${DOCKER_EMAIL} 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/spinnaker/SpinnakerDefaults.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.spinnaker 2 | 3 | import groovy.transform.CompileStatic 4 | 5 | /** 6 | * Contains default values for names of jobs and views 7 | * 8 | * @author Marcin Grzejszczak 9 | * @since 1.0.0 10 | */ 11 | @CompileStatic 12 | class SpinnakerDefaults { 13 | static String projectName(String gitRepoName) { 14 | return "spinnaker-${gitRepoName}-pipeline" 15 | } 16 | 17 | static String viewName(String gitRepoName) { 18 | return "spinnaker-${gitRepoName}" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /docs/js/tocbot/tocbot.css: -------------------------------------------------------------------------------- 1 | .toc{overflow-y:auto}.toc>.toc-list{overflow:hidden;position:relative}.toc>.toc-list li{list-style:none}.toc-list{margin:0;padding-left:10px}a.toc-link{color:currentColor;height:100%}.is-collapsible{max-height:1000px;overflow:hidden;transition:all 300ms ease-in-out}.is-collapsed{max-height:0}.is-position-fixed{position:fixed !important;top:0}.is-active-link{font-weight:700}.toc-link::before{background-color:#EEE;content:' ';display:inline-block;height:inherit;left:0;margin-top:-1px;position:absolute;width:2px}.is-active-link::before{background-color:#54BC4B} 2 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/steps/CreatedJob.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.steps 2 | 3 | import groovy.transform.CompileStatic 4 | import javaposse.jobdsl.dsl.Job 5 | 6 | /** 7 | * Contains the created job and info whether the next 8 | * step should be automated or not 9 | * 10 | * @author Marcin Grzejszczak 11 | * @since 1.0.0 12 | */ 13 | @CompileStatic 14 | class CreatedJob { 15 | final Job job 16 | final boolean autoNextJob 17 | 18 | CreatedJob(Job job, boolean autoNextJob) { 19 | this.job = job 20 | this.autoNextJob = autoNextJob 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/common/PipelineJobsFactoryProvider.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.common 2 | 3 | import javaposse.jobdsl.dsl.DslFactory 4 | 5 | import io.cloudpipelines.projectcrawler.Repository 6 | 7 | interface PipelineJobsFactoryProvider { 8 | /** 9 | * Gets the concrete jobs factory 10 | */ 11 | PipelineJobsFactory get(PipelineDefaults pipelineDefaults, 12 | DslFactory dsl, 13 | PipelineDescriptor descriptor, 14 | Repository repository) 15 | 16 | /** 17 | * List of additional files that should be parsed 18 | */ 19 | List additionalFiles() 20 | } 21 | -------------------------------------------------------------------------------- /job-dsl/src/test/resources/cloudpipelines-scripts/prod_rollback.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o errtrace 5 | set -o pipefail 6 | 7 | # synopsis {{{ 8 | # Rolls back app from production. Sources pipeline.sh 9 | # }}} 10 | 11 | __DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 12 | 13 | export ENVIRONMENT=PROD 14 | 15 | # shellcheck source=/dev/null 16 | [[ -f "${__DIR}/pipeline.sh" ]] && source "${__DIR}/pipeline.sh" || \ 17 | echo "No pipeline.sh found" 18 | 19 | if rollbackToPreviousVersion; then 20 | removeProdTag 21 | exit 0 22 | else 23 | echo "Failed to rollback to previous version" 24 | exit 1 25 | fi 26 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/default_pipeline/DefaultPipelineDefaults.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.default_pipeline 2 | 3 | import groovy.transform.CompileStatic 4 | 5 | /** 6 | * Contains default values for names of jobs and views for the default 7 | * cloud pipelines approach (cloud pipelines deploys the apps) 8 | * 9 | * @author Marcin Grzejszczak 10 | * @since 1.0.0 11 | */ 12 | @CompileStatic 13 | class DefaultPipelineDefaults { 14 | static String projectName(String gitRepoName) { 15 | return "${gitRepoName}-pipeline" 16 | } 17 | 18 | static String viewName(String gitRepoName) { 19 | return gitRepoName 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tools/k8s/jenkins-vsphere-pvc.yml: -------------------------------------------------------------------------------- 1 | kind: StorageClass 2 | apiVersion: storage.k8s.io/v1 3 | metadata: 4 | name: ci-storage 5 | labels: 6 | name: jenkins 7 | annotations: 8 | storageclass.beta.kubernetes.io/is-default-class: "true" 9 | provisioner: kubernetes.io/vsphere-volume 10 | parameters: 11 | diskformat: zeroedthick 12 | --- 13 | kind: PersistentVolumeClaim 14 | apiVersion: v1 15 | metadata: 16 | name: jenkins-volume 17 | annotations: 18 | volume.beta.kubernetes.io/storage-class: ci-storage 19 | spec: 20 | accessModes: 21 | - ReadWriteOnce 22 | resources: 23 | requests: 24 | storage: 10Gi 25 | storageClassName: ci-storage 26 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/steps/Step.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.steps 2 | 3 | import groovy.transform.CompileStatic 4 | import groovy.transform.Immutable 5 | import javaposse.jobdsl.dsl.Job 6 | import javaposse.jobdsl.dsl.jobs.FreeStyleJob 7 | 8 | import io.cloudpipelines.common.Coordinates 9 | import io.cloudpipelines.common.PipelineDescriptor 10 | 11 | /** 12 | * Represents a step inside the pipeline 13 | * 14 | * @author Marcin Grzejszczak 15 | * @since 1.0.0 16 | */ 17 | @CompileStatic 18 | interface Step { 19 | CreatedJob step(String projectName, Coordinates coordinates, PipelineDescriptor descriptor) 20 | void customize(T step) 21 | } 22 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/spinnaker/pipeline/model/Stage.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.spinnaker.pipeline.model 2 | 3 | import groovy.transform.CompileStatic 4 | 5 | @CompileStatic 6 | class Stage { 7 | List clusters 8 | Boolean failPipeline 9 | String name 10 | String refId 11 | List requisiteStageRefIds = [] 12 | String type 13 | String command 14 | String scriptPath 15 | String user 16 | Boolean waitForCompletion 17 | Map parameters 18 | String master 19 | String job 20 | List judgmentInputs 21 | List notifications 22 | Boolean continuePipeline 23 | Integer waitTime 24 | StageEnabled stageEnabled 25 | } 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Mobile Tools for Java (J2ME) 4 | .mtj.tmp/ 5 | 6 | # Package Files # 7 | *.jar 8 | *.war 9 | *.ear 10 | 11 | # virtual machine crash logs, see https://www.java.com/en/download/help/error_hotspot.xml 12 | hs_err_pid* 13 | 14 | .gradle 15 | .idea 16 | build 17 | *.iml 18 | .DS_Store 19 | *.log 20 | target 21 | out 22 | 23 | # Vim 24 | [._]*.s[a-v][a-z] 25 | [._]*.sw[a-p] 26 | [._]s[a-v][a-z] 27 | [._]sw[a-p] 28 | Session.vim 29 | .netrwhist 30 | *~ 31 | 32 | *.crt 33 | *.key 34 | 35 | credentials.yml 36 | credentials-cf.yml 37 | credentials-k8s.yml 38 | pom.xml.versionsBackup 39 | .asciidoctor 40 | bin/ 41 | out/ 42 | .classpath 43 | .project 44 | .settings/ 45 | .classpath 46 | .project 47 | .settings/ 48 | .vscode/ 49 | bin/ -------------------------------------------------------------------------------- /tools/remove-prod-tags.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o errtrace 5 | set -o nounset 6 | set -o pipefail 7 | 8 | __dir="$( cd "$(dirname "${BASH_SOURCE[0]}")" && pwd )" 9 | 10 | REPOSITORIES="github-webhook github-analytics" 11 | 12 | if [[ $# -ne 1 ]]; then 13 | echo "usage: $0 " 14 | exit 1 15 | fi 16 | 17 | GH_ORG="$1" 18 | 19 | mkdir -p "${__dir}/../target" && cd "${__dir}/../target" 20 | 21 | for REPO in ${REPOSITORIES}; do 22 | if [[ ! -d "${REPO}" ]]; then 23 | git clone "git@github.com:${GH_ORG}/${REPO}.git" 24 | fi 25 | pushd "${REPO}" 26 | while read -r TAG; do 27 | git push --delete origin "${TAG}" 28 | done < <( git ls-remote -q --tags origin | cut -f 2 | grep '^refs/tags/prod/' | grep -v '{}' ) 29 | popd 30 | done 31 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/common/PipelineJobsFactory.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.common 2 | 3 | import groovy.transform.CompileStatic 4 | 5 | /** 6 | * Contract for generating all the jobs for a pipeline 7 | * 8 | * @author Marcin Grzejszczak 9 | * @since 1.0.0 10 | */ 11 | @CompileStatic 12 | interface PipelineJobsFactory { 13 | 14 | /** 15 | * Builds all jobs for the deployment pipeline 16 | * 17 | * @param coordinates - coordinates of a repo for which the pipelines is to be built 18 | * @param pipelineVersion - the deployment pipeline version 19 | * @param additionalFiles - a map of file name to its contents retrieved from the repo 20 | */ 21 | void allJobs(Coordinates coordinates, String pipelineVersion, Map additionalFiles) 22 | } 23 | -------------------------------------------------------------------------------- /job-dsl/src/test/resources/default-pipeline/views/Seeds.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | false 4 | false 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | .*-seed 19 | 20 | -------------------------------------------------------------------------------- /job-dsl/src/test/resources/cloudpipelines-scripts/test_rollback_deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o errtrace 5 | set -o pipefail 6 | 7 | # synopsis {{{ 8 | # If applicable, deploys current prod version to test environment. 9 | # Sources pipeline.sh 10 | # }}} 11 | 12 | __DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 13 | 14 | export ENVIRONMENT=TEST 15 | 16 | # shellcheck source=/dev/null 17 | [[ -f "${__DIR}/pipeline.sh" ]] && source "${__DIR}/pipeline.sh" || \ 18 | echo "No pipeline.sh found" 19 | 20 | # Find latest prod version 21 | prodTag="$(findLatestProdTag)" 22 | echo "Last prod tag equals [${prodTag}]" 23 | if [[ -z "${prodTag}" ]]; then 24 | echo "No prod release took place - skipping this step" 25 | else 26 | "${GIT_BIN}" checkout "${prodTag}" 27 | testRollbackDeploy "${prodTag}" 28 | fi 29 | -------------------------------------------------------------------------------- /job-dsl/src/test/resources/cloudpipelines-scripts/test_rollback_smoke.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o errtrace 5 | set -o pipefail 6 | 7 | # synopsis {{{ 8 | # If applicable, runs smoke tests on the test environment. 9 | # Sources pipeline.sh 10 | # }}} 11 | 12 | __DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 13 | 14 | export ENVIRONMENT=TEST 15 | 16 | # shellcheck source=/dev/null 17 | [[ -f "${__DIR}/pipeline.sh" ]] && source "${__DIR}/pipeline.sh" || \ 18 | echo "No pipeline.sh found" 19 | 20 | # Find latest prod version 21 | prodTag="$(findLatestProdTag)" 22 | echo "Last prod tag equals [${prodTag}]" 23 | 24 | if [[ -z "${prodTag}" || "${prodTag}" == "master" ]]; then 25 | echo "No prod release took place - skipping this step" 26 | else 27 | "${GIT_BIN}" checkout "${prodTag}" 28 | prepareForSmokeTests 29 | runSmokeTests 30 | fi 31 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/common/JobCustomizer.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.common; 2 | 3 | import javaposse.jobdsl.dsl.jobs.FreeStyleJob; 4 | 5 | /** 6 | * Hook to customize the created jobs 7 | * 8 | * @author Marcin Grzejszczak 9 | * @since 1.0.0 10 | */ 11 | interface JobCustomizer { 12 | 13 | /** 14 | * Applicable to all jobs in the pipeline 15 | */ 16 | void customizeAll(FreeStyleJob job) 17 | 18 | /** 19 | * Applicable to jobs from the {@code build} phase 20 | */ 21 | void customizeBuild(FreeStyleJob job) 22 | 23 | /** 24 | * Applicable to jobs from the {@code test} phase 25 | */ 26 | void customizeTest(FreeStyleJob job) 27 | 28 | /** 29 | * Applicable to jobs from the {@code stage} phase 30 | */ 31 | void customizeStage(FreeStyleJob job) 32 | 33 | /** 34 | * Applicable to jobs from the {@code prod} phase 35 | */ 36 | void customizeProd(FreeStyleJob job) 37 | } 38 | -------------------------------------------------------------------------------- /demo/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "2" 2 | services: 3 | jenkins: 4 | build: 5 | context: . 6 | args: 7 | gituser: "${PIPELINE_GIT_USERNAME}" 8 | gitpass: "${PIPELINE_GIT_PASSWORD}" 9 | gitsshkey: "${PIPELINE_GIT_SSH_KEY}" 10 | dockerRegistryOrg: "${DOCKER_REGISTRY_ORGANIZATION}" 11 | dockerRegistryUser: "${DOCKER_REGISTRY_USERNAME}" 12 | dockerRegistryPass: "${DOCKER_REGISTRY_PASSWORD}" 13 | dockerRegistryEmail: "${DOCKER_REGISTRY_EMAIL}" 14 | environment: 15 | FORKED_ORG: "${FORKED_ORG}" 16 | EXTERNAL_IP: "${EXTERNAL_IP}" 17 | ports: 18 | - "50000:50000" 19 | - "8080:8080" 20 | volumes: 21 | # The /var/jenkins_* paths might not work for Docker machine... 22 | - ~/jenkins_home:/var/jenkins_home 23 | - ~/jenkins_root:/root/ 24 | - /var/run/docker.sock:/var/run/docker.sock 25 | links: 26 | - artifactory 27 | artifactory: 28 | build: 29 | context: . 30 | dockerfile: Dockerfile-artifactory 31 | ports: 32 | - "8081:8081" 33 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | jobs: 3 | build: 4 | docker: 5 | - image: springcloud/pipeline-base 6 | environment: 7 | _JAVA_OPTIONS: "-Xms512m -Xmx1024m" 8 | GRADLE_OPTS: '-Dorg.gradle.jvmargs="-Xmx1024m -XX:+HeapDumpOnOutOfMemoryError"' 9 | TERM: dumb 10 | branches: 11 | ignore: 12 | - gh-pages # list of branches to ignore 13 | steps: 14 | - setup_remote_docker 15 | - checkout 16 | - run: 17 | name: "Running build" 18 | command: ./gradlew clean build --stacktrace 19 | - run: 20 | name: "Aggregate test results" 21 | when: always 22 | command: | 23 | mkdir -p $CIRCLE_TEST_REPORTS/junit/ 24 | find . -type f -regex ".*/target/.*-reports/.*" -exec cp {} $CIRCLE_TEST_REPORTS/junit/ \; 25 | bash <(curl -s https://codecov.io/bash) 26 | - store_artifacts: 27 | path: /junit/ 28 | destination: artifacts 29 | - store_test_results: 30 | path: /junit/ 31 | destination: testartifacts 32 | -------------------------------------------------------------------------------- /job-dsl/src/test/groovy/io/cloudpipelines/common/TestJobCustomizer.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.common 2 | 3 | import javaposse.jobdsl.dsl.jobs.FreeStyleJob 4 | 5 | /** 6 | * Test implementation of {@link JobCustomizer} that marks 7 | * a method implemented 8 | * 9 | * @author Marcin Grzejszczak 10 | */ 11 | class TestJobCustomizer implements JobCustomizer { 12 | 13 | public static boolean EXECUTED_ALL = false 14 | public static boolean EXECUTED_BUILD = false 15 | public static boolean EXECUTED_TEST = false 16 | public static boolean EXECUTED_STAGE = false 17 | public static boolean EXECUTED_PROD = false 18 | 19 | @Override 20 | void customizeAll(FreeStyleJob job) { 21 | EXECUTED_ALL = true 22 | } 23 | 24 | @Override 25 | void customizeBuild(FreeStyleJob job) { 26 | EXECUTED_BUILD = true 27 | } 28 | 29 | @Override 30 | void customizeTest(FreeStyleJob job) { 31 | EXECUTED_TEST = true 32 | } 33 | 34 | @Override 35 | void customizeStage(FreeStyleJob job) { 36 | EXECUTED_STAGE = true 37 | } 38 | 39 | @Override 40 | void customizeProd(FreeStyleJob job) { 41 | EXECUTED_PROD = true 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /declarative-pipeline/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'groovy' 2 | 3 | sourceSets { 4 | main { 5 | groovy { 6 | srcDirs 'jobs', 'src/main/groovy' 7 | } 8 | resources { 9 | srcDirs 'src/main/resources', 'src/main/bash' 10 | } 11 | } 12 | test { 13 | resources { 14 | srcDirs 'src/test/bats', 'src/test/docs_helper' 15 | } 16 | } 17 | } 18 | 19 | repositories { 20 | jcenter() 21 | mavenCentral() 22 | maven { url 'https://repo.jenkins-ci.org/releases/' } 23 | maven { url "https://repo.spring.io/libs-snapshot-local" } 24 | maven { url "https://repo.spring.io/libs-milestone-local" } 25 | maven { url "https://repo.spring.io/libs-release-local" } 26 | } 27 | 28 | configurations { 29 | libs 30 | compile.extendsFrom(libs) 31 | } 32 | 33 | dependencies { 34 | compile 'org.codehaus.groovy:groovy-all:2.4.7' 35 | compile "org.jenkins-ci.plugins:job-dsl-core:${jenkinsJobDslVersion}" 36 | compile "org.jenkins-ci.plugins:job-dsl:${jenkinsJobDslVersion}@jar" 37 | 38 | testCompile('org.spockframework:spock-core:1.0-groovy-2.4') { 39 | exclude module: 'groovy-all' 40 | } 41 | } 42 | 43 | test { 44 | testLogging { 45 | exceptionFormat = 'full' 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /job-dsl/src/main/bash/steps/download_latest_prod_binary.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -o errexit 3 | set -o errtrace 4 | set -o pipefail 5 | 6 | function fetchLatestProdJar() { 7 | local projectGroupId 8 | projectGroupId=$(retrieveGroupId) 9 | local appName 10 | appName=$(retrieveAppName) 11 | # Downloading latest jar 12 | echo "Last prod version equals ${LATEST_PROD_VERSION}" 13 | downloadAppBinary "${REPO_WITH_BINARIES}" "${projectGroupId}" "${appName}" "${LATEST_PROD_VERSION}" "${M2_SETTINGS_REPO_USERNAME}" "${M2_SETTINGS_REPO_PASSWORD}" 14 | mv "$(pwd)/${OUTPUT_FOLDER}/${appName}-${LATEST_PROD_VERSION}.${BINARY_EXTENSION}" "$(pwd)/${OUTPUT_FOLDER}/${appName}-${LATEST_PROD_VERSION}-latestprodversion.${BINARY_EXTENSION}" 15 | } 16 | 17 | export PAAS_TYPE=CF 18 | export ENVIRONMENT=BUILD 19 | 20 | # shellcheck source=/dev/null 21 | source "${WORKSPACE}"/.git/tools/src/main/bash/pipeline.sh 22 | 23 | # Find latest prod version 24 | readTestPropertiesFromFile "${OUTPUT_FOLDER}/trigger.properties" 25 | cat "${OUTPUT_FOLDER}/trigger.properties" 26 | if [[ -z "${LATEST_PROD_VERSION}" ]]; then 27 | echo "No prod release took place - skipping this step" 28 | else 29 | fetchLatestProdJar 30 | fi 31 | -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/DEMO_SETUP.adoc: -------------------------------------------------------------------------------- 1 | image::{demo-root-docs}/demo.png[caption="The overview of the demo: ", title="Github Webhook listens to HTTP calls and sends a message to Github Analytics"] 2 | 3 | {nbsp} 4 | {nbsp} 5 | 6 | For the demo scenario we have two applications. `Github Analytics` and `Github Webhook`. 7 | Let's imagine a case where Github is emitting events via HTTP. `Github Webhook` has 8 | an API that could register to such hooks and receive those messages. Once this happens 9 | `Github Webhook` sends a message by RabbitMQ to a channel. `Github Analytics` is 10 | listening to those messages and stores them in a MySQL database. 11 | 12 | image::{demo-root-docs}/demo_metrics.png[caption="Gathering metrics: ", title="Github Analytics exposes metrics that are polled by Prometheus"] 13 | 14 | {nbsp} 15 | {nbsp} 16 | 17 | `Github Analytics` has its KPIs (Key Performance Indicators) monitored. In the case 18 | of that application the KPI is number of issues. 19 | 20 | image::{demo-root-docs}/demo_alerting.png[caption="Alerting over metrics: ", title="Grafana alerts Slack over Prometheus metrics"] 21 | 22 | {nbsp} 23 | {nbsp} 24 | 25 | Let's assume that if we go below the threshold of X issues then an alert should be 26 | sent to Slack. 27 | -------------------------------------------------------------------------------- /docs/js/highlight/styles/monokai.min.css: -------------------------------------------------------------------------------- 1 | /* 2 | Monokai style - ported by Luigi Maselli - http://grigio.org 3 | */ 4 | 5 | .hljs { 6 | display: block; 7 | overflow-x: auto; 8 | padding: 0.5em; 9 | background: #272822; color: #ddd; 10 | } 11 | 12 | .hljs-tag, 13 | .hljs-keyword, 14 | .hljs-selector-tag, 15 | .hljs-literal, 16 | .hljs-strong, 17 | .hljs-name { 18 | color: #f92672; 19 | } 20 | 21 | .hljs-code { 22 | color: #66d9ef; 23 | } 24 | 25 | .hljs-class .hljs-title { 26 | color: white; 27 | } 28 | 29 | .hljs-attribute, 30 | .hljs-symbol, 31 | .hljs-regexp, 32 | .hljs-link { 33 | color: #bf79db; 34 | } 35 | 36 | .hljs-string, 37 | .hljs-bullet, 38 | .hljs-subst, 39 | .hljs-title, 40 | .hljs-section, 41 | .hljs-emphasis, 42 | .hljs-type, 43 | .hljs-built_in, 44 | .hljs-builtin-name, 45 | .hljs-selector-attr, 46 | .hljs-selector-pseudo, 47 | .hljs-addition, 48 | .hljs-variable, 49 | .hljs-template-tag, 50 | .hljs-template-variable { 51 | color: #a6e22e; 52 | } 53 | 54 | .hljs-comment, 55 | .hljs-quote, 56 | .hljs-deletion, 57 | .hljs-meta { 58 | color: #75715e; 59 | } 60 | 61 | .hljs-keyword, 62 | .hljs-selector-tag, 63 | .hljs-literal, 64 | .hljs-doctag, 65 | .hljs-title, 66 | .hljs-section, 67 | .hljs-type, 68 | .hljs-selector-id { 69 | font-weight: bold; 70 | } 71 | -------------------------------------------------------------------------------- /tools/k8s/jenkins-gce.yml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: jenkins 5 | spec: 6 | replicas: 1 7 | template: 8 | metadata: 9 | labels: 10 | name: jenkins 11 | spec: 12 | containers: 13 | - name: jenkins 14 | image: cloudpipelines/cloud-pipelines-jenkins:latest 15 | ports: 16 | - containerPort: 8080 17 | resources: 18 | requests: 19 | cpu: 10m 20 | env: 21 | - name: DOCKER_HOST 22 | value: tcp://localhost:2375 23 | - name: dind-daemon 24 | image: docker:1.12.6-dind 25 | resources: 26 | requests: 27 | cpu: 20m 28 | memory: 512Mi 29 | securityContext: 30 | privileged: true 31 | volumeMounts: 32 | - name: docker-graph-storage 33 | mountPath: /var/lib/docker 34 | - name: jenkinshome 35 | mountPath: /var/jenkins_home 36 | securityContext: 37 | fsGroup: 1000 38 | volumes: 39 | - name: docker-graph-storage 40 | emptyDir: {} 41 | - name: jenkinshome 42 | persistentVolumeClaim: 43 | claimName: jenkins-volume 44 | -------------------------------------------------------------------------------- /tools/k8s/jenkins-vsphere.yml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: jenkins 5 | spec: 6 | replicas: 1 7 | template: 8 | metadata: 9 | labels: 10 | name: jenkins 11 | spec: 12 | containers: 13 | - name: jenkins 14 | image: cloudpipelines/cloud-pipelines-jenkins:latest 15 | ports: 16 | - containerPort: 8080 17 | resources: 18 | requests: 19 | cpu: 10m 20 | env: 21 | - name: DOCKER_HOST 22 | value: tcp://localhost:2375 23 | - name: dind-daemon 24 | image: docker:1.12.6-dind 25 | resources: 26 | requests: 27 | cpu: 20m 28 | memory: 512Mi 29 | securityContext: 30 | privileged: true 31 | volumeMounts: 32 | - name: docker-graph-storage 33 | mountPath: /var/lib/docker 34 | - name: jenkinshome 35 | mountPath: /var/jenkins_home 36 | securityContext: 37 | fsGroup: 1000 38 | volumes: 39 | - name: docker-graph-storage 40 | emptyDir: {} 41 | - name: jenkinshome 42 | persistentVolumeClaim: 43 | claimName: jenkins-volume 44 | -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/JENKINS_RUN_SEED.adoc: -------------------------------------------------------------------------------- 1 | We created the seed job for you, but you have to run it. When you do 2 | run it, you have to provide some properties. By default we create a seed that 3 | has all the properties options, but you can delete most of it. If you 4 | set the properties as global environment variables, you have to remove them from the 5 | seed. 6 | 7 | To run the demo, provide a comma-separated 8 | list of the URLs of the two aforementioned forks (`github-webhook` and `github-analytics') in the `REPOS` variable. 9 | 10 | The following images shows the steps involved: 11 | 12 | {nbsp} 13 | {nbsp} 14 | 15 | image::{jenkins-root-docs}/seed_click.png[caption="Step 1: ", title="Click the 'jenkins-pipeline-seed-cf' job for Cloud Foundry and `jenkins-pipeline-seed-k8s` for Kubernetes"] 16 | 17 | {nbsp} 18 | {nbsp} 19 | 20 | image::{jenkins-root-docs}/seed_run.png[caption="Step 2: ", title="Click the 'Build with parameters'"] 21 | 22 | {nbsp} 23 | {nbsp} 24 | 25 | image::{jenkins-root-docs}/seed.png[caption="Step 3: ", title="The `REPOS` parameter should already contain your forked repos (you'll have more properties than the ones in the screenshot)"] 26 | 27 | {nbsp} 28 | {nbsp} 29 | 30 | image::{jenkins-root-docs}/seed_built.png[caption="Step 4: ", title="This is how the results of seed should look like"] 31 | -------------------------------------------------------------------------------- /docs/js/highlight/styles/zenburn.min.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Zenburn style from voldmar.ru (c) Vladimir Epifanov 4 | based on dark.css by Ivan Sagalaev 5 | 6 | */ 7 | 8 | .hljs { 9 | display: block; 10 | overflow-x: auto; 11 | padding: 0.5em; 12 | background: #3f3f3f; 13 | color: #dcdcdc; 14 | } 15 | 16 | .hljs-keyword, 17 | .hljs-selector-tag, 18 | .hljs-tag { 19 | color: #e3ceab; 20 | } 21 | 22 | .hljs-template-tag { 23 | color: #dcdcdc; 24 | } 25 | 26 | .hljs-number { 27 | color: #8cd0d3; 28 | } 29 | 30 | .hljs-variable, 31 | .hljs-template-variable, 32 | .hljs-attribute { 33 | color: #efdcbc; 34 | } 35 | 36 | .hljs-literal { 37 | color: #efefaf; 38 | } 39 | 40 | .hljs-subst { 41 | color: #8f8f8f; 42 | } 43 | 44 | .hljs-title, 45 | .hljs-name, 46 | .hljs-selector-id, 47 | .hljs-selector-class, 48 | .hljs-section, 49 | .hljs-type { 50 | color: #efef8f; 51 | } 52 | 53 | .hljs-symbol, 54 | .hljs-bullet, 55 | .hljs-link { 56 | color: #dca3a3; 57 | } 58 | 59 | .hljs-deletion, 60 | .hljs-string, 61 | .hljs-built_in, 62 | .hljs-builtin-name { 63 | color: #cc9393; 64 | } 65 | 66 | .hljs-addition, 67 | .hljs-comment, 68 | .hljs-quote, 69 | .hljs-meta { 70 | color: #7f9f7f; 71 | } 72 | 73 | 74 | .hljs-emphasis { 75 | font-style: italic; 76 | } 77 | 78 | .hljs-strong { 79 | font-weight: bold; 80 | } 81 | -------------------------------------------------------------------------------- /declarative-pipeline/jobs/jenkins_pipeline_jenkinsfile_empty.groovy: -------------------------------------------------------------------------------- 1 | import javaposse.jobdsl.dsl.DslFactory 2 | 3 | /** 4 | * This script contains a simple example of a Jenkinsfile approach that does nothing 5 | * but echos output. You can use this file as a simple template to build sth custom 6 | */ 7 | 8 | 9 | DslFactory dsl = this 10 | 11 | dsl.pipelineJob('jenkins-pipeline-jenkinsfile-empty') { 12 | definition { 13 | cps { 14 | script(""" 15 | node { 16 | stage 'Build and Upload' 17 | echo 'Building and Deploying' 18 | stage 'API compatibility check' 19 | echo 'Running API compatibility check' 20 | 21 | stage 'Deploy to test' 22 | echo 'Deploying to test' 23 | stage 'Tests on test' 24 | echo 'Running tests on test' 25 | stage 'Deploy to test latest prod version' 26 | echo 'Deploying to test latest prod version' 27 | stage 'Tests on test latest prod version' 28 | echo 'Running tests on test with latest prod version' 29 | 30 | stage 'Deploy to stage' 31 | echo 'Deploying to stage' 32 | stage 'End to end tests on stage' 33 | echo 'Running end to end tests on stage' 34 | 35 | stage 'Deploy to prod' 36 | echo 'Deploying to prod green instance' 37 | stage 'Complete switch over' 38 | echo 'Disabling blue instance' 39 | } 40 | """) 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /job-dsl/src/test/resources/spinnaker-jobs/views/Spinnaker.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | false 4 | false 5 | 6 | 7 | 8 | false 9 | false 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | spinnaker-foo-pipeline.* 24 | spinnaker-foo 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /docs/js/highlight/styles/dracula.min.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Dracula Theme v1.2.0 4 | 5 | https://github.com/zenorocha/dracula-theme 6 | 7 | Copyright 2015, All rights reserved 8 | 9 | Code licensed under the MIT license 10 | http://zenorocha.mit-license.org 11 | 12 | @author Éverton Ribeiro 13 | @author Zeno Rocha 14 | 15 | */ 16 | 17 | .hljs { 18 | display: block; 19 | overflow-x: auto; 20 | padding: 0.5em; 21 | background: #282a36; 22 | } 23 | 24 | .hljs-keyword, 25 | .hljs-selector-tag, 26 | .hljs-literal, 27 | .hljs-section, 28 | .hljs-link { 29 | color: #8be9fd; 30 | } 31 | 32 | .hljs-function .hljs-keyword { 33 | color: #ff79c6; 34 | } 35 | 36 | .hljs, 37 | .hljs-subst { 38 | color: #f8f8f2; 39 | } 40 | 41 | .hljs-string, 42 | .hljs-title, 43 | .hljs-name, 44 | .hljs-type, 45 | .hljs-attribute, 46 | .hljs-symbol, 47 | .hljs-bullet, 48 | .hljs-addition, 49 | .hljs-variable, 50 | .hljs-template-tag, 51 | .hljs-template-variable { 52 | color: #f1fa8c; 53 | } 54 | 55 | .hljs-comment, 56 | .hljs-quote, 57 | .hljs-deletion, 58 | .hljs-meta { 59 | color: #6272a4; 60 | } 61 | 62 | .hljs-keyword, 63 | .hljs-selector-tag, 64 | .hljs-literal, 65 | .hljs-title, 66 | .hljs-section, 67 | .hljs-doctag, 68 | .hljs-type, 69 | .hljs-name, 70 | .hljs-strong { 71 | font-weight: bold; 72 | } 73 | 74 | .hljs-emphasis { 75 | font-style: italic; 76 | } 77 | -------------------------------------------------------------------------------- /docs/js/highlight/styles/monokai-sublime.min.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Monokai Sublime style. Derived from Monokai by noformnocontent http://nn.mit-license.org/ 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 0.5em; 11 | background: #23241f; 12 | } 13 | 14 | .hljs, 15 | .hljs-tag, 16 | .hljs-subst { 17 | color: #f8f8f2; 18 | } 19 | 20 | .hljs-strong, 21 | .hljs-emphasis { 22 | color: #a8a8a2; 23 | } 24 | 25 | .hljs-bullet, 26 | .hljs-quote, 27 | .hljs-number, 28 | .hljs-regexp, 29 | .hljs-literal, 30 | .hljs-link { 31 | color: #ae81ff; 32 | } 33 | 34 | .hljs-code, 35 | .hljs-title, 36 | .hljs-section, 37 | .hljs-selector-class { 38 | color: #a6e22e; 39 | } 40 | 41 | .hljs-strong { 42 | font-weight: bold; 43 | } 44 | 45 | .hljs-emphasis { 46 | font-style: italic; 47 | } 48 | 49 | .hljs-keyword, 50 | .hljs-selector-tag, 51 | .hljs-name, 52 | .hljs-attr { 53 | color: #f92672; 54 | } 55 | 56 | .hljs-symbol, 57 | .hljs-attribute { 58 | color: #66d9ef; 59 | } 60 | 61 | .hljs-params, 62 | .hljs-class .hljs-title { 63 | color: #f8f8f2; 64 | } 65 | 66 | .hljs-string, 67 | .hljs-type, 68 | .hljs-built_in, 69 | .hljs-builtin-name, 70 | .hljs-selector-id, 71 | .hljs-selector-attr, 72 | .hljs-selector-pseudo, 73 | .hljs-addition, 74 | .hljs-variable, 75 | .hljs-template-variable { 76 | color: #e6db74; 77 | } 78 | 79 | .hljs-comment, 80 | .hljs-deletion, 81 | .hljs-meta { 82 | color: #75715e; 83 | } 84 | -------------------------------------------------------------------------------- /declarative-pipeline/src/test/groovy/io/cloudpipelines/JobScriptsSpec.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines 2 | 3 | import groovy.io.FileType 4 | import javaposse.jobdsl.dsl.DslScriptLoader 5 | import javaposse.jobdsl.dsl.GeneratedItems 6 | import javaposse.jobdsl.dsl.MemoryJobManagement 7 | import javaposse.jobdsl.dsl.ScriptRequest 8 | import spock.lang.Specification 9 | import spock.lang.Unroll 10 | /** 11 | * Tests that all dsl scripts in the jobs directory will compile. 12 | */ 13 | class JobScriptsSpec extends Specification { 14 | 15 | URL sample = JobScriptsSpec.getResource("/Jenkinsfile-sample") 16 | 17 | @Unroll 18 | def 'should compile script #file.name'() { 19 | given: 20 | 21 | MemoryJobManagement jm = new MemoryJobManagement() 22 | defaultStubbing(jm) 23 | jm.parameters << [ 24 | SCRIPTS_DIR: 'foo', 25 | JENKINSFILE_DIR: 'foo', 26 | TEST_MODE_DESCRIPTOR: '' 27 | ] 28 | DslScriptLoader loader = new DslScriptLoader(jm) 29 | 30 | when: 31 | GeneratedItems scripts = loader.runScripts([new ScriptRequest(file.text)]) 32 | 33 | then: 34 | noExceptionThrown() 35 | 36 | where: 37 | file << jobFiles() 38 | } 39 | 40 | private void defaultStubbing(MemoryJobManagement jm) { 41 | jm.availableFiles['foo/Jenkinsfile-sample'] = sample.text 42 | } 43 | 44 | static List jobFiles() { 45 | List files = [] 46 | new File('jobs').eachFileRecurse(FileType.FILES) { 47 | files << it 48 | } 49 | return files 50 | } 51 | 52 | } 53 | 54 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/common/BashFunctions.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.common 2 | 3 | import groovy.transform.CompileStatic 4 | 5 | /** 6 | * Useful bash functions 7 | * 8 | * @author Marcin Grzejszczak 9 | * @since 1.0.0 10 | */ 11 | @CompileStatic 12 | class BashFunctions { 13 | 14 | private final boolean gitUseSsh 15 | private final String gitUser 16 | private final String gitEmail 17 | 18 | BashFunctions(String gitUser, String gitEmail, boolean gitUseSsh) { 19 | this.gitUseSsh = gitUseSsh 20 | this.gitUser = gitUser 21 | this.gitEmail = gitEmail 22 | } 23 | 24 | BashFunctions(PipelineDefaults defaults) { 25 | this.gitUseSsh = defaults.gitUseSshKey() 26 | this.gitUser = defaults.gitName() 27 | this.gitEmail = defaults.gitEmail() 28 | } 29 | 30 | String setupGitCredentials(String repoUrl) { 31 | if (gitUseSsh) { 32 | return "" 33 | } 34 | String repoWithoutGit = repoUrl.startsWith("git@") ? repoUrl.substring("git@".length()) : repoUrl 35 | URI uri = URI.create(repoWithoutGit) 36 | String host = uri.getHost() 37 | return """\ 38 | set +x 39 | tmpDir="\$(mktemp -d)" 40 | trap "{ rm -rf \${tmpDir}; }" EXIT 41 | git config user.name "${gitUser}" 42 | git config user.email "${gitEmail}" 43 | git config credential.helper "store --file=\${tmpDir}/gitcredentials" 44 | echo "https://\$${EnvironmentVariables.GIT_USERNAME_ENV_VAR}:\$${EnvironmentVariables.GIT_PASSWORD_ENV_VAR}@${host}" > \${tmpDir}/gitcredentials 45 | """ 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /job-dsl/src/test/groovy/io/cloudpipelines/common/PipelineDescriptorSpec.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.common 2 | 3 | import spock.lang.Specification 4 | 5 | /** 6 | * @author Marcin Grzejszczak 7 | */ 8 | class PipelineDescriptorSpec extends Specification { 9 | def "should parse the pipeline descriptor"() { 10 | given: 11 | String yml = """ 12 | # This file describes which services are required by this application 13 | # in order for the smoke tests on the TEST environment and end to end tests 14 | # on the STAGE environment to pass 15 | 16 | # lowercase name of the environment 17 | test: 18 | # list of required services 19 | services: 20 | # Prepared for PCF DEV 21 | - name: github-rabbitmq 22 | type: broker 23 | broker: p-rabbitmq 24 | plan: standard 25 | - name: github-eureka 26 | type: app 27 | coordinates: com.example.eureka:github-eureka:0.0.1.M1 28 | pathToManifest: sc-pipelines/manifest-eureka.yml 29 | 30 | stage: 31 | services: 32 | # Prepared for PCF DEV 33 | - name: github-rabbitmq 34 | type: broker 35 | broker: p-rabbitmq 36 | plan: standard 37 | - name: github-eureka 38 | type: app 39 | coordinates: com.example.eureka:github-eureka:0.0.1.M1 40 | pathToManifest: sc-pipelines/manifest-eureka.yml 41 | """ 42 | when: 43 | PipelineDescriptor descriptor = PipelineDescriptor.from(yml) 44 | then: 45 | descriptor.test.services.size() == 2 46 | descriptor.stage.services.size() == 2 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /demo/src/test/groovy/io/cloudpipelines/SingleScriptPipelineSpec.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines 2 | 3 | import javaposse.jobdsl.dsl.DslScriptLoader 4 | import javaposse.jobdsl.dsl.GeneratedItems 5 | import javaposse.jobdsl.dsl.MemoryJobManagement 6 | import javaposse.jobdsl.dsl.ScriptRequest 7 | import spock.lang.Specification 8 | 9 | /** 10 | * Tests that all dsl scripts in the jobs directory will compile. 11 | */ 12 | class SingleScriptPipelineSpec extends Specification { 13 | 14 | //remove::start[CF] 15 | def 'should create seed job for CF'() { 16 | given: 17 | MemoryJobManagement jm = new MemoryJobManagement() 18 | DslScriptLoader loader = new DslScriptLoader(jm) 19 | 20 | when: 21 | GeneratedItems scripts = loader.runScripts([new ScriptRequest( 22 | new File("seed/jenkins_pipeline.groovy").text)]) 23 | 24 | then: 25 | noExceptionThrown() 26 | 27 | and: 28 | scripts.jobs.collect { it.jobName }.contains("jenkins-pipeline-cf-seed") 29 | } 30 | //remove::end[CF] 31 | 32 | //remove::start[K8S] 33 | def 'should create seed job for K8s'() { 34 | given: 35 | MemoryJobManagement jm = new MemoryJobManagement() 36 | DslScriptLoader loader = new DslScriptLoader(jm) 37 | 38 | when: 39 | GeneratedItems scripts = loader.runScripts([new ScriptRequest( 40 | new File("seed/jenkins_pipeline.groovy").text)]) 41 | 42 | then: 43 | noExceptionThrown() 44 | 45 | and: 46 | scripts.jobs.collect { it.jobName }.contains("jenkins-pipeline-k8s-seed") 47 | } 48 | //remove::end[K8S] 49 | 50 | } 51 | 52 | -------------------------------------------------------------------------------- /docs/js/highlight/styles/solarized-light.min.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Orginal Style from ethanschoonover.com/solarized (c) Jeremy Hull 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 0.5em; 11 | background: #fdf6e3; 12 | color: #657b83; 13 | } 14 | 15 | .hljs-comment, 16 | .hljs-quote { 17 | color: #93a1a1; 18 | } 19 | 20 | /* Solarized Green */ 21 | .hljs-keyword, 22 | .hljs-selector-tag, 23 | .hljs-addition { 24 | color: #859900; 25 | } 26 | 27 | /* Solarized Cyan */ 28 | .hljs-number, 29 | .hljs-string, 30 | .hljs-meta .hljs-meta-string, 31 | .hljs-literal, 32 | .hljs-doctag, 33 | .hljs-regexp { 34 | color: #2aa198; 35 | } 36 | 37 | /* Solarized Blue */ 38 | .hljs-title, 39 | .hljs-section, 40 | .hljs-name, 41 | .hljs-selector-id, 42 | .hljs-selector-class { 43 | color: #268bd2; 44 | } 45 | 46 | /* Solarized Yellow */ 47 | .hljs-attribute, 48 | .hljs-attr, 49 | .hljs-variable, 50 | .hljs-template-variable, 51 | .hljs-class .hljs-title, 52 | .hljs-type { 53 | color: #b58900; 54 | } 55 | 56 | /* Solarized Orange */ 57 | .hljs-symbol, 58 | .hljs-bullet, 59 | .hljs-subst, 60 | .hljs-meta, 61 | .hljs-meta .hljs-keyword, 62 | .hljs-selector-attr, 63 | .hljs-selector-pseudo, 64 | .hljs-link { 65 | color: #cb4b16; 66 | } 67 | 68 | /* Solarized Red */ 69 | .hljs-built_in, 70 | .hljs-deletion { 71 | color: #dc322f; 72 | } 73 | 74 | .hljs-formula { 75 | background: #eee8d5; 76 | } 77 | 78 | .hljs-emphasis { 79 | font-style: italic; 80 | } 81 | 82 | .hljs-strong { 83 | font-weight: bold; 84 | } 85 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/spinnaker/SpinnakerDefaultView.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.spinnaker 2 | 3 | import groovy.transform.CompileStatic 4 | import javaposse.jobdsl.dsl.DslFactory 5 | 6 | import io.cloudpipelines.common.Coordinates 7 | import io.cloudpipelines.common.PipelineDefaults 8 | import io.cloudpipelines.spinnaker.SpinnakerDefaults 9 | import io.cloudpipelines.projectcrawler.Repository 10 | 11 | /** 12 | * Default view for Spinnaker 13 | * 14 | * @author Marcin Grzejszczak 15 | * @since 1.0.0 16 | */ 17 | @CompileStatic 18 | class SpinnakerDefaultView { 19 | private final DslFactory dsl 20 | private final io.cloudpipelines.common.PipelineDefaults pipelineDefaults 21 | 22 | SpinnakerDefaultView(DslFactory dsl, io.cloudpipelines.common.PipelineDefaults pipelineDefaults) { 23 | this.dsl = dsl 24 | this.pipelineDefaults = pipelineDefaults 25 | } 26 | 27 | void view(List repositories) { 28 | dsl.nestedView('Spinnaker') { 29 | repositories.each { Repository repo -> 30 | Coordinates coordinates = Coordinates.fromRepo(repo, pipelineDefaults) 31 | String viewName = SpinnakerDefaults.viewName(coordinates.gitRepoName) 32 | String gitRepoName = SpinnakerDefaults.projectName(coordinates.gitRepoName) 33 | views { 34 | listView(viewName) { 35 | jobs { 36 | regex("${gitRepoName}.*") 37 | } 38 | columns { 39 | status() 40 | name() 41 | lastSuccess() 42 | lastFailure() 43 | lastBuildConsole() 44 | buildButton() 45 | } 46 | } 47 | } 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /docs/js/highlight/styles/an-old-hope.min.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | An Old Hope – Star Wars Syntax (c) Gustavo Costa 4 | Original theme - Ocean Dark Theme – by https://github.com/gavsiu 5 | Based on Jesse Leite's Atom syntax theme 'An Old Hope' – https://github.com/JesseLeite/an-old-hope-syntax-atom 6 | 7 | */ 8 | 9 | /* Death Star Comment */ 10 | .hljs-comment, 11 | .hljs-quote 12 | { 13 | color: #B6B18B; 14 | } 15 | 16 | /* Darth Vader */ 17 | .hljs-variable, 18 | .hljs-template-variable, 19 | .hljs-tag, 20 | .hljs-name, 21 | .hljs-selector-id, 22 | .hljs-selector-class, 23 | .hljs-regexp, 24 | .hljs-deletion 25 | { 26 | color: #EB3C54; 27 | } 28 | 29 | /* Threepio */ 30 | .hljs-number, 31 | .hljs-built_in, 32 | .hljs-builtin-name, 33 | .hljs-literal, 34 | .hljs-type, 35 | .hljs-params, 36 | .hljs-meta, 37 | .hljs-link 38 | { 39 | color: #E7CE56; 40 | } 41 | 42 | /* Luke Skywalker */ 43 | .hljs-attribute 44 | { 45 | color: #EE7C2B; 46 | } 47 | 48 | /* Obi Wan Kenobi */ 49 | .hljs-string, 50 | .hljs-symbol, 51 | .hljs-bullet, 52 | .hljs-addition 53 | { 54 | color: #4FB4D7; 55 | } 56 | 57 | /* Yoda */ 58 | .hljs-title, 59 | .hljs-section 60 | { 61 | color: #78BB65; 62 | } 63 | 64 | /* Mace Windu */ 65 | .hljs-keyword, 66 | .hljs-selector-tag 67 | { 68 | color: #B45EA4; 69 | } 70 | 71 | /* Millenium Falcon */ 72 | .hljs 73 | { 74 | display: block; 75 | overflow-x: auto; 76 | background: #1C1D21; 77 | color: #c0c5ce; 78 | padding: 0.5em; 79 | } 80 | 81 | .hljs-emphasis 82 | { 83 | font-style: italic; 84 | } 85 | 86 | .hljs-strong 87 | { 88 | font-weight: bold; 89 | } 90 | -------------------------------------------------------------------------------- /docs/js/highlight/styles/github.min.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | github.com style (c) Vasily Polovnyov 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 0.5em; 11 | color: #333; 12 | background: #f8f8f8; 13 | } 14 | 15 | .hljs-comment, 16 | .hljs-quote { 17 | color: #998; 18 | font-style: italic; 19 | } 20 | 21 | .hljs-keyword, 22 | .hljs-selector-tag, 23 | .hljs-subst { 24 | color: #333; 25 | font-weight: bold; 26 | } 27 | 28 | .hljs-number, 29 | .hljs-literal, 30 | .hljs-variable, 31 | .hljs-template-variable, 32 | .hljs-tag .hljs-attr { 33 | color: #008080; 34 | } 35 | 36 | .hljs-string, 37 | .hljs-doctag { 38 | color: #d14; 39 | } 40 | 41 | .hljs-title, 42 | .hljs-section, 43 | .hljs-selector-id { 44 | color: #900; 45 | font-weight: bold; 46 | } 47 | 48 | .hljs-subst { 49 | font-weight: normal; 50 | } 51 | 52 | .hljs-type, 53 | .hljs-class .hljs-title { 54 | color: #458; 55 | font-weight: bold; 56 | } 57 | 58 | .hljs-tag, 59 | .hljs-name, 60 | .hljs-attribute { 61 | color: #000080; 62 | font-weight: normal; 63 | } 64 | 65 | .hljs-regexp, 66 | .hljs-link { 67 | color: #009926; 68 | } 69 | 70 | .hljs-symbol, 71 | .hljs-bullet { 72 | color: #990073; 73 | } 74 | 75 | .hljs-built_in, 76 | .hljs-builtin-name { 77 | color: #0086b3; 78 | } 79 | 80 | .hljs-meta { 81 | color: #999; 82 | font-weight: bold; 83 | } 84 | 85 | .hljs-deletion { 86 | background: #fdd; 87 | } 88 | 89 | .hljs-addition { 90 | background: #dfd; 91 | } 92 | 93 | .hljs-emphasis { 94 | font-style: italic; 95 | } 96 | 97 | .hljs-strong { 98 | font-weight: bold; 99 | } 100 | -------------------------------------------------------------------------------- /docs/js/highlight/styles/atom-one-dark.min.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Atom One Dark by Daniel Gamage 4 | Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax 5 | 6 | base: #282c34 7 | mono-1: #abb2bf 8 | mono-2: #818896 9 | mono-3: #5c6370 10 | hue-1: #56b6c2 11 | hue-2: #61aeee 12 | hue-3: #c678dd 13 | hue-4: #98c379 14 | hue-5: #e06c75 15 | hue-5-2: #be5046 16 | hue-6: #d19a66 17 | hue-6-2: #e6c07b 18 | 19 | */ 20 | 21 | .hljs { 22 | display: block; 23 | overflow-x: auto; 24 | padding: 0.5em; 25 | color: #abb2bf; 26 | background: #282c34; 27 | } 28 | 29 | .hljs-comment, 30 | .hljs-quote { 31 | color: #5c6370; 32 | font-style: italic; 33 | } 34 | 35 | .hljs-doctag, 36 | .hljs-keyword, 37 | .hljs-formula { 38 | color: #c678dd; 39 | } 40 | 41 | .hljs-section, 42 | .hljs-name, 43 | .hljs-selector-tag, 44 | .hljs-deletion, 45 | .hljs-subst { 46 | color: #e06c75; 47 | } 48 | 49 | .hljs-literal { 50 | color: #56b6c2; 51 | } 52 | 53 | .hljs-string, 54 | .hljs-regexp, 55 | .hljs-addition, 56 | .hljs-attribute, 57 | .hljs-meta-string { 58 | color: #98c379; 59 | } 60 | 61 | .hljs-built_in, 62 | .hljs-class .hljs-title { 63 | color: #e6c07b; 64 | } 65 | 66 | .hljs-attr, 67 | .hljs-variable, 68 | .hljs-template-variable, 69 | .hljs-type, 70 | .hljs-selector-class, 71 | .hljs-selector-attr, 72 | .hljs-selector-pseudo, 73 | .hljs-number { 74 | color: #d19a66; 75 | } 76 | 77 | .hljs-symbol, 78 | .hljs-bullet, 79 | .hljs-link, 80 | .hljs-meta, 81 | .hljs-selector-id, 82 | .hljs-title { 83 | color: #61aeee; 84 | } 85 | 86 | .hljs-emphasis { 87 | font-style: italic; 88 | } 89 | 90 | .hljs-strong { 91 | font-weight: bold; 92 | } 93 | 94 | .hljs-link { 95 | text-decoration: underline; 96 | } 97 | -------------------------------------------------------------------------------- /docs/js/highlight/styles/atom-one-light.min.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Atom One Light by Daniel Gamage 4 | Original One Light Syntax theme from https://github.com/atom/one-light-syntax 5 | 6 | base: #fafafa 7 | mono-1: #383a42 8 | mono-2: #686b77 9 | mono-3: #a0a1a7 10 | hue-1: #0184bb 11 | hue-2: #4078f2 12 | hue-3: #a626a4 13 | hue-4: #50a14f 14 | hue-5: #e45649 15 | hue-5-2: #c91243 16 | hue-6: #986801 17 | hue-6-2: #c18401 18 | 19 | */ 20 | 21 | .hljs { 22 | display: block; 23 | overflow-x: auto; 24 | padding: 0.5em; 25 | color: #383a42; 26 | background: #fafafa; 27 | } 28 | 29 | .hljs-comment, 30 | .hljs-quote { 31 | color: #a0a1a7; 32 | font-style: italic; 33 | } 34 | 35 | .hljs-doctag, 36 | .hljs-keyword, 37 | .hljs-formula { 38 | color: #a626a4; 39 | } 40 | 41 | .hljs-section, 42 | .hljs-name, 43 | .hljs-selector-tag, 44 | .hljs-deletion, 45 | .hljs-subst { 46 | color: #e45649; 47 | } 48 | 49 | .hljs-literal { 50 | color: #0184bb; 51 | } 52 | 53 | .hljs-string, 54 | .hljs-regexp, 55 | .hljs-addition, 56 | .hljs-attribute, 57 | .hljs-meta-string { 58 | color: #50a14f; 59 | } 60 | 61 | .hljs-built_in, 62 | .hljs-class .hljs-title { 63 | color: #c18401; 64 | } 65 | 66 | .hljs-attr, 67 | .hljs-variable, 68 | .hljs-template-variable, 69 | .hljs-type, 70 | .hljs-selector-class, 71 | .hljs-selector-attr, 72 | .hljs-selector-pseudo, 73 | .hljs-number { 74 | color: #986801; 75 | } 76 | 77 | .hljs-symbol, 78 | .hljs-bullet, 79 | .hljs-link, 80 | .hljs-meta, 81 | .hljs-selector-id, 82 | .hljs-title { 83 | color: #4078f2; 84 | } 85 | 86 | .hljs-emphasis { 87 | font-style: italic; 88 | } 89 | 90 | .hljs-strong { 91 | font-weight: bold; 92 | } 93 | 94 | .hljs-link { 95 | text-decoration: underline; 96 | } 97 | -------------------------------------------------------------------------------- /gradle/dist.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | Contains tasks and setup to use for dist generation and releasing 3 | */ 4 | buildscript { 5 | repositories { jcenter() } 6 | 7 | dependencies { 8 | classpath 'org.ajoberstar:grgit:2.2.1' 9 | } 10 | } 11 | 12 | import org.ajoberstar.grgit.Grgit 13 | 14 | apply plugin: 'distribution' 15 | 16 | ext { 17 | git = Grgit.open() 18 | revision = git.head().id 19 | } 20 | 21 | distributions { 22 | main { 23 | contents { 24 | from(project.rootDir) { 25 | include "**/*.*" 26 | exclude "**/test/**", "**/build/**", "**/*.tar.gz", "**/*.tgz", 27 | "**/.idea/**", "**/target/**", "**/*.iml", "**/out/**", "**/.gradle/**", 28 | "**/docs/**", "**/docs-sources/**", "**/dist/**" 29 | String gitignore = new File(project.rootDir, ".gitignore").text 30 | exclude gitignore.readLines().findAll { it && !it.startsWith("#") }.collect { "**/${it}"} 31 | } 32 | from(project.buildDir) { 33 | include "VERSION" 34 | } 35 | } 36 | } 37 | } 38 | 39 | task dumpBuildInfo() { 40 | doLast { 41 | String versionContents = """\ 42 | buildDate: ${new Date().format('dd-MM-yyyy HH:mm:ss')} 43 | revision : ${revision} 44 | version : ${project.version} 45 | """ 46 | def fileToStore = new File(project.buildDir, "VERSION") 47 | project.buildDir.mkdirs() 48 | fileToStore.createNewFile() 49 | fileToStore.text = versionContents 50 | } 51 | } 52 | 53 | distTar { 54 | version = "" 55 | compression = "GZIP" 56 | extension = "tar.gz" 57 | dependsOn("dumpBuildInfo") 58 | destinationDir = new File(project.rootDir, "dist") 59 | enabled = !project.hasProperty("skipDist") 60 | } 61 | 62 | distZip { 63 | version = "" 64 | destinationDir = new File(project.rootDir, "dist") 65 | enabled = !project.hasProperty("skipDist") 66 | } 67 | 68 | // TODO: Add releasing 69 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/common/PipelineDescriptor.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.common 2 | 3 | import com.fasterxml.jackson.databind.DeserializationFeature 4 | import com.fasterxml.jackson.databind.ObjectMapper 5 | import com.fasterxml.jackson.dataformat.yaml.YAMLFactory 6 | import groovy.transform.CompileStatic 7 | 8 | /** 9 | * The model representing {@code cloud-pipelines.yml} descriptor 10 | * 11 | * @author Marcin Grzejszczak 12 | * @since 1.0.0 13 | */ 14 | @CompileStatic 15 | class PipelineDescriptor { 16 | String language_type 17 | Build build = new Build() 18 | Pipeline pipeline = new Pipeline() 19 | Environment test = new Environment() 20 | Environment stage = new Environment() 21 | Environment prod = new Environment() 22 | 23 | boolean hasMonoRepoProjects() { 24 | return !pipeline.project_names.empty 25 | } 26 | 27 | @CompileStatic 28 | static class Build { 29 | String main_module 30 | } 31 | 32 | @CompileStatic 33 | static class Pipeline { 34 | List project_names = [] 35 | Boolean api_compatibility_step 36 | Boolean test_step 37 | Boolean rollback_step 38 | Boolean stage_step 39 | Boolean auto_stage 40 | Boolean auto_prod 41 | } 42 | 43 | @CompileStatic 44 | static class Environment { 45 | List services = [] 46 | String deployment_strategy = "" 47 | } 48 | 49 | @CompileStatic 50 | static class Service { 51 | String type, name, coordinates, pathToManifest, broker, plan 52 | } 53 | 54 | static PipelineDescriptor from(String yaml) { 55 | if (!yaml) { 56 | return new PipelineDescriptor() 57 | } 58 | ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory()) 59 | objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) 60 | return objectMapper.readValue(yaml, PipelineDescriptor) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/JENKINS_RUN_PIPELINE.adoc: -------------------------------------------------------------------------------- 1 | We already created the seed job for you, but you have to run it. When you do 2 | run it, you have to provide some properties. By default, we create a seed that 3 | has all the properties options, but you can delete most of it. If you 4 | set the properties as global environment variables, you have to remove them from the 5 | seed. 6 | 7 | To run the demo, provide a comma-separated 8 | list of URLs of the two aforementioned forks (`github-webhook` and `github-analytics`) in the `REPOS` variable. 9 | 10 | The following images shows the steps involved: 11 | 12 | {nbsp} 13 | {nbsp} 14 | 15 | image::{jenkins-root-docs}/seed_views.png[caption="Step 1: ", title="Click the 'github-webhook' view"] 16 | 17 | {nbsp} 18 | {nbsp} 19 | 20 | image::{jenkins-root-docs}/pipeline_run.png[caption="Step 2: ", title="Run the pipeline"] 21 | 22 | {nbsp} 23 | {nbsp} 24 | 25 | IMPORTANT: If your build fails on *deploy previous version to stage* due to a missing jar, 26 | that means that you forgot to clear the tags in your repository. Typically, that happens because 27 | you removed the Artifactory volume with a deployed jar while a tag in the repository still points there. 28 | See <> for how to remove the tag. 29 | 30 | {nbsp} 31 | {nbsp} 32 | 33 | image::{jenkins-root-docs}/pipeline_manual.png[caption="Step 3: ", title="Click the manual step to go to stage (remember about killing the apps on test env). To do this click the *ARROW* next to the job name"] 34 | 35 | {nbsp} 36 | {nbsp} 37 | 38 | IMPORTANT: Servers often run run out of resources at the stage step. 39 | For that reason, we suggest killing all applications on test. See the <> for more detail. 40 | 41 | {nbsp} 42 | {nbsp} 43 | 44 | image::{jenkins-root-docs}/pipeline_finished.png[caption="Step 4: ", title="The full pipeline should look like this"] 45 | 46 | {nbsp} 47 | {nbsp} 48 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/common/StepEnabledChecker.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.common 2 | 3 | import groovy.transform.CompileStatic 4 | 5 | /** 6 | * Knows whether given stage should be enabled or automatic basing on values 7 | * from the descriptor or environment variables 8 | * 9 | * @author Marcin Grzejszczak 10 | * @since 1.0.0 11 | */ 12 | @CompileStatic 13 | class StepEnabledChecker { 14 | 15 | private final PipelineDescriptor descriptor 16 | private final PipelineDefaults defaults 17 | 18 | StepEnabledChecker(PipelineDescriptor descriptor, PipelineDefaults defaults) { 19 | this.descriptor = descriptor 20 | this.defaults = defaults 21 | } 22 | 23 | boolean autoProdSet() { 24 | return valueOrDefaultIfNull(descriptor.pipeline.auto_prod, defaults.autoProd()) 25 | } 26 | 27 | boolean apiCompatibilityStepSet() { 28 | return valueOrDefaultIfNull(descriptor.pipeline.api_compatibility_step, defaults.apiCompatibilityStep()) 29 | } 30 | 31 | boolean stageStepSet() { 32 | return valueOrDefaultIfNull(descriptor.pipeline.stage_step, defaults.stageStep()) 33 | } 34 | 35 | boolean stageStepMissing() { 36 | return !stageStepSet() 37 | } 38 | 39 | boolean autoStageSet() { 40 | return valueOrDefaultIfNull(descriptor.pipeline.auto_stage, defaults.autoStage()) 41 | } 42 | 43 | boolean rollbackStepSet() { 44 | return valueOrDefaultIfNull(descriptor.pipeline.rollback_step, 45 | defaults.rollbackStep()) && testStepSet() 46 | } 47 | 48 | boolean rollbackStepMissing() { 49 | return !rollbackStepSet() 50 | } 51 | 52 | boolean testStepSet() { 53 | return valueOrDefaultIfNull(descriptor.pipeline.test_step, defaults.testStep()) 54 | } 55 | 56 | boolean testStepMissing() { 57 | return !testStepSet() 58 | } 59 | 60 | private boolean valueOrDefaultIfNull(Boolean value, boolean defaultValue) { 61 | return value == null ? defaultValue : value 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /job-dsl/src/test/resources/default-pipeline/views/Pipelines.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | false 4 | false 5 | 6 | 7 | 8 | false 9 | false 10 | 11 | 5 12 | false 13 | 1 14 | none 15 | true 16 | 5 17 | true 18 | true 19 | true 20 | 21 | 22 | Deploy foo to production 23 | foo-pipeline-build 24 | 25 | 26 | true 27 | true 28 | true 29 | true 30 | true 31 | true 32 | foo 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /docs/js/highlight/styles/atom-one-dark-reasonable.min.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Atom One Dark With support for ReasonML by Gidi Morris, based off work by Daniel Gamage 4 | 5 | Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax 6 | 7 | */ 8 | .hljs { 9 | display: block; 10 | overflow-x: auto; 11 | padding: 0.5em; 12 | line-height: 1.3em; 13 | color: #abb2bf; 14 | background: #282c34; 15 | border-radius: 5px; 16 | } 17 | .hljs-keyword, .hljs-operator { 18 | color: #F92672; 19 | } 20 | .hljs-pattern-match { 21 | color: #F92672; 22 | } 23 | .hljs-pattern-match .hljs-constructor { 24 | color: #61aeee; 25 | } 26 | .hljs-function { 27 | color: #61aeee; 28 | } 29 | .hljs-function .hljs-params { 30 | color: #A6E22E; 31 | } 32 | .hljs-function .hljs-params .hljs-typing { 33 | color: #FD971F; 34 | } 35 | .hljs-module-access .hljs-module { 36 | color: #7e57c2; 37 | } 38 | .hljs-constructor { 39 | color: #e2b93d; 40 | } 41 | .hljs-constructor .hljs-string { 42 | color: #9CCC65; 43 | } 44 | .hljs-comment, .hljs-quote { 45 | color: #b18eb1; 46 | font-style: italic; 47 | } 48 | .hljs-doctag, .hljs-formula { 49 | color: #c678dd; 50 | } 51 | .hljs-section, .hljs-name, .hljs-selector-tag, .hljs-deletion, .hljs-subst { 52 | color: #e06c75; 53 | } 54 | .hljs-literal { 55 | color: #56b6c2; 56 | } 57 | .hljs-string, .hljs-regexp, .hljs-addition, .hljs-attribute, .hljs-meta-string { 58 | color: #98c379; 59 | } 60 | .hljs-built_in, .hljs-class .hljs-title { 61 | color: #e6c07b; 62 | } 63 | .hljs-attr, .hljs-variable, .hljs-template-variable, .hljs-type, .hljs-selector-class, .hljs-selector-attr, .hljs-selector-pseudo, .hljs-number { 64 | color: #d19a66; 65 | } 66 | .hljs-symbol, .hljs-bullet, .hljs-link, .hljs-meta, .hljs-selector-id, .hljs-title { 67 | color: #61aeee; 68 | } 69 | .hljs-emphasis { 70 | font-style: italic; 71 | } 72 | .hljs-strong { 73 | font-weight: bold; 74 | } 75 | .hljs-link { 76 | text-decoration: underline; 77 | } 78 | -------------------------------------------------------------------------------- /docs/js/highlight/styles/a11y-dark.min.css: -------------------------------------------------------------------------------- 1 | /* a11y-dark theme */ 2 | /* Based on the Tomorrow Night Eighties theme: https://github.com/isagalaev/highlight.js/blob/master/src/styles/tomorrow-night-eighties.css */ 3 | /* @author: ericwbailey */ 4 | 5 | /* Comment */ 6 | .hljs-comment, 7 | .hljs-quote { 8 | color: #d4d0ab; 9 | } 10 | 11 | /* Red */ 12 | .hljs-variable, 13 | .hljs-template-variable, 14 | .hljs-tag, 15 | .hljs-name, 16 | .hljs-selector-id, 17 | .hljs-selector-class, 18 | .hljs-regexp, 19 | .hljs-deletion { 20 | color: #ffa07a; 21 | } 22 | 23 | /* Orange */ 24 | .hljs-number, 25 | .hljs-built_in, 26 | .hljs-builtin-name, 27 | .hljs-literal, 28 | .hljs-type, 29 | .hljs-params, 30 | .hljs-meta, 31 | .hljs-link { 32 | color: #f5ab35; 33 | } 34 | 35 | /* Yellow */ 36 | .hljs-attribute { 37 | color: #ffd700; 38 | } 39 | 40 | /* Green */ 41 | .hljs-string, 42 | .hljs-symbol, 43 | .hljs-bullet, 44 | .hljs-addition { 45 | color: #abe338; 46 | } 47 | 48 | /* Blue */ 49 | .hljs-title, 50 | .hljs-section { 51 | color: #00e0e0; 52 | } 53 | 54 | /* Purple */ 55 | .hljs-keyword, 56 | .hljs-selector-tag { 57 | color: #dcc6e0; 58 | } 59 | 60 | .hljs { 61 | display: block; 62 | overflow-x: auto; 63 | background: #2b2b2b; 64 | color: #f8f8f2; 65 | padding: 0.5em; 66 | } 67 | 68 | .hljs-emphasis { 69 | font-style: italic; 70 | } 71 | 72 | .hljs-strong { 73 | font-weight: bold; 74 | } 75 | 76 | @media screen and (-ms-high-contrast: active) { 77 | .hljs-addition, 78 | .hljs-attribute, 79 | .hljs-built_in, 80 | .hljs-builtin-name, 81 | .hljs-bullet, 82 | .hljs-comment, 83 | .hljs-link, 84 | .hljs-literal, 85 | .hljs-meta, 86 | .hljs-number, 87 | .hljs-params, 88 | .hljs-string, 89 | .hljs-symbol, 90 | .hljs-type, 91 | .hljs-quote { 92 | color: highlight; 93 | } 94 | 95 | .hljs-keyword, 96 | .hljs-selector-tag { 97 | font-weight: bold; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/CUSTOMIZATION.adoc: -------------------------------------------------------------------------------- 1 | == Customizing the Project 2 | 3 | Cloud Pipelines offers a way to override the way pipelines are built 4 | 5 | * <> 6 | * <> 7 | 8 | [[customization-overriding-project-setup]] 9 | === Overriding Project Setup 10 | 11 | If you want to customize the Cloud Pipelines build, you can update the contents 12 | of the `gradle/custom.gradle` build script. That way your customizations will not 13 | interfere with the changes in the main part of the code, thus there should be 14 | no merge conflicts when pulling the changes from Cloud Pipeline repositories. 15 | 16 | [[customization-overriding-pipelines]] 17 | === Overriding Pipelines 18 | 19 | Currently, the best way to extend Jenkins Jenkinsfile pipelines is to make 20 | a copy of the Jenkins seed and pipeline jobs. 21 | 22 | ==== Overriding Jenkins Job DSL pipelines 23 | 24 | We provide an interface (called `io.cloudpipelines.common.JobCustomizer`) 25 | that lets you provide customization for: 26 | 27 | * all jobs 28 | * build jobs 29 | * test jobs 30 | * stage jobs 31 | * prod jobs 32 | 33 | We use the JDK's `java.util.ServiceLoader` mechanism to achieve extensibility. 34 | 35 | You can write an implementation of that interface (for example, `com.example.MyJubCustomizer`) 36 | and create a `META-INF/io.cloudpipelines.common.JobCustomizer` file in which you put the 37 | `com.example.MyJubCustomizer` line. 38 | 39 | If you create a JAR with your class (for example `com.example:my-customizer:1.0.0`), 40 | put it on the build classpath, as the following example shows: 41 | 42 | ==== 43 | [source,groovy] 44 | ---- 45 | dependencies { 46 | // ... 47 | libs "com.example:my-customizer:1.0.0" 48 | // ... 49 | } 50 | ---- 51 | ==== 52 | 53 | If you do not want to create a separate library, you can create an implementation in the 54 | sources under `src/main/resources/META-INF`. 55 | 56 | Regardless of what you chose, your implementation runs for each job. You can add notifications 57 | or any other customizations of your choosing. 58 | -------------------------------------------------------------------------------- /job-dsl/src/test/groovy/io/cloudpipelines/util/XmlComparator.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.util 2 | 3 | import groovy.transform.CompileStatic 4 | 5 | /** 6 | * @author Marcin Grzejszczak 7 | */ 8 | import groovy.xml.XmlUtil 9 | import javaposse.jobdsl.dsl.Item 10 | import javaposse.jobdsl.dsl.MemoryJobManagement 11 | import org.xmlunit.builder.DiffBuilder 12 | import org.xmlunit.diff.DefaultNodeMatcher 13 | import org.xmlunit.diff.Diff 14 | import org.xmlunit.diff.ElementSelectors 15 | 16 | @CompileStatic 17 | trait XmlComparator { 18 | 19 | void assertJobsAndViews(MemoryJobManagement jm) { 20 | jm.savedConfigs.each { 21 | assertThatJobIsOk(it.key, it.value) 22 | } 23 | jm.savedViews.each { 24 | assertThatViewIsOk(it.key, it.value) 25 | } 26 | } 27 | 28 | String folderName() { 29 | return "default_pipeline" 30 | } 31 | 32 | void assertThatJobIsOk(String name, String value) { 33 | compareXmls("/${folderName()}/jobs/${name}.xml", value) 34 | } 35 | 36 | void assertThatViewIsOk(String name, String value) { 37 | compareXmls("/${folderName()}/views/${name}.xml", value) 38 | } 39 | 40 | void compareXmls(String file, String nodeToCompare) { 41 | String referenceXml = XmlUtil.serialize(getFileContent(file)).stripIndent().stripMargin() 42 | String nodeXml = XmlUtil.serialize(nodeToCompare).stripIndent().stripMargin() 43 | Diff diff = DiffBuilder.compare(referenceXml).withTest(nodeXml) 44 | .ignoreWhitespace() 45 | .ignoreElementContentWhitespace() 46 | .ignoreComments() 47 | .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byName)) 48 | .checkForSimilar() 49 | .build() 50 | if (diff.hasDifferences()) { 51 | throw new XmlsAreNotSimilar(file, diff.getDifferences()) 52 | } 53 | } 54 | 55 | private static String getFileContent(String file) { 56 | new File(XmlComparator.getResource(file).toURI()).getCanonicalFile().text 57 | } 58 | 59 | static class XmlsAreNotSimilar extends RuntimeException { 60 | XmlsAreNotSimilar(String file, Iterable diffs) { 61 | super("For file [$file] the following differences where found [$diffs]") 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/JENKINS_BLUE_OCEAN.adoc: -------------------------------------------------------------------------------- 1 | You can also use the https://jenkins.io/doc/book/pipeline/syntax/[declarative pipeline] approach with the 2 | https://jenkins.io/projects/blueocean/[Blue Ocean UI]. 3 | 4 | The Blue Ocean UI is available under the `blue/` URL (for example, for Docker Machine-based setup: `https://192.168.99.100:8080/blue`). 5 | 6 | The following images show the various steps involved: 7 | 8 | {nbsp} 9 | {nbsp} 10 | 11 | image::{jenkins-root-docs}/blue_1.png[caption="Step 1: ", title="Open Blue Ocean UI and click on `github-webhook-declarative-pipeline`"] 12 | 13 | {nbsp} 14 | {nbsp} 15 | 16 | image::{jenkins-root-docs}/blue_2.png[caption="Step 2: ", title="Your first run will look like this. Click `Run` button"] 17 | 18 | {nbsp} 19 | {nbsp} 20 | 21 | image::{jenkins-root-docs}/blue_3.png[caption="Step 3: ", title="Enter parameters required for the build and click `run`"] 22 | 23 | {nbsp} 24 | {nbsp} 25 | 26 | image::{jenkins-root-docs}/blue_4.png[caption="Step 4: ", title="A list of pipelines will be shown. Click your first run."] 27 | 28 | {nbsp} 29 | {nbsp} 30 | 31 | image::{jenkins-root-docs}/blue_5.png[caption="Step 5: ", title="State if you want to go to production or not and click `Proceed`"] 32 | 33 | {nbsp} 34 | {nbsp} 35 | 36 | image::{jenkins-root-docs}/blue_6.png[caption="Step 6: ", title="The build is in progress..."] 37 | 38 | {nbsp} 39 | {nbsp} 40 | 41 | image::{jenkins-root-docs}/blue_7.png[caption="Step 7: ", title="The pipeline is done!"] 42 | 43 | {nbsp} 44 | {nbsp} 45 | 46 | 47 | IMPORTANT: There is no possibility of restarting a pipeline from a specific stage after failure. 48 | See https://issues.jenkins-ci.org/browse/JENKINS-33846[this issue] for more information 49 | 50 | WARNING: Currently, there is no way to introduce manual steps in a performant way. Jenkins 51 | blocks an executor when a manual step is required. That means that you run out of executors 52 | pretty quickly. See https://issues.jenkins-ci.org/browse/JENKINS-36235[this issue] 53 | and https://stackoverflow.com/questions/42561241/how-to-wait-for-user-input-in-a-declarative-pipeline-without-blocking-a-heavywei[this StackOverflow question] 54 | for more information. 55 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/common/Coordinates.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.common 2 | 3 | import groovy.transform.CompileStatic 4 | import groovy.transform.Immutable 5 | 6 | import io.cloudpipelines.projectcrawler.Repository 7 | 8 | /** 9 | * Git repo (either https or ssh) together with the proper project 10 | * and branch names 11 | * 12 | * @author Marcin Grzejszczak 13 | * @since 1.0.0 14 | */ 15 | @CompileStatic 16 | @Immutable 17 | class Coordinates { 18 | String gitRepoName 19 | String fullGitRepo 20 | String branchName 21 | 22 | static Coordinates fromRepo(Repository repository, PipelineDefaults defaults) { 23 | String repo = defaults.gitUseSshKey() ? repository.ssh_url : repository.clone_url 24 | String gitRepoName = repo.split('/').last() - '.git' 25 | String fullGitRepo = "" 26 | String branchName = "master" 27 | int customNameIndex = repo.indexOf('$') 28 | int customBranchIndex = repo.indexOf('#') 29 | if (customNameIndex == -1 && customBranchIndex == -1) { 30 | // url 31 | fullGitRepo = repo 32 | branchName = "master" 33 | } else if (customNameIndex > -1 && (customNameIndex < customBranchIndex || customBranchIndex == -1)) { 34 | fullGitRepo = repo.substring(0, customNameIndex) 35 | if (customNameIndex < customBranchIndex) { 36 | // url$newName#someBranch 37 | gitRepoName = repo.substring(customNameIndex + 1, customBranchIndex) 38 | branchName = repo.substring(customBranchIndex + 1) 39 | } else if (customBranchIndex == -1) { 40 | // url$newName 41 | gitRepoName = repo.substring(customNameIndex + 1) 42 | } 43 | } else if (customBranchIndex > -1) { 44 | fullGitRepo = repo.substring(0, customBranchIndex) 45 | if (customBranchIndex < customNameIndex) { 46 | // url#someBranch$newName 47 | gitRepoName = repo.substring(customNameIndex + 1) 48 | branchName = repo.substring(customBranchIndex + 1, customNameIndex) 49 | } else if (customNameIndex == -1) { 50 | // url#someBranch 51 | gitRepoName = repo.substring(repo.lastIndexOf("/") + 1, customBranchIndex) 52 | branchName = repo.substring(customBranchIndex + 1) 53 | } 54 | } 55 | return new Coordinates(gitRepoName, fullGitRepo, branchName) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /job-dsl/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'groovy' 2 | apply from: "${project.rootDir}/gradle/bash.gradle" 3 | 4 | sourceSets { 5 | main { 6 | groovy { 7 | srcDirs 'jobs', 'src/main/groovy' 8 | } 9 | resources { 10 | srcDirs 'src/main/resources', 'src/main/bash' 11 | } 12 | } 13 | test { 14 | resources { 15 | srcDirs 'src/test/bats', 'src/test/docs_helper' 16 | } 17 | } 18 | } 19 | 20 | ext { 21 | projectCrawlerVersion = "1.0.0.BUILD-SNAPSHOT" 22 | jacksonVersion = "2.9.5" 23 | } 24 | 25 | repositories { 26 | jcenter() 27 | mavenCentral() 28 | maven { url 'https://repo.jenkins-ci.org/releases/' } 29 | maven { url "https://repo.spring.io/libs-snapshot-local" } 30 | maven { url "https://repo.spring.io/libs-milestone-local" } 31 | maven { url "https://repo.spring.io/libs-release-local" } 32 | } 33 | 34 | configurations { 35 | libs 36 | compile.extendsFrom(libs) 37 | } 38 | 39 | dependencies { 40 | compile 'org.codehaus.groovy:groovy-all:2.4.7' 41 | compile "org.jenkins-ci.plugins:job-dsl-core:${jenkinsJobDslVersion}" 42 | compile "org.jenkins-ci.plugins:job-dsl:${jenkinsJobDslVersion}@jar" 43 | 44 | // for dsl 45 | libs "io.cloudpipelines:project-crawler:${projectCrawlerVersion}" 46 | libs "com.fasterxml.jackson.core:jackson-core:${jacksonVersion}" 47 | libs "com.fasterxml.jackson.core:jackson-databind:${jacksonVersion}" 48 | libs "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:${jacksonVersion}" 49 | 50 | testCompile('org.spockframework:spock-core:1.0-groovy-2.4') { 51 | exclude module: 'groovy-all' 52 | } 53 | testCompile 'org.xmlunit:xmlunit-core:2.6.0' 54 | testCompile "org.skyscreamer:jsonassert:1.4.0" 55 | } 56 | 57 | test { 58 | testLogging { 59 | exceptionFormat = 'full' 60 | } 61 | } 62 | 63 | task libs(type: Copy) { 64 | into "${project.buildDir}/lib" 65 | from configurations.libs 66 | } 67 | 68 | task storeFile { 69 | doLast { 70 | File file = new File(project.buildDir, "lib/jcabigithub.properties") 71 | file.createNewFile() 72 | file.text = """\ 73 | #User-Agent info 74 | JCabi-Version 0.41 75 | JCabi-Build f1055c4 76 | JCabi-Date 2018-06-20 11:00 77 | """ 78 | } 79 | } 80 | 81 | build.dependsOn libs 82 | build.dependsOn storeFile 83 | storeFile.mustRunAfter(libs) 84 | -------------------------------------------------------------------------------- /tools/deploy-infra-k8s.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # The script will clone the infra repos and build their docker images 4 | # You can provide a destination directory to which project should be cloned. 5 | # If not provided will use a temporary directory. 6 | # 7 | # Examples: 8 | # $ ./tools/deploy-infra.sh 9 | # $ ./tools/deploy-infra.sh ../repos/pivotal/ 10 | # 11 | 12 | set -o errexit 13 | 14 | if [[ $# -lt 1 ]]; then 15 | DEST_DIR="$( mktemp -d )" 16 | else 17 | DEST_DIR="$1" 18 | fi 19 | 20 | POTENTIAL_DOCKER_HOST="$( echo "$DOCKER_HOST" | cut -d ":" -f 2 | cut -d "/" -f 3 )" 21 | if [[ -z "${POTENTIAL_DOCKER_HOST}" ]]; then 22 | POTENTIAL_DOCKER_HOST="localhost" 23 | fi 24 | 25 | function deploy_project { 26 | local project_repo="$1" 27 | local project_name 28 | 29 | project_name="$( basename "${project_repo}" )" 30 | 31 | echo "Deploying ${project_name} to Docker registry" 32 | 33 | pushd "${DEST_DIR}" 34 | rm -rf "${project_name}" 35 | git clone "${project_repo}" "${project_name}" && cd "${project_name}" 36 | ./mvnw install docker:build -Pdocker 37 | popd 38 | } 39 | 40 | echo "Using Docker running at [${POTENTIAL_DOCKER_HOST}]" 41 | echo "Destination directory to clone the apps is [${DEST_DIR}]" 42 | echo "Artifactory ID [${ARTIFACTORY_ID}]" 43 | 44 | deploy_project "https://github.com/spring-cloud-samples/github-eureka" 45 | deploy_project "https://github.com/spring-cloud-samples/github-analytics-stub-runner-boot" 46 | deploy_project "https://github.com/spring-cloud-samples/github-analytics-stub-runner-boot-no-eureka" 47 | #deploy_project "https://github.com/spring-cloud-samples/github-webhook" 48 | deploy_project "https://github.com/spring-cloud-samples/github-analytics-stub-runner-boot-classpath-stubs" || echo "Failed to build the project - try again once github-webhook stubs get uploaded" 49 | #deploy_project "https://github.com/spring-cloud-samples/github-analytics-stub-runner-boot-classpath-stubs-kubernetes" || echo "Failed to build the project - try again once github-webhook stubs get uploaded" 50 | deploy_project "https://github.com/spring-cloud-samples/github-analytics-stub-runner-boot-no-eureka-classpath-stubs" || echo "Failed to build the project - try again once github-webhook stubs get uploaded" 51 | 52 | echo "DONE!" 53 | -------------------------------------------------------------------------------- /job-dsl/jobs/jenkins_pipeline_sample_view.groovy: -------------------------------------------------------------------------------- 1 | import javaposse.jobdsl.dsl.DslFactory 2 | 3 | /** 4 | * This script contains logic that 5 | * 6 | * - generates views for each deployment pipeline from the REPOS env var 7 | */ 8 | 9 | 10 | DslFactory dsl = this 11 | 12 | // we're parsing the REPOS parameter to retrieve list of repos to build 13 | String repos = binding.variables['REPOS'] ?: 14 | ['https://github.com/marcingrzejszczak/github-analytics', 15 | 'https://github.com/marcingrzejszczak/github-webhook'].join(',') 16 | List parsedRepos = repos.split(',') 17 | parsedRepos.each { 18 | String gitRepoName = it.split('/').last() - '.git' 19 | int customNameIndex = it.indexOf('$') 20 | int customBranchIndex = it.indexOf('#') 21 | if (customNameIndex > -1 && (customNameIndex < customBranchIndex || customBranchIndex == -1)) { 22 | if (customNameIndex < customBranchIndex) { 23 | // url$newName#someBranch 24 | gitRepoName = it.substring(customNameIndex + 1, customBranchIndex) 25 | } else if (customBranchIndex == -1) { 26 | // url$newName 27 | gitRepoName = it.substring(customNameIndex + 1) 28 | } 29 | } else if (customBranchIndex > -1) { 30 | if (customBranchIndex < customNameIndex) { 31 | // url#someBranch$newName 32 | gitRepoName = it.substring(customNameIndex + 1) 33 | } else if (customNameIndex == -1) { 34 | // url#someBranch 35 | gitRepoName = it.substring(it.lastIndexOf("/") + 1, customBranchIndex) 36 | } 37 | } 38 | String projectName = "${gitRepoName}-pipeline" 39 | dsl.deliveryPipelineView(projectName) { 40 | allowPipelineStart() 41 | pipelineInstances(5) 42 | showAggregatedPipeline(false) 43 | columns(1) 44 | updateInterval(5) 45 | enableManualTriggers() 46 | showAvatars() 47 | showChangeLog() 48 | pipelines { 49 | component("Deployment", "${projectName}-build") 50 | } 51 | allowRebuild() 52 | showDescription() 53 | showPromotions() 54 | showTotalBuildTime() 55 | configure { 56 | (it / 'showTestResults').setValue(true) 57 | (it / 'pagingEnabled').setValue(true) 58 | } 59 | } 60 | } 61 | 62 | dsl.listView("ci") { 63 | jobs { 64 | regex(".*-ci") 65 | } 66 | columns { 67 | status() 68 | name() 69 | lastSuccess() 70 | lastFailure() 71 | lastBuildConsole() 72 | buildButton() 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /job-dsl/src/test/bats/fixtures/scripts/pipeline.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | function retrieveGroupId() { 3 | echo "com.example" 4 | } 5 | 6 | function retrieveAppName() { 7 | echo "${PROJECT_NAME}" 8 | } 9 | 10 | function retrieveStubRunnerIds() { 11 | echo "com.example:foo:1.0.0.RELEASE:stubs:1234" 12 | } 13 | 14 | function deleteService() { 15 | echo "$*" 16 | } 17 | 18 | function deployService() { 19 | echo "$*" 20 | } 21 | 22 | function outputFolder() { 23 | echo "target/" 24 | } 25 | 26 | function testResultsAntPattern() { 27 | echo "**/test-results/*.xml" 28 | } 29 | 30 | # ---- BUILD PHASE ---- 31 | function build() { 32 | echo "build" 33 | } 34 | 35 | function executeApiCompatibilityCheck() { 36 | echo "executeApiCompatibilityCheck" 37 | } 38 | 39 | # ---- TEST PHASE ---- 40 | 41 | function testDeploy() { 42 | echo "testDeploy" 43 | } 44 | 45 | function testRollbackDeploy() { 46 | echo "testRollbackDeploy [${1}]" 47 | } 48 | 49 | function prepareForSmokeTests() { 50 | echo "prepareForSmokeTests" 51 | } 52 | 53 | function runSmokeTests() { 54 | echo "runSmokeTests" 55 | } 56 | 57 | # ---- STAGE PHASE ---- 58 | 59 | function stageDeploy() { 60 | echo "stageDeploy" 61 | } 62 | 63 | function prepareForE2eTests() { 64 | echo "prepareForE2eTests" 65 | } 66 | 67 | function runE2eTests() { 68 | echo "runE2eTests" 69 | } 70 | 71 | # ---- PRODUCTION PHASE ---- 72 | 73 | function prodDeploy() { 74 | echo "prodDeploy" 75 | } 76 | 77 | function completeSwitchOver() { 78 | echo "completeSwitchOver" 79 | } 80 | 81 | function rollbackToPreviousVersion() { 82 | echo "rollbackToPreviousVersion" 83 | } 84 | 85 | function removeProdTag() { 86 | echo "removeProdTag" 87 | } 88 | 89 | export -f retrieveGroupId 90 | export -f retrieveAppName 91 | export -f deleteService 92 | export -f deployService 93 | export -f outputFolder 94 | export -f testResultsAntPattern 95 | export -f testDeploy 96 | export -f testRollbackDeploy 97 | export -f prepareForSmokeTests 98 | export -f runSmokeTests 99 | export -f stageDeploy 100 | export -f prepareForE2eTests 101 | export -f runE2eTests 102 | export -f prodDeploy 103 | export -f completeSwitchOver 104 | export -f rollbackToPreviousVersion 105 | export -f removeProdTag 106 | -------------------------------------------------------------------------------- /tools/deploy-infra.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # The script will clone the infra repos and upload them to your artifactory 4 | # You can provide a destination directory to which project should be cloned. 5 | # If not provided will use a temporary directory. 6 | # 7 | # Examples: 8 | # $ ./tools/deploy-infra.sh 9 | # $ ./tools/deploy-infra.sh ../repos/pivotal/ 10 | # $ ARTIFACTORY_URL="https://192.168.99.100:8081/artifactory/libs-release-local" ./tools/deploy-infra.sh 11 | # 12 | 13 | set -o errexit 14 | 15 | if [[ $# -lt 1 ]]; then 16 | DEST_DIR="$( mktemp -d )" 17 | else 18 | DEST_DIR="$1" 19 | fi 20 | 21 | POTENTIAL_DOCKER_HOST="$( echo "$DOCKER_HOST" | cut -d ":" -f 2 | cut -d "/" -f 3 )" 22 | if [[ -z "${POTENTIAL_DOCKER_HOST}" ]]; then 23 | POTENTIAL_DOCKER_HOST="localhost" 24 | fi 25 | 26 | ARTIFACTORY_URL="${ARTIFACTORY_URL:-https://admin:password@${POTENTIAL_DOCKER_HOST}:8081/artifactory/libs-release-local}" 27 | ARTIFACTORY_ID="${ARTIFACTORY_ID:-artifactory-local}" 28 | 29 | function deploy_project { 30 | local project_repo="$1" 31 | local project_name 32 | 33 | project_name="$( basename "${project_repo}" )" 34 | 35 | echo "Deploying ${project_name} to Artifactory" 36 | 37 | pushd "${DEST_DIR}" 38 | rm -rf "${project_name}" 39 | git clone "${project_repo}" "${project_name}" && cd "${project_name}" 40 | ./mvnw clean deploy \ 41 | -Ddistribution.management.release.url="${ARTIFACTORY_URL}" -Ddistribution.management.release.id="${ARTIFACTORY_ID}" 42 | popd 43 | } 44 | 45 | echo "Using Docker running at [${POTENTIAL_DOCKER_HOST}]" 46 | echo "Destination directory to clone the apps is [${DEST_DIR}]" 47 | echo "Artifactory ID [${ARTIFACTORY_ID}]" 48 | 49 | deploy_project "https://github.com/spring-cloud-samples/github-eureka" 50 | deploy_project "https://github.com/spring-cloud-samples/github-analytics-stub-runner-boot" 51 | deploy_project "https://github.com/spring-cloud-samples/github-analytics-stub-runner-boot-no-eureka" 52 | deploy_project "https://github.com/spring-cloud-samples/github-analytics-stub-runner-boot-classpath-stubs" || echo "Failed to build the project - try again once github-webhook stubs get uploaded" 53 | deploy_project "https://github.com/spring-cloud-samples/github-analytics-stub-runner-boot-no-eureka-classpath-stubs" || echo "Failed to build the project - try again once github-webhook stubs get uploaded" 54 | 55 | echo "DONE!" 56 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/default_pipeline/DefaultView.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.default_pipeline 2 | 3 | import groovy.transform.CompileDynamic 4 | import groovy.transform.CompileStatic 5 | import javaposse.jobdsl.dsl.DslFactory 6 | import javaposse.jobdsl.dsl.Job 7 | import javaposse.jobdsl.dsl.View 8 | import javaposse.jobdsl.dsl.views.ColumnsContext 9 | 10 | import io.cloudpipelines.common.Coordinates 11 | import io.cloudpipelines.common.PipelineDefaults 12 | import io.cloudpipelines.common.PipelineDescriptor 13 | import io.cloudpipelines.steps.Build 14 | import io.cloudpipelines.projectcrawler.Repository 15 | 16 | /** 17 | * Generates views for a project 18 | * 19 | * @author Marcin Grzejszczak 20 | * @since 1.0.0 21 | */ 22 | @CompileStatic 23 | class DefaultView { 24 | private final io.cloudpipelines.common.PipelineDefaults pipelineDefaults 25 | private final DslFactory dsl 26 | 27 | DefaultView(io.cloudpipelines.common.PipelineDefaults pipelineDefaults, DslFactory dsl) { 28 | this.pipelineDefaults = pipelineDefaults 29 | this.dsl = dsl 30 | } 31 | 32 | void allViews(List repositories) { 33 | dsl.listView('Seeds') { 34 | jobs { 35 | regex('.*-seed') 36 | } 37 | columns { 38 | defaultColumns(delegate as ColumnsContext) 39 | } 40 | } 41 | dsl.nestedView('Pipelines') { 42 | def nested = delegate 43 | repositories.each { 44 | String projectName = it.name 45 | nested.views { 46 | deliveryPipelineView(projectName) { 47 | allowPipelineStart() 48 | pipelineInstances(5) 49 | showAggregatedPipeline(false) 50 | columns(1) 51 | updateInterval(5) 52 | enableManualTriggers() 53 | showAvatars() 54 | showChangeLog() 55 | pipelines { 56 | component("Deploy ${projectName} to production", Build.stepName(DefaultPipelineDefaults.projectName(projectName))) 57 | } 58 | allowRebuild() 59 | showDescription() 60 | showPromotions() 61 | showTotalBuildTime() 62 | configureAdditionalFields(delegate as View) 63 | } 64 | } 65 | } 66 | } 67 | } 68 | 69 | @CompileDynamic 70 | private void configureAdditionalFields(View context) { 71 | context.configure { 72 | (it / 'showTestResults').setValue(true) 73 | (it / 'pagingEnabled').setValue(true) 74 | } 75 | } 76 | 77 | private void defaultColumns(ColumnsContext context) { 78 | context.with { 79 | status() 80 | name() 81 | lastSuccess() 82 | lastFailure() 83 | lastBuildConsole() 84 | buildButton() 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS="-Xmx64m" 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /demo/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ $# < 3 ]] ; then 4 | echo "You have to pass three params" 5 | echo "1 - git username with access to the forked repos or \"-key\" if using private key authentication instead" 6 | echo "2 - git password of that user or path to the private SSH key file if \"-key\" option is specified" 7 | echo "3 - org or your user id where the forked repos lay" 8 | echo "4 - (for k8s) docker registry organization - you can leave an empty value" 9 | echo "5 - (for k8s) docker registry username - you can leave an empty value" 10 | echo "6 - (for k8s) docker registry password - you can leave an empty value" 11 | echo "7 - (for k8s) docker registry email - you can leave an empty value" 12 | echo "8 - (optional) external ip (for example Docker Machine if you're using one)" 13 | echo "Example: ./start.sh user pass forkedOrg dockerOrg dockerUser dockerPass dockerEmail" 14 | echo "Example: ./start.sh -key ~/.ssh/my_key forkedOrg dockerOrg dockerUser dockerPass dockerEmail" 15 | echo "Example: ./start.sh user pass forkedOrg dockerOrg dockerUser dockerPass dockerEmail 192.168.99.100" 16 | echo "Example: ./start.sh user pass forkedOrg '' '' '' '' 192.168.99.100" 17 | exit 0 18 | fi 19 | 20 | GIT_AUTH_MODE="username/password" 21 | 22 | export PIPELINE_GIT_USERNAME="${1}" 23 | export PIPELINE_GIT_PASSWORD="${2}" 24 | export FORKED_ORG="${3}" 25 | export DOCKER_REGISTRY_ORGANIZATION="${4}" 26 | export DOCKER_REGISTRY_USERNAME="${5}" 27 | export DOCKER_REGISTRY_PASSWORD="${6}" 28 | export DOCKER_REGISTRY_EMAIL="${7}" 29 | export EXTERNAL_IP="${8}" 30 | 31 | if [ "-key" == ${PIPELINE_GIT_USERNAME} ]; then 32 | export PIPELINE_GIT_USERNAME="" 33 | export PIPELINE_GIT_SSH_KEY="$(cat ${PIPELINE_GIT_PASSWORD})" 34 | export PIPELINE_GIT_PASSWORD="" 35 | GIT_AUTH_MODE="private key" 36 | fi 37 | 38 | if [[ -z "${EXTERNAL_IP}" ]]; then 39 | EXTERNAL_IP=`echo ${DOCKER_HOST} | cut -d ":" -f 2 | cut -d "/" -f 3` 40 | if [[ -z "${EXTERNAL_IP}" ]]; then 41 | EXTERNAL_IP="$( whats_my_ip.sh )" 42 | fi 43 | fi 44 | 45 | echo "Git authentication mode [${GIT_AUTH_MODE}]" 46 | echo "Forked organization [${FORKED_ORG}]" 47 | echo "External IP [${EXTERNAL_IP}]" 48 | 49 | # Kubernetes 50 | echo "Copying Kubernetes certificates" 51 | cp ~/.minikube/ca.crt seed/k8s/ || echo "Failed to copy Kubernetes certificate authority file" 52 | cp ~/.minikube/apiserver.crt seed/k8s/ || echo "Failed to copy Kubernetes client certificate file" 53 | cp ~/.minikube/apiserver.key seed/k8s/ || echo "Failed to copy Kubernetes client key file" 54 | 55 | docker-compose build --no-cache 56 | #docker-compose build 57 | docker-compose up -d 58 | -------------------------------------------------------------------------------- /job-dsl/src/test/groovy/io/cloudpipelines/util/JobCreator.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.util 2 | 3 | import groovy.transform.CompileStatic 4 | import groovy.xml.XmlUtil 5 | import javaposse.jobdsl.dsl.JobManagement 6 | import javaposse.jobdsl.dsl.JobParent 7 | import javaposse.jobdsl.dsl.MemoryJobManagement 8 | 9 | /** 10 | * @author Marcin Grzejszczak 11 | */ 12 | @CompileStatic 13 | trait JobCreator { 14 | 15 | JobParent createJobParent() { 16 | JobParent jp = new StubbedJobParent() 17 | JobManagement jm = new MemoryJobManagement() 18 | jp.setJm(jm) 19 | defaultStubbing(jm) 20 | return jp 21 | } 22 | 23 | String folderName() { 24 | return "default_pipeline" 25 | } 26 | 27 | void storeJobsAndViews(MemoryJobManagement jm) { 28 | File jobs = new File("build/${folderName()}/jobs/") 29 | File views = new File("build/${folderName()}/views/") 30 | jobs.mkdirs() 31 | views.mkdirs() 32 | jm.savedConfigs.each { 33 | new File(jobs, "${it.key}.xml").text = XmlUtil.serialize(it.value) 34 | } 35 | jm.savedViews.each { 36 | new File(views, "${it.key}.xml").text = XmlUtil.serialize(it.value) 37 | } 38 | } 39 | 40 | private void defaultStubbing(MemoryJobManagement jm) { 41 | jm.availableFiles['foo/pipeline.sh'] = JobCreator.getResource('/cloudpipelines-scripts/pipeline.sh').text 42 | jm.availableFiles['foo/build_and_upload.sh'] = JobCreator.getResource('/cloudpipelines-scripts/build_and_upload.sh').text 43 | jm.availableFiles['foo/build_api_compatibility_check.sh'] = JobCreator.getResource('/cloudpipelines-scripts/build_api_compatibility_check.sh').text 44 | jm.availableFiles['foo/test_deploy.sh'] = JobCreator.getResource('/cloudpipelines-scripts/test_deploy.sh').text 45 | jm.availableFiles['foo/test_smoke.sh'] = JobCreator.getResource('/cloudpipelines-scripts/test_smoke.sh').text 46 | jm.availableFiles['foo/test_rollback_deploy.sh'] = JobCreator.getResource('/cloudpipelines-scripts/test_rollback_deploy.sh').text 47 | jm.availableFiles['foo/test_rollback_smoke.sh'] = JobCreator.getResource('/cloudpipelines-scripts/test_rollback_smoke.sh').text 48 | jm.availableFiles['foo/stage_deploy.sh'] = JobCreator.getResource('/cloudpipelines-scripts/stage_deploy.sh').text 49 | jm.availableFiles['foo/stage_e2e.sh'] = JobCreator.getResource('/cloudpipelines-scripts/stage_e2e.sh').text 50 | jm.availableFiles['foo/prod_deploy.sh'] = JobCreator.getResource('/cloudpipelines-scripts/prod_deploy.sh').text 51 | jm.availableFiles['foo/prod_complete.sh'] = JobCreator.getResource('/cloudpipelines-scripts/prod_complete.sh').text 52 | } 53 | 54 | static class StubbedJobParent extends JobParent { 55 | @Override 56 | Object run() { 57 | return null 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /job-dsl/src/test/bats/steps.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | load 'test_helper' 4 | load 'test_helper/bats-support/load' 5 | load 'test_helper/bats-assert/load' 6 | 7 | setup() { 8 | export TEMP_DIR="$( mktemp -d )" 9 | 10 | mkdir -p "${TEMP_DIR}/scripts" 11 | cp -a "${FIXTURES_DIR}/scripts" "${TEMP_DIR}" 12 | 13 | # Copying the common folder 14 | NEW_SRC="${TEMP_DIR}/.git/tools/src/main/bash/" 15 | mkdir -p "${NEW_SRC}" 16 | cp "${TEMP_DIR}"/scripts/*.sh "${NEW_SRC}/" 17 | 18 | export WORKSPACE="${TEMP_DIR}" 19 | } 20 | 21 | teardown() { 22 | rm -rf "${TEMP_DIR}" 23 | } 24 | 25 | @test "should run test_deploy" { 26 | export SCRIPT_NAME="test_deploy" 27 | run "${STEPS_DIR}"/${SCRIPT_NAME}.sh 28 | 29 | assert_success 30 | assert_output "Executed ${SCRIPT_NAME}" 31 | } 32 | 33 | @test "should run test_smoke" { 34 | export SCRIPT_NAME="test_smoke" 35 | run "${STEPS_DIR}"/${SCRIPT_NAME}.sh 36 | 37 | assert_success 38 | assert_output "Executed ${SCRIPT_NAME}" 39 | } 40 | 41 | @test "should run test_rollback_deploy" { 42 | export SCRIPT_NAME="test_rollback_deploy" 43 | run "${STEPS_DIR}"/${SCRIPT_NAME}.sh 44 | 45 | assert_success 46 | assert_output "Executed ${SCRIPT_NAME}" 47 | } 48 | 49 | @test "should run test_rollback_smoke" { 50 | export SCRIPT_NAME="test_rollback_smoke" 51 | run "${STEPS_DIR}"/${SCRIPT_NAME}.sh 52 | 53 | assert_success 54 | assert_output "Executed ${SCRIPT_NAME}" 55 | } 56 | 57 | @test "should run stage_deploy" { 58 | export SCRIPT_NAME="stage_deploy" 59 | run "${STEPS_DIR}"/${SCRIPT_NAME}.sh 60 | 61 | assert_success 62 | assert_output "Executed ${SCRIPT_NAME}" 63 | } 64 | 65 | @test "should run stage_e2e" { 66 | export SCRIPT_NAME="stage_e2e" 67 | run "${STEPS_DIR}"/${SCRIPT_NAME}.sh 68 | 69 | assert_success 70 | assert_output "Executed ${SCRIPT_NAME}" 71 | } 72 | 73 | @test "should run prod_deploy" { 74 | export SCRIPT_NAME="prod_deploy" 75 | run "${STEPS_DIR}"/${SCRIPT_NAME}.sh 76 | 77 | assert_success 78 | assert_output "Executed ${SCRIPT_NAME}" 79 | } 80 | 81 | @test "should run prod_complete" { 82 | export SCRIPT_NAME="prod_complete" 83 | run "${STEPS_DIR}"/${SCRIPT_NAME}.sh 84 | 85 | assert_success 86 | assert_output "Executed ${SCRIPT_NAME}" 87 | } 88 | 89 | @test "should run prod_rollback" { 90 | export SCRIPT_NAME="prod_rollback" 91 | run "${STEPS_DIR}"/${SCRIPT_NAME}.sh 92 | 93 | assert_success 94 | assert_output "Executed ${SCRIPT_NAME}" 95 | } 96 | 97 | @test "should run prod_remove_tag" { 98 | export SCRIPT_NAME="prod_remove_prod_tag" 99 | run "${STEPS_DIR}"/${SCRIPT_NAME}.sh 100 | 101 | assert_success 102 | assert_output "removeProdTag" 103 | } 104 | -------------------------------------------------------------------------------- /docs/DEMO_SETUP.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Untitled 9 | 10 | 11 | 12 | 13 | 15 |
16 |
17 |
18 | demo 19 |
20 |
The overview of the demo: Github Webhook listens to HTTP calls and sends a message to Github Analytics
21 |
22 |
23 |

  24 |  

25 |
26 |
27 |

For the demo scenario we have two applications. Github Analytics and Github Webhook. 28 | Let’s imagine a case where Github is emitting events via HTTP. Github Webhook has 29 | an API that could register to such hooks and receive those messages. Once this happens 30 | Github Webhook sends a message by RabbitMQ to a channel. Github Analytics is 31 | listening to those messages and stores them in a MySQL database.

32 |
33 |
34 |
35 | demo metrics 36 |
37 |
Gathering metrics: Github Analytics exposes metrics that are polled by Prometheus
38 |
39 |
40 |

  41 |  

42 |
43 |
44 |

Github Analytics has its KPIs (Key Performance Indicators) monitored. In the case 45 | of that application the KPI is number of issues.

46 |
47 |
48 |
49 | demo alerting 50 |
51 |
Alerting over metrics: Grafana alerts Slack over Prometheus metrics
52 |
53 |
54 |

  55 |  

56 |
57 |
58 |

Let’s assume that if we go below the threshold of X issues then an alert should be 59 | sent to Slack.

60 |
61 |
62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /job-dsl/jobs/jenkins_pipeline_crawler_sample.groovy: -------------------------------------------------------------------------------- 1 | import javaposse.jobdsl.dsl.DslFactory 2 | 3 | import io.cloudpipelines.common.GeneratedJobs 4 | import io.cloudpipelines.common.PipelineDefaults 5 | import io.cloudpipelines.common.PipelineDescriptor 6 | import io.cloudpipelines.common.PipelineFactory 7 | import io.cloudpipelines.common.PipelineJobsFactory 8 | import io.cloudpipelines.common.PipelineJobsFactoryProvider 9 | import io.cloudpipelines.default_pipeline.DefaultPipelineJobsFactory 10 | import io.cloudpipelines.default_pipeline.DefaultView 11 | import io.cloudpipelines.test.TestUtils 12 | import io.cloudpipelines.projectcrawler.OptionsBuilder 13 | import io.cloudpipelines.projectcrawler.Repository 14 | import io.cloudpipelines.projectcrawler.ProjectCrawler 15 | 16 | /** 17 | * This script contains logic that 18 | * 19 | * - uses the Project Crawler to crawl repos from an organization 20 | * - for each repo picks the cloud-pipelines.yml descriptor 21 | * - basing on the contents of that repo generates proper deployment pipeline 22 | * - generates views for all projects 23 | */ 24 | 25 | DslFactory dsl = this 26 | 27 | // These will be taken either from seed or global variables 28 | PipelineDefaults defaults = new PipelineDefaults(binding.variables) 29 | String pipelineVersion = defaults.pipelineVersion() 30 | String org = defaults.repoOrganization() ?: "sc-pipelines" 31 | String repoType = defaults.repoManagement() ?: "GITHUB" 32 | String urlRoot = defaults.repoUrlRoot() ?: "https://github.com" 33 | 34 | // crawl the org 35 | ProjectCrawler crawler = new ProjectCrawler(OptionsBuilder 36 | .builder().rootUrl(urlRoot) 37 | .username(defaults.gitUsername()) 38 | .password(defaults.gitPassword()) 39 | .token(defaults.gitToken()) 40 | .exclude(defaults.repoProjectsExcludePattern()) 41 | .repository(repoType).build()) 42 | 43 | // get the repos from the org 44 | List repositories = defaults.testModeDescriptor() != null ? 45 | TestUtils.TEST_REPO : crawler.repositories(org) 46 | 47 | // generate jobs and store errors 48 | GeneratedJobs generatedJobs = new PipelineFactory( 49 | new PipelineJobsFactoryProvider() { 50 | @Override 51 | PipelineJobsFactory get(PipelineDefaults pipelineDefaults, DslFactory dslFactory, PipelineDescriptor descriptor, Repository repository) { 52 | return new DefaultPipelineJobsFactory(pipelineDefaults, descriptor, dslFactory) 53 | } 54 | @Override 55 | List additionalFiles() { 56 | return [] 57 | } 58 | }, defaults, crawler, dsl).generate(repositories, org, pipelineVersion) 59 | 60 | if (generatedJobs.hasErrors()) { 61 | println "\n\n\nWARNING, THERE WERE ERRORS WHILE TRYING TO BUILD PROJECTS\n\n\n" 62 | generatedJobs.errors.each { String key, Exception error -> 63 | println "Exception for project [${key}], [${error}]" 64 | println "Stacktrace:" 65 | error.printStackTrace() 66 | } 67 | } 68 | 69 | new DefaultView(defaults, dsl).allViews(repositories) 70 | -------------------------------------------------------------------------------- /docs-sources/src/main/asciidoc/CF_JENKINS_FAQ.adoc: -------------------------------------------------------------------------------- 1 | I ran out of resources. (Cloud Foundry):: 2 | [jenkins-cf-resources]] When deploying the application to stage or prod, you can get an `Insufficient resources` exception. The way to 3 | solve it is to kill some applications from the test and stage environments. To do so, run the following commands: 4 | + 5 | ==== 6 | [source,bash] 7 | ---- 8 | $ cf target -o pcfdev-org -s pcfdev-test 9 | $ cf stop github-webhook 10 | $ cf stop github-eureka 11 | $ cf stop stubrunner 12 | ---- 13 | ==== 14 | + 15 | You can also run `./tools/cf-helper.sh kill-all-apps` to remove all demo-related apps 16 | deployed to PCF Dev. 17 | 18 | Deploying to test or stage or prod fails with an error about finding space (Cloud Foundry):: 19 | You receive an exception similar to the following: 20 | + 21 | ==== 22 | [source,bash] 23 | ---- 24 | 20:26:18 API endpoint: https://api.local.pcfdev.io (API version: 2.58.0) 25 | 20:26:18 User: user 26 | 20:26:18 Org: pcfdev-org 27 | 20:26:18 Space: No space targeted, use 'cf target -s SPACE' 28 | 20:26:18 FAILED 29 | 20:26:18 Error finding space pcfdev-test 30 | 20:26:18 Space pcfdev-test not found 31 | ---- 32 | ==== 33 | + 34 | It means that you forgot to <> in your PCF Dev installation. 35 | 36 | The route is already in use (Cloud Foundry).:: 37 | If you play around with Jenkins, you can end up with routes that are 38 | already occupied, as identified by errors similar to the following: 39 | + 40 | ==== 41 | [source,bash] 42 | ---- 43 | Using route github-webhook-test.local.pcfdev.io 44 | Binding github-webhook-test.local.pcfdev.io to github-webhook... 45 | FAILED 46 | The route github-webhook-test.local.pcfdev.io is already in use. 47 | ---- 48 | ==== 49 | + 50 | To resolve the issue, delete the offending routes, by using commands similar to the following: 51 | + 52 | ==== 53 | [source,bash] 54 | ---- 55 | $ yes | cf delete-route local.pcfdev.io -n github-webhook-test 56 | $ yes | cf delete-route local.pcfdev.io -n github-eureka-test 57 | $ yes | cf delete-route local.pcfdev.io -n stubrunner-test 58 | $ yes | cf delete-route local.pcfdev.io -n github-webhook-stage 59 | $ yes | cf delete-route local.pcfdev.io -n github-eureka-stage 60 | $ yes | cf delete-route local.pcfdev.io -n github-webhook-prod 61 | $ yes | cf delete-route local.pcfdev.io -n github-eureka-prod 62 | ---- 63 | ==== 64 | + 65 | You can also run the `./tools/cf-helper.sh delete-routes` script. 66 | 67 | How can I run helper scripts against a real Cloud Foundry instance that I'm logged into?:: 68 | Assuming that you are already logged into the cluster, uyou can run the 69 | helper script with the `REUSE_CF_LOGIN=true` env variable, as shown in the following example: 70 | + 71 | ==== 72 | [source,bash] 73 | ---- 74 | REUSE_CF_LOGIN=true ./tools/cf-helper.sh setup-prod-infra 75 | ---- 76 | ==== 77 | + 78 | This script create the MySQL database and the RabbitMQ service and downloads and deploys Eureka 79 | to the space and organization you are logged into. 80 | -------------------------------------------------------------------------------- /job-dsl/jobs/jenkins_spinnaker_pipeline_sample.groovy: -------------------------------------------------------------------------------- 1 | import javaposse.jobdsl.dsl.DslFactory 2 | 3 | import io.cloudpipelines.common.GeneratedJobs 4 | import io.cloudpipelines.common.PipelineDefaults 5 | import io.cloudpipelines.common.PipelineDescriptor 6 | import io.cloudpipelines.common.PipelineFactory 7 | import io.cloudpipelines.common.PipelineJobsFactory 8 | import io.cloudpipelines.common.PipelineJobsFactoryProvider 9 | import io.cloudpipelines.spinnaker.SpinnakerDefaultView 10 | import io.cloudpipelines.spinnaker.SpinnakerJobsFactory 11 | import io.cloudpipelines.test.TestUtils 12 | import io.cloudpipelines.projectcrawler.OptionsBuilder 13 | import io.cloudpipelines.projectcrawler.Repository 14 | import io.cloudpipelines.projectcrawler.ProjectCrawler 15 | 16 | /** 17 | * This script contains logic that 18 | * 19 | * - uses the Project Crawler to crawl repos from an organization 20 | * - for each repo picks the cloud-pipelines.yml descriptor 21 | * - basing on the contents of that repo generates proper Spinnaker deployment pipeline JSON 22 | * - generates Jenkins jobs required by Spinnaker 23 | * - generates views for all projects 24 | */ 25 | 26 | 27 | DslFactory dsl = this 28 | 29 | // These will be taken either from seed or global variables 30 | PipelineDefaults defaults = new PipelineDefaults(binding.variables) 31 | String pipelineVersion = defaults.pipelineVersion() 32 | String org = defaults.repoOrganization() ?: "sc-pipelines" 33 | String repoType = defaults.repoManagement() ?: "GITHUB" 34 | String urlRoot = defaults.repoUrlRoot() ?: "https://github.com" 35 | 36 | // crawl the org 37 | ProjectCrawler crawler = new ProjectCrawler(OptionsBuilder 38 | .builder().rootUrl(urlRoot) 39 | .username(defaults.gitUsername()) 40 | .password(defaults.gitPassword()) 41 | .token(defaults.gitToken()) 42 | .exclude(defaults.repoProjectsExcludePattern()) 43 | .repository(repoType).build()) 44 | 45 | // get the repos from the org 46 | List repositories = defaults.testModeDescriptor() != null ? 47 | TestUtils.TEST_REPO : crawler.repositories(org) 48 | 49 | // generate jobs and store errors 50 | GeneratedJobs generatedJobs = new PipelineFactory( 51 | new PipelineJobsFactoryProvider() { 52 | @Override 53 | PipelineJobsFactory get(PipelineDefaults pipelineDefaults, DslFactory dslFactory, PipelineDescriptor descriptor, Repository repository) { 54 | return new SpinnakerJobsFactory(pipelineDefaults, descriptor, dslFactory, repository) 55 | } 56 | @Override 57 | List additionalFiles() { 58 | return ["manifest.yml"] 59 | } 60 | }, defaults, crawler, dsl).generate(repositories, org, pipelineVersion) 61 | 62 | if (generatedJobs.hasErrors()) { 63 | println "\n\n\nWARNING, THERE WERE ERRORS WHILE TRYING TO BUILD PROJECTS\n\n\n" 64 | generatedJobs.errors.each { String key, Exception error -> 65 | println "Exception for project [${key}], [${error}]" 66 | println "Stacktrace:" 67 | error.printStackTrace() 68 | } 69 | } 70 | 71 | // build the views 72 | new SpinnakerDefaultView(dsl, defaults).view(generatedJobs.repositoriesForViews) 73 | -------------------------------------------------------------------------------- /demo/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'groovy' 2 | 3 | sourceSets { 4 | main { 5 | groovy { 6 | srcDirs 'seed' 7 | } 8 | } 9 | } 10 | 11 | repositories { 12 | jcenter() 13 | mavenCentral() 14 | maven { url 'https://repo.jenkins-ci.org/releases/' } 15 | maven { url "https://repo.spring.io/snapshot" } 16 | maven { url "https://repo.spring.io/milestone" } 17 | maven { url "https://repo.spring.io/release" } 18 | } 19 | 20 | dependencies { 21 | compile 'org.codehaus.groovy:groovy-all:2.4.7' 22 | compile "org.jenkins-ci.plugins:job-dsl-core:${jenkinsJobDslVersion}" 23 | compile "org.jenkins-ci.plugins:job-dsl:${jenkinsJobDslVersion}@jar" 24 | 25 | // for init.groovy 26 | compile 'org.jenkins-ci.plugins:credentials:2.1.13@jar' 27 | compile 'org.jenkins-ci.plugins:ssh-credentials:1.13@jar' 28 | compile 'org.jenkins-ci.plugins:groovy:1.30@jar' 29 | compile 'org.jenkins-ci.main:jenkins-core:2.19.1' 30 | // for Intellij not to throw exceptions 31 | compile 'javax.servlet:servlet-api:2.4' 32 | 33 | testCompile('org.spockframework:spock-core:1.0-groovy-2.4') { 34 | exclude module: 'groovy-all' 35 | } 36 | } 37 | 38 | // docker 39 | 40 | /* ext { 41 | dockerImagePrefix = "cloudpipelines" 42 | dockerImageName = "${dockerImagePrefix}/${project.rootProject.name}" 43 | } 44 | 45 | apply plugin: 'com.bmuschko.docker-remote-api' 46 | 47 | import com.bmuschko.gradle.docker.tasks.image.* 48 | 49 | docker { 50 | registryCredentials { 51 | url = getProp('DOCKER_REGISTRY_URL') ?: 'https://index.docker.io/v1/' 52 | username = getProp('DOCKER_HUB_USERNAME') ?: "changeme" 53 | password = getProp('DOCKER_HUB_PASSWORD') ?: "changeme" 54 | email = getProp('DOCKER_HUB_EMAIL') ?: "change@me.com" 55 | } 56 | } 57 | 58 | task buildImage(type: DockerBuildImage) { 59 | inputDir = project.projectDir 60 | tags = ["${dockerImageName}".toString()] as Set 61 | } 62 | 63 | task tagImage(type: DockerTagImage) { 64 | dependsOn([buildImage]) 65 | targetImageId { buildImage.getImageId() } 66 | repository = "${dockerImageName}" 67 | tag = project.version 68 | } 69 | 70 | task pushLatestImage(type: DockerPushImage) { 71 | dependsOn([tagImage]) 72 | imageName = "${dockerImageName}" 73 | tag = "latest" 74 | } 75 | 76 | task pushConcreteImage(type: DockerPushImage) { 77 | dependsOn([tagImage]) 78 | imageName = "${dockerImageName}" 79 | tag = project.version 80 | } 81 | 82 | task pushImages { 83 | enabled = project.hasProperty("releaseDocker") 84 | dependsOn([pushLatestImage, pushConcreteImage]) 85 | } 86 | 87 | task removeImage(type: DockerRemoveImage) { 88 | dependsOn([tagImage, pushImages]) 89 | targetImageId { buildImage.getImageId() } 90 | force(true) 91 | } 92 | 93 | test.dependsOn("tagImage") 94 | if (project.hasProperty("releaseDocker")) build.dependsOn("removeImage") 95 | 96 | String getProp(String propName) { 97 | return hasProperty(propName) ? 98 | (getProperty(propName) ?: System.properties[propName]) : System.properties[propName] ?: 99 | System.getenv(propName) 100 | } */ 101 | -------------------------------------------------------------------------------- /docs/JENKINS_RUN_SEED.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Untitled 9 | 10 | 11 | 12 | 13 | 15 |
16 |
17 |

We created the seed job for you, but you have to run it. When you do 18 | run it, you have to provide some properties. By default we create a seed that 19 | has all the properties options, but you can delete most of it. If you 20 | set the properties as global environment variables, you have to remove them from the 21 | seed.

22 |
23 |
24 |

To run the demo, provide a comma-separated 25 | list of the URLs of the two aforementioned forks (github-webhook and github-analytics') in the `REPOS variable.

26 |
27 |
28 |

The following images shows the steps involved:

29 |
30 |
31 |

  32 |  

33 |
34 |
35 |
36 | seed click 37 |
38 |
Step 1: Click the 'jenkins-pipeline-seed-cf' job for Cloud Foundry and jenkins-pipeline-seed-k8s for Kubernetes
39 |
40 |
41 |

  42 |  

43 |
44 |
45 |
46 | seed run 47 |
48 |
Step 2: Click the 'Build with parameters'
49 |
50 |
51 |

  52 |  

53 |
54 |
55 |
56 | seed 57 |
58 |
Step 3: The REPOS parameter should already contain your forked repos (you’ll have more properties than the ones in the screenshot)
59 |
60 |
61 |

  62 |  

63 |
64 |
65 |
66 | seed built 67 |
68 |
Step 4: This is how the results of seed should look like
69 |
70 |
71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/spinnaker/pipeline/steps/ProdSetTag.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.spinnaker.pipeline.steps 2 | 3 | import groovy.transform.CompileStatic 4 | import javaposse.jobdsl.dsl.DslFactory 5 | import javaposse.jobdsl.dsl.Job 6 | import javaposse.jobdsl.dsl.helpers.ScmContext 7 | import javaposse.jobdsl.dsl.helpers.publisher.PublisherContext 8 | import javaposse.jobdsl.dsl.helpers.step.StepContext 9 | import javaposse.jobdsl.dsl.helpers.wrapper.WrapperContext 10 | import javaposse.jobdsl.dsl.jobs.FreeStyleJob 11 | 12 | import io.cloudpipelines.common.BashFunctions 13 | import io.cloudpipelines.common.Coordinates 14 | import io.cloudpipelines.common.EnvironmentVariables 15 | import io.cloudpipelines.common.PipelineDefaults 16 | import io.cloudpipelines.common.PipelineDescriptor 17 | import io.cloudpipelines.steps.CommonSteps 18 | import io.cloudpipelines.steps.CreatedJob 19 | import io.cloudpipelines.steps.Step 20 | 21 | /** 22 | * Pushes production tag 23 | * 24 | * @author Marcin Grzejszczak 25 | * @since 1.0.0 26 | */ 27 | @CompileStatic 28 | class ProdSetTag implements Step { 29 | private final DslFactory dsl 30 | private final io.cloudpipelines.common.PipelineDefaults pipelineDefaults 31 | private final BashFunctions bashFunctions 32 | private final CommonSteps commonSteps 33 | 34 | ProdSetTag(DslFactory dsl, io.cloudpipelines.common.PipelineDefaults pipelineDefaults) { 35 | this.dsl = dsl 36 | this.pipelineDefaults = pipelineDefaults 37 | this.bashFunctions = pipelineDefaults.bashFunctions() 38 | this.commonSteps = new CommonSteps(this.pipelineDefaults, this.bashFunctions) 39 | } 40 | 41 | @Override 42 | CreatedJob step(String projectName, Coordinates coordinates, PipelineDescriptor descriptor) { 43 | String gitRepoName = coordinates.gitRepoName 44 | String fullGitRepo = coordinates.fullGitRepo 45 | Job job = dsl.job("${projectName}-prod-tag-repo") { 46 | deliveryPipelineConfiguration('Prod', 'Tag the repo') 47 | environmentVariables(pipelineDefaults.defaultEnvVars as Map) 48 | parameters { 49 | stringParam(EnvironmentVariables.PIPELINE_VERSION_ENV_VAR, "", "Version of the project to run the tests against") 50 | } 51 | wrappers { 52 | commonSteps.defaultWrappers(delegate as WrapperContext) 53 | commonSteps.deliveryPipelineVersion(delegate as WrapperContext) 54 | } 55 | scm { 56 | commonSteps.configureScm(delegate as ScmContext, fullGitRepo, 57 | "dev/${gitRepoName}/\${${EnvironmentVariables.PIPELINE_VERSION_ENV_VAR}}") 58 | } 59 | commonSteps.gitEmail(delegate as Job) 60 | publishers { 61 | git { 62 | forcePush(true) 63 | pushOnlyIfSuccess() 64 | tag('origin', "prod/${gitRepoName}/\${${EnvironmentVariables.PIPELINE_VERSION_ENV_VAR}}") { 65 | create() 66 | update() 67 | } 68 | } 69 | } 70 | } 71 | customize(job) 72 | return new CreatedJob(job, false) 73 | } 74 | 75 | @Override void customize(FreeStyleJob job) { 76 | commonSteps.customizers().each { 77 | it.customizeAll(job) 78 | it.customizeProd(job) 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /job-dsl/src/test/groovy/io/cloudpipelines/JobScriptsSpec.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines 2 | 3 | import groovy.io.FileType 4 | import javaposse.jobdsl.dsl.DslScriptLoader 5 | import javaposse.jobdsl.dsl.GeneratedItems 6 | import javaposse.jobdsl.dsl.MemoryJobManagement 7 | import javaposse.jobdsl.dsl.ScriptRequest 8 | import spock.lang.Specification 9 | import spock.lang.Unroll 10 | /** 11 | * Tests that all dsl scripts in the jobs directory will compile. 12 | */ 13 | class JobScriptsSpec extends Specification { 14 | 15 | @Unroll 16 | def 'should compile script #file.name'() { 17 | given: 18 | 19 | MemoryJobManagement jm = new MemoryJobManagement() 20 | defaultStubbing(jm) 21 | jm.parameters << [ 22 | SCRIPTS_DIR: 'foo', 23 | JENKINSFILE_DIR: 'foo', 24 | TEST_MODE_DESCRIPTOR: '' 25 | ] 26 | DslScriptLoader loader = new DslScriptLoader(jm) 27 | 28 | when: 29 | GeneratedItems scripts = loader.runScripts([new ScriptRequest(file.text)]) 30 | 31 | then: 32 | noExceptionThrown() 33 | 34 | and: 35 | if (file.name.endsWith('jenkins_pipeline_sample.groovy')) { 36 | List jobNames = scripts.jobs.collect { it.jobName } 37 | assert jobNames.find { it == "github-analytics-pipeline-build" } 38 | assert jobNames.find { it == "github-webhook-pipeline-build" } 39 | assert jobNames.find { it.contains("stage") } 40 | assert jobNames.find { it.contains("prod-env-deploy") } 41 | } 42 | 43 | where: 44 | file << jobFiles() 45 | } 46 | 47 | private void defaultStubbing(MemoryJobManagement jm) { 48 | jm.availableFiles['foo/pipeline.sh'] = JobScriptsSpec.getResource('/cloudpipelines-scripts/pipeline.sh').text 49 | jm.availableFiles['foo/build_and_upload.sh'] = JobScriptsSpec.getResource('/cloudpipelines-scripts/build_and_upload.sh').text 50 | jm.availableFiles['foo/build_api_compatibility_check.sh'] = JobScriptsSpec.getResource('/cloudpipelines-scripts/build_api_compatibility_check.sh').text 51 | jm.availableFiles['foo/test_deploy.sh'] = JobScriptsSpec.getResource('/cloudpipelines-scripts/test_deploy.sh').text 52 | jm.availableFiles['foo/test_smoke.sh'] = JobScriptsSpec.getResource('/cloudpipelines-scripts/test_smoke.sh').text 53 | jm.availableFiles['foo/test_rollback_deploy.sh'] = JobScriptsSpec.getResource('/cloudpipelines-scripts/test_rollback_deploy.sh').text 54 | jm.availableFiles['foo/test_rollback_smoke.sh'] = JobScriptsSpec.getResource('/cloudpipelines-scripts/test_rollback_smoke.sh').text 55 | jm.availableFiles['foo/stage_deploy.sh'] = JobScriptsSpec.getResource('/cloudpipelines-scripts/stage_deploy.sh').text 56 | jm.availableFiles['foo/stage_e2e.sh'] = JobScriptsSpec.getResource('/cloudpipelines-scripts/stage_e2e.sh').text 57 | jm.availableFiles['foo/prod_deploy.sh'] = JobScriptsSpec.getResource('/cloudpipelines-scripts/prod_deploy.sh').text 58 | jm.availableFiles['foo/prod_complete.sh'] = JobScriptsSpec.getResource('/cloudpipelines-scripts/prod_complete.sh').text 59 | } 60 | 61 | static List jobFiles() { 62 | List files = [] 63 | new File('jobs').eachFileRecurse(FileType.FILES) { 64 | files << it 65 | } 66 | return files 67 | } 68 | 69 | } 70 | 71 | -------------------------------------------------------------------------------- /demo/artifactory.config.import.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1 3 | ## This file is complementary to the JFrog Artifactory startup wizard, and may be used to specify the initial basic 4 | ## settings for a new Artifactory installation, namely: 5 | ## * License Key(s) 6 | ## * Base URL 7 | ## * Proxy 8 | ## * Default repositories 9 | ## 10 | ## 11 | ## HOW TO USE THIS FILE: 12 | ## 13 | ## To import these settings when bootstrapping Artifactory, save this file as artifactory.config.import.yml under Artifactory’s /etc folder 14 | ## Artifactory will load this file if all of the following conditions are met: 15 | ## - no repositories have been created 16 | ## - a proxy has not been set up, or you did set up a proxy externally, but did not configure proxy setup through this file 17 | ## - the base URL has not been set up, or you did set up the base URL externally, but did not configure the base URL setup through this file 18 | ## - Artifactory has not been activated with a license, or Artifactory has been activated with a license, and you did not specify a license in this file 19 | ## 20 | ## To have any of these parameters automatically configured when you bootstrap an Artifactory instance using this file, 21 | ## simply uncomment the relevant sections below, and where required, provide values. 22 | 23 | ################################################################################## 24 | # General Configurations # 25 | ################################################################################## 26 | #GeneralConfiguration: 27 | ## License key to import in onboarding 28 | # licenseKey : "Enter your license key" 29 | 30 | ## Setup the Artifactory base URL 31 | ## For more information about the Artifactory base URL, please refer to 32 | ## https://www.jfrog.com/confluence/display/RTF/Configuring+Artifactory#ConfiguringArtifactory-GeneralSettings 33 | ## Uncomment the line below to set the Artifactory base URL 34 | # baseUrl : "https://mycomp.arti.co" 35 | 36 | ## Configure proxies for artifactory 37 | ## For more information on configuring a proxy in Artifactory, please refer to 38 | ## https://www.jfrog.com/confluence/display/RTF/Managing+Proxies 39 | ## Uncomment the lines below to setup a proxy 40 | # proxies : 41 | # - key : "proxy1" 42 | # host : "https://proxy.mycomp.io" 43 | # port : 443 44 | # userName : "admin" 45 | # password : "password" 46 | # defaultProxy : true 47 | # - key : "proxy2" 48 | # ... 49 | ################################################################################## 50 | # Onboarding Configurations # 51 | ################################################################################## 52 | OnboardingConfiguration: 53 | ## Uncomment the package types for which you want to create default repositories 54 | repoTypes : 55 | # - bower 56 | # - cocoapods 57 | # - conan 58 | # - debian 59 | # - docker 60 | # - gems 61 | # - gradle 62 | # - ivy 63 | - maven 64 | # - npm 65 | # - nuget 66 | # - opkg 67 | # - composer 68 | # - pypi 69 | # - sbt 70 | # - vagrant 71 | # - rpm 72 | # - gitlfs 73 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/spinnaker/pipeline/steps/ProdRemoveTag.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.spinnaker.pipeline.steps 2 | 3 | import groovy.transform.CompileStatic 4 | import javaposse.jobdsl.dsl.DslFactory 5 | import javaposse.jobdsl.dsl.Job 6 | import javaposse.jobdsl.dsl.helpers.ScmContext 7 | import javaposse.jobdsl.dsl.helpers.publisher.PublisherContext 8 | import javaposse.jobdsl.dsl.helpers.step.StepContext 9 | import javaposse.jobdsl.dsl.helpers.wrapper.WrapperContext 10 | import javaposse.jobdsl.dsl.jobs.FreeStyleJob 11 | 12 | import io.cloudpipelines.common.BashFunctions 13 | import io.cloudpipelines.common.Coordinates 14 | import io.cloudpipelines.common.EnvironmentVariables 15 | import io.cloudpipelines.common.PipelineDefaults 16 | import io.cloudpipelines.common.PipelineDescriptor 17 | import io.cloudpipelines.steps.CommonSteps 18 | import io.cloudpipelines.steps.CreatedJob 19 | import io.cloudpipelines.steps.Step 20 | 21 | /** 22 | * Removes the production tag 23 | * 24 | * @author Marcin Grzejszczak 25 | * @since 1.0.0 26 | */ 27 | @CompileStatic 28 | class ProdRemoveTag implements Step { 29 | private final DslFactory dsl 30 | private final io.cloudpipelines.common.PipelineDefaults pipelineDefaults 31 | private final BashFunctions bashFunctions 32 | private final CommonSteps commonSteps 33 | 34 | ProdRemoveTag(DslFactory dsl, io.cloudpipelines.common.PipelineDefaults pipelineDefaults) { 35 | this.dsl = dsl 36 | this.pipelineDefaults = pipelineDefaults 37 | this.bashFunctions = pipelineDefaults.bashFunctions() 38 | this.commonSteps = new CommonSteps(this.pipelineDefaults, this.bashFunctions) 39 | } 40 | 41 | @Override 42 | CreatedJob step(String projectName, Coordinates coordinates, PipelineDescriptor descriptor) { 43 | String gitRepoName = coordinates.gitRepoName 44 | String fullGitRepo = coordinates.fullGitRepo 45 | Job job = dsl.job("${projectName}-prod-env-remove-tag") { 46 | deliveryPipelineConfiguration('Prod', 'Remove the prod tag') 47 | environmentVariables(pipelineDefaults.defaultEnvVars as Map) 48 | parameters { 49 | stringParam(EnvironmentVariables.PIPELINE_VERSION_ENV_VAR, "", "Version of the project to run the tests against") 50 | } 51 | wrappers { 52 | commonSteps.defaultWrappers(delegate as WrapperContext) 53 | credentialsBinding { 54 | if (!pipelineDefaults.gitUseSshKey()) usernamePassword(EnvironmentVariables.GIT_USERNAME_ENV_VAR, 55 | EnvironmentVariables.GIT_PASSWORD_ENV_VAR, 56 | pipelineDefaults.gitCredentials()) 57 | } 58 | } 59 | scm { 60 | commonSteps.configureScm(delegate as ScmContext, fullGitRepo, 61 | "dev/${gitRepoName}/\${${EnvironmentVariables.PIPELINE_VERSION_ENV_VAR}}") 62 | } 63 | commonSteps.gitEmail(delegate as Job) 64 | steps { 65 | commonSteps.downloadTools(delegate as StepContext, fullGitRepo) 66 | shell("""#!/bin/bash 67 | set -o errexit 68 | set -o errtrace 69 | set -o pipefail 70 | 71 | ${bashFunctions.setupGitCredentials(fullGitRepo)} 72 | 73 | """ + commonSteps.readScript("prod_remove_prod_tag.sh")) 74 | } 75 | publishers { 76 | commonSteps.defaultPublishers(delegate as PublisherContext) 77 | commonSteps.deployPublishers(delegate as PublisherContext) 78 | } 79 | } 80 | customize(job) 81 | return new CreatedJob(job, false) 82 | } 83 | 84 | @Override 85 | void customize(FreeStyleJob step) { 86 | commonSteps.customizers().each { 87 | it.customizeAll(step) 88 | it.customizeProd(step) 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/steps/ProdRollback.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.steps 2 | 3 | import groovy.transform.CompileStatic 4 | import javaposse.jobdsl.dsl.DslFactory 5 | import javaposse.jobdsl.dsl.Job 6 | import javaposse.jobdsl.dsl.helpers.ScmContext 7 | import javaposse.jobdsl.dsl.helpers.publisher.PublisherContext 8 | import javaposse.jobdsl.dsl.helpers.step.StepContext 9 | import javaposse.jobdsl.dsl.helpers.wrapper.WrapperContext 10 | import javaposse.jobdsl.dsl.jobs.FreeStyleJob 11 | 12 | import io.cloudpipelines.common.BashFunctions 13 | import io.cloudpipelines.common.Coordinates 14 | import io.cloudpipelines.common.EnvironmentVariables 15 | import io.cloudpipelines.common.PipelineDefaults 16 | import io.cloudpipelines.common.PipelineDescriptor 17 | 18 | /** 19 | * Rolls back on production 20 | * 21 | * @author Marcin Grzejszczak 22 | * @since 1.0.0 23 | */ 24 | @CompileStatic 25 | class ProdRollback implements Step { 26 | private final DslFactory dsl 27 | private final io.cloudpipelines.common.PipelineDefaults pipelineDefaults 28 | private final BashFunctions bashFunctions 29 | private final CommonSteps commonSteps 30 | 31 | ProdRollback(DslFactory dsl, io.cloudpipelines.common.PipelineDefaults pipelineDefaults) { 32 | this.dsl = dsl 33 | this.pipelineDefaults = pipelineDefaults 34 | this.bashFunctions = pipelineDefaults.bashFunctions() 35 | this.commonSteps = new CommonSteps(this.pipelineDefaults, this.bashFunctions) 36 | } 37 | 38 | @Override 39 | CreatedJob step(String projectName, Coordinates coordinates, PipelineDescriptor descriptor) { 40 | String gitRepoName = coordinates.gitRepoName 41 | String fullGitRepo = coordinates.fullGitRepo 42 | Job job = dsl.job("${projectName}-prod-env-rollback") { 43 | deliveryPipelineConfiguration('Prod', 'Rollback') 44 | environmentVariables(pipelineDefaults.defaultEnvVars as Map) 45 | wrappers { 46 | commonSteps.defaultWrappers(delegate as WrapperContext) 47 | commonSteps.deliveryPipelineVersion(delegate as WrapperContext) 48 | credentialsBinding { 49 | if (!pipelineDefaults.gitUseSshKey()) usernamePassword(EnvironmentVariables.GIT_USERNAME_ENV_VAR, 50 | EnvironmentVariables.GIT_PASSWORD_ENV_VAR, 51 | pipelineDefaults.gitCredentials()) 52 | // remove::start[CF] 53 | if (pipelineDefaults.cfProdCredentialId()) usernamePassword( 54 | EnvironmentVariables.PAAS_PROD_USERNAME_ENV_VAR, 55 | EnvironmentVariables.PAAS_PROD_PASSWORD_ENV_VAR, 56 | pipelineDefaults.cfProdCredentialId()) 57 | // remove::end[CF] 58 | // remove::start[K8S] 59 | if (pipelineDefaults.k8sProdTokenCredentialId()) string(EnvironmentVariables.TOKEN_ENV_VAR, 60 | pipelineDefaults.k8sProdTokenCredentialId()) 61 | // remove::end[K8S] 62 | } 63 | } 64 | scm { 65 | commonSteps.configureScm(delegate as ScmContext, fullGitRepo, 66 | "dev/${gitRepoName}/\${${EnvironmentVariables.PIPELINE_VERSION_ENV_VAR}}") 67 | } 68 | steps { 69 | commonSteps.downloadTools(delegate as StepContext, fullGitRepo) 70 | commonSteps.runStep(delegate as StepContext, "prod_rollback.sh") 71 | } 72 | publishers { 73 | commonSteps.defaultPublishers(delegate as PublisherContext) 74 | commonSteps.deployPublishers(delegate as PublisherContext) 75 | } 76 | } 77 | customize(job) 78 | return new CreatedJob(job, false) 79 | } 80 | 81 | @Override void customize(FreeStyleJob job) { 82 | commonSteps.customizers().each { 83 | it.customizeAll(job) 84 | it.customizeProd(job) 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/steps/StageTest.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.steps 2 | 3 | import groovy.transform.CompileStatic 4 | import javaposse.jobdsl.dsl.DslFactory 5 | import javaposse.jobdsl.dsl.Job 6 | import javaposse.jobdsl.dsl.helpers.ScmContext 7 | import javaposse.jobdsl.dsl.helpers.publisher.PublisherContext 8 | import javaposse.jobdsl.dsl.helpers.step.StepContext 9 | import javaposse.jobdsl.dsl.helpers.wrapper.WrapperContext 10 | import javaposse.jobdsl.dsl.jobs.FreeStyleJob 11 | 12 | import io.cloudpipelines.common.BashFunctions 13 | import io.cloudpipelines.common.Coordinates 14 | import io.cloudpipelines.common.EnvironmentVariables 15 | import io.cloudpipelines.common.PipelineDefaults 16 | import io.cloudpipelines.common.PipelineDescriptor 17 | import io.cloudpipelines.common.StepEnabledChecker 18 | 19 | /** 20 | * Tests on stage 21 | * 22 | * @author Marcin Grzejszczak 23 | * @since 1.0.0 24 | */ 25 | @CompileStatic 26 | class StageTest implements Step { 27 | private final DslFactory dsl 28 | private final io.cloudpipelines.common.PipelineDefaults pipelineDefaults 29 | private final BashFunctions bashFunctions 30 | private final CommonSteps commonSteps 31 | 32 | StageTest(DslFactory dsl, io.cloudpipelines.common.PipelineDefaults pipelineDefaults) { 33 | this.dsl = dsl 34 | this.pipelineDefaults = pipelineDefaults 35 | this.bashFunctions = pipelineDefaults.bashFunctions() 36 | this.commonSteps = new CommonSteps(this.pipelineDefaults, this.bashFunctions) 37 | } 38 | 39 | @Override 40 | CreatedJob step(String projectName, Coordinates coordinates, PipelineDescriptor descriptor) { 41 | StepEnabledChecker checker = new StepEnabledChecker(descriptor, pipelineDefaults) 42 | if (checker.stageStepMissing()) { 43 | return null 44 | } 45 | String gitRepoName = coordinates.gitRepoName 46 | String fullGitRepo = coordinates.fullGitRepo 47 | Job job = dsl.job("${projectName}-stage-env-test") { 48 | deliveryPipelineConfiguration('Stage', 'Tests on stage') 49 | environmentVariables(pipelineDefaults.defaultEnvVars as Map) 50 | wrappers { 51 | commonSteps.defaultWrappers(delegate as WrapperContext) 52 | commonSteps.deliveryPipelineVersion(delegate as WrapperContext) 53 | credentialsBinding { 54 | // remove::start[CF] 55 | if (pipelineDefaults.cfStageCredentialId()) usernamePassword( 56 | EnvironmentVariables.PAAS_STAGE_USERNAME_ENV_VAR, 57 | EnvironmentVariables.PAAS_STAGE_PASSWORD_ENV_VAR, 58 | pipelineDefaults.cfStageCredentialId()) 59 | // remove::end[CF] 60 | // remove::start[K8S] 61 | if (pipelineDefaults.k8sStageTokenCredentialId()) string( 62 | EnvironmentVariables.TOKEN_ENV_VAR, 63 | pipelineDefaults.k8sStageTokenCredentialId()) 64 | // remove::end[K8S] 65 | } 66 | } 67 | scm { 68 | commonSteps.configureScm(delegate as ScmContext, fullGitRepo, "dev/${gitRepoName}/\${${EnvironmentVariables.PIPELINE_VERSION_ENV_VAR}}") 69 | } 70 | steps { 71 | commonSteps.downloadTools(delegate as StepContext, fullGitRepo) 72 | commonSteps.runStep(delegate as StepContext, "stage_e2e.sh") 73 | } 74 | publishers { 75 | commonSteps.defaultPublishers(delegate as PublisherContext) 76 | } 77 | } 78 | customize(job) 79 | return new CreatedJob(job, autoNextJob(checker)) 80 | } 81 | 82 | private boolean autoNextJob(StepEnabledChecker checker) { 83 | return checker.autoProdSet() 84 | } 85 | 86 | @Override void customize(FreeStyleJob job) { 87 | commonSteps.customizers().each { 88 | it.customizeAll(job) 89 | it.customizeStage(job) 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/steps/ProdComplete.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.steps 2 | 3 | import groovy.transform.CompileStatic 4 | import javaposse.jobdsl.dsl.DslFactory 5 | import javaposse.jobdsl.dsl.Job 6 | import javaposse.jobdsl.dsl.helpers.ScmContext 7 | import javaposse.jobdsl.dsl.helpers.publisher.PublisherContext 8 | import javaposse.jobdsl.dsl.helpers.step.StepContext 9 | import javaposse.jobdsl.dsl.helpers.wrapper.WrapperContext 10 | import javaposse.jobdsl.dsl.jobs.FreeStyleJob 11 | 12 | import io.cloudpipelines.common.BashFunctions 13 | import io.cloudpipelines.common.Coordinates 14 | import io.cloudpipelines.common.EnvironmentVariables 15 | import io.cloudpipelines.common.JobCustomizer 16 | import io.cloudpipelines.common.PipelineDefaults 17 | import io.cloudpipelines.common.PipelineDescriptor 18 | 19 | /** 20 | * Switches over the production deployment 21 | * 22 | * @author Marcin Grzejszczak 23 | * @since 1.0.0 24 | */ 25 | @CompileStatic 26 | class ProdComplete implements Step { 27 | private final DslFactory dsl 28 | private final io.cloudpipelines.common.PipelineDefaults pipelineDefaults 29 | private final BashFunctions bashFunctions 30 | private final CommonSteps commonSteps 31 | 32 | ProdComplete(DslFactory dsl, io.cloudpipelines.common.PipelineDefaults pipelineDefaults) { 33 | this.dsl = dsl 34 | this.pipelineDefaults = pipelineDefaults 35 | this.bashFunctions = pipelineDefaults.bashFunctions() 36 | this.commonSteps = new CommonSteps(this.pipelineDefaults, this.bashFunctions) 37 | } 38 | 39 | @Override 40 | CreatedJob step(String projectName, Coordinates coordinates, PipelineDescriptor descriptor) { 41 | String gitRepoName = coordinates.gitRepoName 42 | String fullGitRepo = coordinates.fullGitRepo 43 | Job job = dsl.job("${projectName}-prod-env-complete") { 44 | deliveryPipelineConfiguration('Prod', 'Complete switch over') 45 | environmentVariables(pipelineDefaults.defaultEnvVars as Map) 46 | wrappers { 47 | commonSteps.defaultWrappers(delegate as WrapperContext) 48 | commonSteps.deliveryPipelineVersion(delegate as WrapperContext) 49 | credentialsBinding { 50 | if (!pipelineDefaults.gitUseSshKey()) usernamePassword(EnvironmentVariables.GIT_USERNAME_ENV_VAR, 51 | EnvironmentVariables.GIT_PASSWORD_ENV_VAR, 52 | pipelineDefaults.gitCredentials()) 53 | // remove::start[CF] 54 | if (pipelineDefaults.cfProdCredentialId()) usernamePassword( 55 | EnvironmentVariables.PAAS_PROD_USERNAME_ENV_VAR, 56 | EnvironmentVariables.PAAS_PROD_PASSWORD_ENV_VAR, 57 | pipelineDefaults.cfProdCredentialId()) 58 | // remove::end[CF] 59 | // remove::start[K8S] 60 | if (pipelineDefaults.k8sProdTokenCredentialId()) string(EnvironmentVariables.TOKEN_ENV_VAR, 61 | pipelineDefaults.k8sProdTokenCredentialId()) 62 | // remove::end[K8S] 63 | } 64 | } 65 | scm { 66 | commonSteps.configureScm(delegate as ScmContext, fullGitRepo, 67 | "dev/${gitRepoName}/\${${EnvironmentVariables.PIPELINE_VERSION_ENV_VAR}}") 68 | } 69 | steps { 70 | commonSteps.downloadTools(delegate as StepContext, fullGitRepo) 71 | commonSteps.runStep(delegate as StepContext, "prod_complete.sh") 72 | } 73 | publishers { 74 | commonSteps.defaultPublishers(delegate as PublisherContext) 75 | commonSteps.deployPublishers(delegate as PublisherContext) 76 | } 77 | } 78 | customize(job) 79 | return new CreatedJob(job, false) 80 | } 81 | 82 | @Override void customize(FreeStyleJob job) { 83 | commonSteps.customizers().each { 84 | it.customizeAll(job) 85 | it.customizeProd(job) 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/steps/ProdDeploy.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.steps 2 | 3 | import groovy.transform.CompileStatic 4 | import javaposse.jobdsl.dsl.DslFactory 5 | import javaposse.jobdsl.dsl.Job 6 | import javaposse.jobdsl.dsl.helpers.ScmContext 7 | import javaposse.jobdsl.dsl.helpers.publisher.PublisherContext 8 | import javaposse.jobdsl.dsl.helpers.step.StepContext 9 | import javaposse.jobdsl.dsl.helpers.wrapper.WrapperContext 10 | import javaposse.jobdsl.dsl.jobs.FreeStyleJob 11 | 12 | import io.cloudpipelines.common.BashFunctions 13 | import io.cloudpipelines.common.Coordinates 14 | import io.cloudpipelines.common.EnvironmentVariables 15 | import io.cloudpipelines.common.PipelineDefaults 16 | import io.cloudpipelines.common.PipelineDescriptor 17 | 18 | /** 19 | * Deploys to production 20 | * 21 | * @author Marcin Grzejszczak 22 | * @since 1.0.0 23 | */ 24 | @CompileStatic 25 | class ProdDeploy implements Step { 26 | private final DslFactory dsl 27 | private final io.cloudpipelines.common.PipelineDefaults pipelineDefaults 28 | private final BashFunctions bashFunctions 29 | private final CommonSteps commonSteps 30 | 31 | ProdDeploy(DslFactory dsl, io.cloudpipelines.common.PipelineDefaults pipelineDefaults) { 32 | this.dsl = dsl 33 | this.pipelineDefaults = pipelineDefaults 34 | this.bashFunctions = pipelineDefaults.bashFunctions() 35 | this.commonSteps = new CommonSteps(this.pipelineDefaults, this.bashFunctions) 36 | } 37 | 38 | @Override 39 | CreatedJob step(String projectName, Coordinates coordinates, PipelineDescriptor descriptor) { 40 | String gitRepoName = coordinates.gitRepoName 41 | String fullGitRepo = coordinates.fullGitRepo 42 | Job job = dsl.job("${projectName}-prod-env-deploy") { 43 | deliveryPipelineConfiguration('Prod', 'Deploy to prod') 44 | environmentVariables(pipelineDefaults.defaultEnvVars as Map) 45 | wrappers { 46 | commonSteps.defaultWrappers(delegate as WrapperContext) 47 | commonSteps.deliveryPipelineVersion(delegate as WrapperContext) 48 | credentialsBinding { 49 | // remove::start[CF] 50 | if (pipelineDefaults.cfProdCredentialId()) usernamePassword( 51 | EnvironmentVariables.PAAS_PROD_USERNAME_ENV_VAR, 52 | EnvironmentVariables.PAAS_PROD_PASSWORD_ENV_VAR, 53 | pipelineDefaults.cfProdCredentialId()) 54 | // remove::end[CF] 55 | // remove::start[K8S] 56 | if (pipelineDefaults.k8sProdTokenCredentialId()) string(EnvironmentVariables.TOKEN_ENV_VAR, 57 | pipelineDefaults.k8sProdTokenCredentialId()) 58 | // remove::end[K8S] 59 | } 60 | } 61 | scm { 62 | commonSteps.configureScm(delegate as ScmContext, fullGitRepo, 63 | "dev/${gitRepoName}/\${${EnvironmentVariables.PIPELINE_VERSION_ENV_VAR}}") 64 | } 65 | steps { 66 | commonSteps.downloadTools(delegate as StepContext, fullGitRepo) 67 | commonSteps.runStep(delegate as StepContext, "prod_deploy.sh") 68 | } 69 | commonSteps.gitEmail(delegate as Job) 70 | publishers { 71 | commonSteps.defaultPublishers(delegate as PublisherContext) 72 | commonSteps.deployPublishers(delegate as PublisherContext) 73 | } 74 | publishers { 75 | git { 76 | forcePush(true) 77 | pushOnlyIfSuccess() 78 | tag('origin', "prod/${gitRepoName}/\${${EnvironmentVariables.PIPELINE_VERSION_ENV_VAR}}") { 79 | create() 80 | update() 81 | } 82 | } 83 | } 84 | } 85 | customize(job) 86 | return new CreatedJob(job, false) 87 | } 88 | 89 | @Override void customize(FreeStyleJob job) { 90 | commonSteps.customizers().each { 91 | it.customizeAll(job) 92 | it.customizeProd(job) 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/steps/TestDeployLatestProdVersion.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.steps 2 | 3 | import groovy.transform.CompileStatic 4 | import javaposse.jobdsl.dsl.DslFactory 5 | import javaposse.jobdsl.dsl.Job 6 | import javaposse.jobdsl.dsl.helpers.ScmContext 7 | import javaposse.jobdsl.dsl.helpers.publisher.PublisherContext 8 | import javaposse.jobdsl.dsl.helpers.step.StepContext 9 | import javaposse.jobdsl.dsl.helpers.wrapper.WrapperContext 10 | import javaposse.jobdsl.dsl.jobs.FreeStyleJob 11 | 12 | import io.cloudpipelines.common.BashFunctions 13 | import io.cloudpipelines.common.Coordinates 14 | import io.cloudpipelines.common.EnvironmentVariables 15 | import io.cloudpipelines.common.PipelineDefaults 16 | import io.cloudpipelines.common.PipelineDescriptor 17 | import io.cloudpipelines.common.StepEnabledChecker 18 | 19 | /** 20 | * Deploys to test latest production version 21 | * 22 | * @author Marcin Grzejszczak 23 | * @since 1.0.0 24 | */ 25 | @CompileStatic 26 | class TestDeployLatestProdVersion implements Step { 27 | private final DslFactory dsl 28 | private final io.cloudpipelines.common.PipelineDefaults pipelineDefaults 29 | private final BashFunctions bashFunctions 30 | private final CommonSteps commonSteps 31 | 32 | TestDeployLatestProdVersion(DslFactory dsl, io.cloudpipelines.common.PipelineDefaults pipelineDefaults) { 33 | this.dsl = dsl 34 | this.pipelineDefaults = pipelineDefaults 35 | this.bashFunctions = pipelineDefaults.bashFunctions() 36 | this.commonSteps = new CommonSteps(this.pipelineDefaults, this.bashFunctions) 37 | } 38 | 39 | @Override 40 | CreatedJob step(String projectName, Coordinates coordinates, PipelineDescriptor descriptor) { 41 | StepEnabledChecker checker = new StepEnabledChecker(descriptor, pipelineDefaults) 42 | if (checker.rollbackStepMissing()) { 43 | return null 44 | } 45 | String gitRepoName = coordinates.gitRepoName 46 | String fullGitRepo = coordinates.fullGitRepo 47 | Job job = dsl.job("${projectName}-test-env-rollback-deploy") { 48 | deliveryPipelineConfiguration('Test', 'Deploy to test latest prod version') 49 | environmentVariables(pipelineDefaults.defaultEnvVars as Map) 50 | wrappers { 51 | commonSteps.defaultWrappers(delegate as WrapperContext) 52 | commonSteps.deliveryPipelineVersion(delegate as WrapperContext) 53 | credentialsBinding { 54 | // remove::start[CF] 55 | if (pipelineDefaults.cfTestCredentialId()) usernamePassword( 56 | EnvironmentVariables.PAAS_TEST_USERNAME_ENV_VAR, 57 | EnvironmentVariables.PAAS_TEST_PASSWORD_ENV_VAR, 58 | pipelineDefaults.cfTestCredentialId()) 59 | // remove::end[CF] 60 | // remove::start[K8S] 61 | if (pipelineDefaults.k8sTestTokenCredentialId()) string(EnvironmentVariables.TOKEN_ENV_VAR, 62 | pipelineDefaults.k8sTestTokenCredentialId()) 63 | // remove::end[K8S] 64 | } 65 | } 66 | scm { 67 | commonSteps.configureScm(delegate as ScmContext, fullGitRepo, 68 | "dev/${gitRepoName}/\${${EnvironmentVariables.PIPELINE_VERSION_ENV_VAR}}") 69 | } 70 | steps { 71 | commonSteps.downloadTools(delegate as StepContext, fullGitRepo) 72 | commonSteps.runStep(delegate as StepContext, "test_rollback_deploy.sh") 73 | } 74 | publishers { 75 | commonSteps.defaultPublishers(delegate as PublisherContext) 76 | commonSteps.deployPublishers(delegate as PublisherContext) 77 | } 78 | } 79 | customize(job) 80 | return new CreatedJob(job, true) 81 | } 82 | 83 | @Override void customize(FreeStyleJob job) { 84 | commonSteps.customizers().each { 85 | it.customizeAll(job) 86 | it.customizeTest(job) 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/steps/TestTest.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.steps 2 | 3 | import groovy.transform.CompileStatic 4 | import javaposse.jobdsl.dsl.DslFactory 5 | import javaposse.jobdsl.dsl.Job 6 | import javaposse.jobdsl.dsl.helpers.ScmContext 7 | import javaposse.jobdsl.dsl.helpers.publisher.PublisherContext 8 | import javaposse.jobdsl.dsl.helpers.step.StepContext 9 | import javaposse.jobdsl.dsl.helpers.wrapper.WrapperContext 10 | import javaposse.jobdsl.dsl.jobs.FreeStyleJob 11 | 12 | import io.cloudpipelines.common.BashFunctions 13 | import io.cloudpipelines.common.Coordinates 14 | import io.cloudpipelines.common.EnvironmentVariables 15 | import io.cloudpipelines.common.PipelineDefaults 16 | import io.cloudpipelines.common.PipelineDescriptor 17 | import io.cloudpipelines.common.StepEnabledChecker 18 | 19 | /** 20 | * Runs tests on test 21 | * 22 | * @author Marcin Grzejszczak 23 | * @since 1.0.0 24 | */ 25 | @CompileStatic 26 | class TestTest implements Step { 27 | private final DslFactory dsl 28 | private final io.cloudpipelines.common.PipelineDefaults pipelineDefaults 29 | private final BashFunctions bashFunctions 30 | private final CommonSteps commonSteps 31 | 32 | TestTest(DslFactory dsl, io.cloudpipelines.common.PipelineDefaults pipelineDefaults) { 33 | this.dsl = dsl 34 | this.pipelineDefaults = pipelineDefaults 35 | this.bashFunctions = pipelineDefaults.bashFunctions() 36 | this.commonSteps = new CommonSteps(this.pipelineDefaults, this.bashFunctions) 37 | } 38 | 39 | @Override 40 | CreatedJob step(String projectName, Coordinates coordinates, PipelineDescriptor descriptor) { 41 | StepEnabledChecker checker = new StepEnabledChecker(descriptor, pipelineDefaults) 42 | if (checker.testStepMissing()) { 43 | return null 44 | } 45 | String gitRepoName = coordinates.gitRepoName 46 | String fullGitRepo = coordinates.fullGitRepo 47 | Job job = dsl.job("${projectName}-test-env-test") { 48 | deliveryPipelineConfiguration('Test', 'Tests on test') 49 | environmentVariables(pipelineDefaults.defaultEnvVars as Map) 50 | wrappers { 51 | commonSteps.defaultWrappers(delegate as WrapperContext) 52 | commonSteps.deliveryPipelineVersion(delegate as WrapperContext) 53 | credentialsBinding { 54 | // remove::start[CF] 55 | if (pipelineDefaults.cfTestCredentialId()) usernamePassword( 56 | EnvironmentVariables.PAAS_TEST_USERNAME_ENV_VAR, 57 | EnvironmentVariables.PAAS_TEST_PASSWORD_ENV_VAR, 58 | pipelineDefaults.cfTestCredentialId()) 59 | // remove::end[CF] 60 | // remove::start[K8S] 61 | if (pipelineDefaults.k8sTestTokenCredentialId()) string(EnvironmentVariables.TOKEN_ENV_VAR, 62 | pipelineDefaults.k8sTestTokenCredentialId()) 63 | // remove::end[K8S] 64 | } 65 | } 66 | scm { 67 | commonSteps.configureScm(delegate as ScmContext, fullGitRepo, "dev/${gitRepoName}/\${PIPELINE_VERSION}") 68 | } 69 | steps { 70 | commonSteps.downloadTools(delegate as StepContext, fullGitRepo) 71 | commonSteps.runStep(delegate as StepContext, "test_smoke.sh") 72 | } 73 | publishers { 74 | commonSteps.defaultPublishers(delegate as PublisherContext) 75 | } 76 | } 77 | customize(job) 78 | return new CreatedJob(job, autoNextJob(checker)) 79 | } 80 | 81 | private boolean autoNextJob(StepEnabledChecker checker) { 82 | if (checker.testStepSet() && checker.rollbackStepSet()) { 83 | return true 84 | } else if (checker.stageStepSet()) { 85 | return checker.autoStageSet() 86 | } 87 | return checker.autoProdSet() 88 | } 89 | 90 | @Override void customize(FreeStyleJob job) { 91 | commonSteps.customizers().each { 92 | it.customizeAll(job) 93 | it.customizeTest(job) 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/steps/TestRollbackTest.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.steps 2 | 3 | import groovy.transform.CompileStatic 4 | import javaposse.jobdsl.dsl.DslFactory 5 | import javaposse.jobdsl.dsl.Job 6 | import javaposse.jobdsl.dsl.helpers.ScmContext 7 | import javaposse.jobdsl.dsl.helpers.publisher.PublisherContext 8 | import javaposse.jobdsl.dsl.helpers.step.StepContext 9 | import javaposse.jobdsl.dsl.helpers.wrapper.WrapperContext 10 | import javaposse.jobdsl.dsl.jobs.FreeStyleJob 11 | 12 | import io.cloudpipelines.common.BashFunctions 13 | import io.cloudpipelines.common.Coordinates 14 | import io.cloudpipelines.common.EnvironmentVariables 15 | import io.cloudpipelines.common.PipelineDefaults 16 | import io.cloudpipelines.common.PipelineDescriptor 17 | import io.cloudpipelines.common.StepEnabledChecker 18 | 19 | /** 20 | * Runs rollback tests on test 21 | * 22 | * @author Marcin Grzejszczak 23 | * @since 1.0.0 24 | */ 25 | @CompileStatic 26 | class TestRollbackTest implements Step { 27 | private final DslFactory dsl 28 | private final io.cloudpipelines.common.PipelineDefaults pipelineDefaults 29 | private final BashFunctions bashFunctions 30 | private final CommonSteps commonSteps 31 | 32 | TestRollbackTest(DslFactory dsl, io.cloudpipelines.common.PipelineDefaults pipelineDefaults) { 33 | this.dsl = dsl 34 | this.pipelineDefaults = pipelineDefaults 35 | this.bashFunctions = pipelineDefaults.bashFunctions() 36 | this.commonSteps = new CommonSteps(this.pipelineDefaults, this.bashFunctions) 37 | } 38 | 39 | @Override 40 | CreatedJob step(String projectName, Coordinates coordinates, PipelineDescriptor descriptor) { 41 | StepEnabledChecker checker = new StepEnabledChecker(descriptor, pipelineDefaults) 42 | if (checker.rollbackStepMissing()) { 43 | return null 44 | } 45 | String gitRepoName = coordinates.gitRepoName 46 | String fullGitRepo = coordinates.fullGitRepo 47 | Job job = dsl.job("${projectName}-test-env-rollback-test") { 48 | deliveryPipelineConfiguration('Test', 'Tests on test latest prod version') 49 | environmentVariables(pipelineDefaults.defaultEnvVars as Map) 50 | wrappers { 51 | commonSteps.defaultWrappers(delegate as WrapperContext) 52 | commonSteps.deliveryPipelineVersion(delegate as WrapperContext) 53 | credentialsBinding { 54 | // remove::start[CF] 55 | if (pipelineDefaults.cfTestCredentialId()) usernamePassword( 56 | EnvironmentVariables.PAAS_TEST_USERNAME_ENV_VAR, 57 | EnvironmentVariables.PAAS_TEST_PASSWORD_ENV_VAR, 58 | pipelineDefaults.cfTestCredentialId()) 59 | // remove::end[CF] 60 | // remove::start[K8S] 61 | if (pipelineDefaults.k8sTestTokenCredentialId()) string( 62 | EnvironmentVariables.TOKEN_ENV_VAR, 63 | pipelineDefaults.k8sTestTokenCredentialId()) 64 | // remove::end[K8S] 65 | } 66 | } 67 | scm { 68 | commonSteps.configureScm(delegate as ScmContext, fullGitRepo, "dev/${gitRepoName}/\${${EnvironmentVariables.PIPELINE_VERSION_ENV_VAR}}") 69 | } 70 | steps { 71 | commonSteps.downloadTools(delegate as StepContext, fullGitRepo) 72 | commonSteps.runStep(delegate as StepContext, "test_rollback_smoke.sh") 73 | } 74 | publishers { 75 | commonSteps.defaultPublishers(delegate as PublisherContext) 76 | } 77 | } 78 | customize(job) 79 | return new CreatedJob(job, autoNextJob(checker)) 80 | } 81 | 82 | private boolean autoNextJob(StepEnabledChecker checker) { 83 | if (checker.stageStepSet()) { 84 | return checker.autoStageSet() 85 | } 86 | return checker.autoProdSet() 87 | } 88 | 89 | @Override void customize(FreeStyleJob job) { 90 | commonSteps.customizers().each { 91 | it.customizeAll(job) 92 | it.customizeTest(job) 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /job-dsl/src/main/groovy/io/cloudpipelines/steps/TestDeploy.groovy: -------------------------------------------------------------------------------- 1 | package io.cloudpipelines.steps 2 | 3 | import groovy.transform.CompileStatic 4 | import javaposse.jobdsl.dsl.DslFactory 5 | import javaposse.jobdsl.dsl.Job 6 | import javaposse.jobdsl.dsl.helpers.ScmContext 7 | import javaposse.jobdsl.dsl.helpers.publisher.PublisherContext 8 | import javaposse.jobdsl.dsl.helpers.step.StepContext 9 | import javaposse.jobdsl.dsl.helpers.wrapper.WrapperContext 10 | import javaposse.jobdsl.dsl.jobs.FreeStyleJob 11 | 12 | import io.cloudpipelines.common.BashFunctions 13 | import io.cloudpipelines.common.Coordinates 14 | import io.cloudpipelines.common.EnvironmentVariables 15 | import io.cloudpipelines.common.PipelineDefaults 16 | import io.cloudpipelines.common.PipelineDescriptor 17 | import io.cloudpipelines.common.StepEnabledChecker 18 | 19 | /** 20 | * Deploys to test 21 | * 22 | * @author Marcin Grzejszczak 23 | * @since 1.0.0 24 | */ 25 | @CompileStatic 26 | class TestDeploy implements Step { 27 | private final DslFactory dsl 28 | private final io.cloudpipelines.common.PipelineDefaults pipelineDefaults 29 | private final BashFunctions bashFunctions 30 | private final CommonSteps commonSteps 31 | 32 | TestDeploy(DslFactory dsl, io.cloudpipelines.common.PipelineDefaults pipelineDefaults) { 33 | this.dsl = dsl 34 | this.pipelineDefaults = pipelineDefaults 35 | this.bashFunctions = pipelineDefaults.bashFunctions() 36 | this.commonSteps = new CommonSteps(this.pipelineDefaults, this.bashFunctions) 37 | } 38 | 39 | @Override 40 | CreatedJob step(String projectName, Coordinates coordinates, PipelineDescriptor descriptor) { 41 | StepEnabledChecker checker = new StepEnabledChecker(descriptor, pipelineDefaults) 42 | if (checker.testStepMissing()) { 43 | return null 44 | } 45 | String gitRepoName = coordinates.gitRepoName 46 | String fullGitRepo = coordinates.fullGitRepo 47 | Job job = dsl.job("${projectName}-test-env-deploy") { 48 | deliveryPipelineConfiguration('Test', 'Deploy to test') 49 | environmentVariables(pipelineDefaults.defaultEnvVars as Map) 50 | wrappers { 51 | commonSteps.defaultWrappers(delegate as WrapperContext) 52 | commonSteps.deliveryPipelineVersion(delegate as WrapperContext) 53 | credentialsBinding { 54 | // remove::start[CF] 55 | if (pipelineDefaults.cfTestCredentialId()) usernamePassword( 56 | EnvironmentVariables.PAAS_TEST_USERNAME_ENV_VAR, 57 | EnvironmentVariables.PAAS_TEST_PASSWORD_ENV_VAR, 58 | pipelineDefaults.cfTestCredentialId()) 59 | // remove::end[CF] 60 | // remove::start[K8S] 61 | if (pipelineDefaults.mySqlCredential()) string(EnvironmentVariables.MYSQL_USER_ENV_VAR, 62 | pipelineDefaults.mySqlCredential()) 63 | if (pipelineDefaults.mySqlRootCredential()) string(EnvironmentVariables.MYSQL_ROOT_USER_ENV_VAR, 64 | pipelineDefaults.mySqlRootCredential()) 65 | if (pipelineDefaults.k8sTestTokenCredentialId()) string(EnvironmentVariables.TOKEN_ENV_VAR, 66 | pipelineDefaults.k8sTestTokenCredentialId()) 67 | // remove::end[K8S] 68 | } 69 | } 70 | scm { 71 | commonSteps.configureScm(delegate as ScmContext, fullGitRepo, 72 | "dev/${gitRepoName}/\${${EnvironmentVariables.PIPELINE_VERSION_ENV_VAR}}") 73 | } 74 | steps { 75 | commonSteps.downloadTools(delegate as StepContext, fullGitRepo) 76 | commonSteps.runStep(delegate as StepContext, "test_deploy.sh") 77 | } 78 | publishers { 79 | commonSteps.defaultPublishers(delegate as PublisherContext) 80 | commonSteps.deployPublishers(delegate as PublisherContext) 81 | } 82 | } 83 | customize(job) 84 | return new CreatedJob(job, true) 85 | } 86 | 87 | @Override void customize(FreeStyleJob job) { 88 | commonSteps.customizers().each { 89 | it.customizeAll(job) 90 | it.customizeTest(job) 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /tools/build-helper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | [[ -z $DEBUG ]] || set -o xtrace 4 | 5 | set -o errexit 6 | set -o errtrace 7 | set -o nounset 8 | set -o pipefail 9 | 10 | ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 11 | 12 | function usage { 13 | echo "usage: $0: " 14 | exit 1 15 | } 16 | 17 | if [[ $# -ne 1 ]]; then 18 | usage 19 | fi 20 | 21 | case $1 in 22 | download-shellcheck) 23 | if [[ "${OSTYPE}" == linux* ]]; then 24 | SHELLCHECK_VERSION="v0.4.6" 25 | SHELLCHECK_ARCHIVE="shellcheck-${SHELLCHECK_VERSION}.linux.x86_64.tar.xz" 26 | SHELLCHECK_ARCHIVE_SHA512SUM="d9ac3e4fb2383b2d6862415e8052459ce24fd5402806b9ce739990d5c1cccebe4121288df29de32dcef5daa115874ddf7f9730de256bf134ee11cd9704aaa64c" 27 | if [[ -x "${ROOT_DIR}/../build/shellcheck-${SHELLCHECK_VERSION}/shellcheck" ]]; then 28 | echo "shellcheck already downloaded - skipping..." 29 | exit 0 30 | fi 31 | wget -P "${ROOT_DIR}/../build/" \ 32 | "https://storage.googleapis.com/shellcheck/${SHELLCHECK_ARCHIVE}" 33 | pushd "${ROOT_DIR}/../build/" 34 | echo "${SHELLCHECK_ARCHIVE_SHA512SUM} ${SHELLCHECK_ARCHIVE}" | sha512sum -c - 35 | tar xvf "${SHELLCHECK_ARCHIVE}" 36 | rm -vf -- "${SHELLCHECK_ARCHIVE}" 37 | popd 38 | else 39 | echo "It seems that automatic installation is not supported on your platform." 40 | echo "Please install shellcheck manually:" 41 | echo " https://github.com/koalaman/shellcheck#installing" 42 | exit 1 43 | fi 44 | ;; 45 | download-bats) 46 | if [[ -x "${ROOT_DIR}/../build/bats/bin/bats" ]]; then 47 | echo "bats already downloaded - skipping..." 48 | exit 0 49 | fi 50 | git clone https://github.com/bats-core/bats-core.git "${ROOT_DIR}/../build/bats" 51 | ;; 52 | install-zsd) 53 | zshInstalled="false" 54 | zsh --version && zshInstalled="true" || echo "zsh is missing" 55 | if [[ "${zshInstalled}" != "true" ]]; then 56 | echo "[WARNING] ZSH is missing! Will return 0 but won't generate any docs" 57 | exit 0 58 | fi 59 | if [[ -x "${ROOT_DIR}/../build/zsd/bin/zsd" ]]; then 60 | echo "zsd already installed - skipping..." 61 | exit 0 62 | fi 63 | "${ROOT_DIR}/build-helper.sh" initialize-submodules 64 | pushd "${ROOT_DIR}/../src/test/docs_helper/zshelldoc/" 65 | make install PREFIX="${ROOT_DIR}/../build/zsd" 66 | popd 67 | ;; 68 | generate-zsd) 69 | zshInstalled="false" 70 | zsh --version && zshInstalled="true" || echo "zsh is missing" 71 | if [[ "${zshInstalled}" != "true" ]]; then 72 | echo "[WARNING] ZSH is missing! Will return 0 but won't generate any docs" 73 | exit 0 74 | fi 75 | pushd "${ROOT_DIR}/../src/main/bash" 76 | # shellcheck disable=SC2035 77 | "${ROOT_DIR}/../build/zsd/bin/zsd" --cignore '\#*FUNCTION:*{{{*|\#*synopsis*{{{*' *.sh 78 | pushd projectType 79 | # shellcheck disable=SC2035 80 | "${ROOT_DIR}/../build/zsd/bin/zsd" --cignore '\#*FUNCTION:*{{{*|\#*synopsis*{{{*' *.sh 81 | popd 82 | popd 83 | ;; 84 | initialize-submodules) 85 | echo "Initilizing submodules" 86 | git submodule init || echo "Submodules already initilized" 87 | git submodule update || echo "Submodules already updated" 88 | git submodule foreach git pull origin master || echo "Failed to pull - continuing the script" 89 | ;; 90 | *) 91 | usage 92 | ;; 93 | esac 94 | --------------------------------------------------------------------------------